Hlavní navigace

Začínáme bezpečně s FreeBSD (12)

5. 10. 2004
Doba čtení: 9 minut

Sdílet

V dnešním zavírajícím dílu našeho seriálu si povíme o vylepšeních ovládání jailu, která přináší nová, pátá řada FreeBSD. Dále si ukážeme pár technik, jakým způsobem můžete uzavřít do jailu jednotlivé démony, a dáme tip na zajímavý program SCPonly.

Jail na FreeBSD 5

Novinky v /etc/rc.conf

Pátá řada systému FreeBSD přináší vylepšenou práci s jaily. Automatické spouštění jailů, které jste museli dříve dělat pomocí vlastních skriptů nebo pomocí jiných nástrojů, můžete nyní ovládat pomocí pár nových voleb v /etc/rc.conf.

Na mé momentální verzi FreeBSD 5.3-beta6 tedy v /etc/rc.conf nalezneme tyto položky týkající se automatického spouštění jailů:

jail_enable="NO" # Autimatické spouštění jailů
jail_list="" # Seznam názvů jailů oddělený mezerou
jail_set_hostname_allow="YES" # Možnost superadministrátora měnit uvnitř jailu hostname
jail_socket_unixiproute_only="YES" # Pouze TCP/IP směrování uvnitř jail
jail_sysvipc_allow="NO" # Povolení SystemV IPC uvnitř jailu
# Pro spouštění jail. infrastruktury v rc skriptech
# vytvořte odpovídající položky pro každý jail
# specifikovaný v jail_list pomocí následujících definic
# To use rc's built-in jail infrastructure create entries for
# each jail, specified in jail_list, with the following variables.
# POZNÁMKA: nahraďte 'example' názvem jailu.
#jail_example_rootdir="/usr/jail/default" # Kořenový adresář jailu
#jail_example_hostname="default.domain.com" # Hostname jailu
#jail_example_ip="192.168.0.10" # IP adresa/y jailu
#jail_example_exec="/bin/sh /etc/rc" # příkaz spuštěný uvnitř jailu
#jail_example_devfs_enable="NO" # připojení devfs v jailu
#jail_example_fdescfs_enable="NO" # připojení fdescfs v jailu
#jail_example_procfs_enable="NO" # připojení procfs jailu
#jail_example_devfs_ruleset="ruleset_name" # pravidla devfs aplikovaná pro jail 

Vlastně jsem přeložil položky týkající se jailu v /etc/rc.conf. Mohli jste postřehnout několik změn oproti čtvrté řadě FreeBSD, jedna, co se týká jailu, je, že můžete přiřadit určitému jailu více IP adres. Pro podrobnější info ohledně ostatních položek nových v páte řadě FreeBSD nahlédněte do příslušných manuálových stránek man 8 devfs, man 5 fdescfsman 5 devf.

Nyní se vám tedy při startu celého systému automaticky spustí i vybrané jaily. Bez restartu můžete použít:

srot# /etc/rc.d/jail start
Configuring jails:.
Starting jails: projekt 

Nové příkazy

V páté řadě se objevilo mimo voleb v /etc/rc.conf i pár nových příkazů pro ovládání jailu, jejichž funkčnost jste možná dříve implementovali pomocí dodatečně nainstalovaných programů. Jedná se o jls  a jexec.

Poněvadž jail(8) od páté řady FreeBSD při startu dává každému jailu unikátní ID – jail indentifier, můžeme pomocí jls vytisknout aktivní jaily a jejich JIDs.

srot# jls
JID IP Address Hostname Path
2 10.0.0.101 projekt /usr/jails/10.0.0.101 

Výše zmíněné JID můžete využít u dalšího nově přidaného příkazu, a tím je jexec. Pomocí jexec jid příkaz můžeme jednoduše ukončit běžící jail, aniž bychom využili v minulém dílu zmíněné příkazy z programů jako jailutils či jailadmin.

srot# jexec 2 kill -TERM -1 

Nové sysctl MIB

V páté řadě FreeBSD přibyly i nové sysctl MIB týkající se jailu. Jedná se o dvě položky, které se nastavují na hostitelském systému a ovlivňují chování všech jailů – klientů.

Položka security.jail.allow_raw_sockets umožňuje rootovi v jailu vytvoření raw devices, která jsou například potřeba pro funkčnost programů ping nebo traceroute. Defaultně je nastavení této sysctl MIB položky zakázáno, protože povolením raw devices v jailu můžete způsobit bezpečnostní komplikace.

Další položkou je security.jail.getfsstatroot_only, která omezuje zobrazení připojených souborových systémů na celém systémů pouze na kořen vlastního jailu. Tedy v případě nastavení security.jail.getfsstatroot=0 (což je defaultní nastavení) uvidíte pouze vlastní kořen jail, rovněž tato volba způsobí schování dalších připojených souborových systémů uvnitř jailu, např.  /tmp.

Momentálně můžete pro každý jail zvlášť nastavit pouze dvě sysctl MIB, a to kern.securelevel a kern.hostname. Vyvojáři FreeBSD stále pracují na vyladění sysctl MIB vztahující se k jailů, proto můžeme v dalších verzích očekávat jemnější nastavení každého jailu zvlášť pomocí systcl MIB – přesněji, v budoucnu budeme tedy moci např. povolovat raw devices pouze určitým jailům atd.

Easy way jailování démona

Jedná se vlastně o takový jednoduchý a úsměvný trik pomocí např. mount_nullfs (přimountování adresáře na přípojný bod jako filesystému), na který jsem narazil na stránce polského vývojáře FreeBSD– Pawel Jakub Dawidek. Postup je jednoduchý, vytvoříte pouze adresářovou strukturu, kterou potřebuje vlastní démon, a části, do nichž nepotřebujete nic zapisovat a mohou být lehce sdíleny, můžete připojit pomocí mount_nullfs z hostitelského systému.

My si to ukážeme na httpd apache. Nejprve si samozřejmě budete muset nainstalovat apache na hostitelském systému (hlavním) a upravit váš httpd.conf, aby se vám vůbec rozjel. (Osobně na hostitelském systému nemám téměř žádné démony, rovněž i porty mám v jailu a tam vytvářím případné balíčky.)

srot# pkg_add -r apache13-modssl
srot# vi /usr/local/etc/apache/httpd.conf 

Nyní se pustíme do samotného jailování.

srot# mkdir /usr/jails/apache && cd /usr/jails/apache
srot# mkdir -p -m 755 bin dev etc lib libexec usr/bin \
usr/home usr/lib usr/libexec usr/local var/log var/run
srot# mount_nullfs -o ro /bin bin
srot# mount_nullfs -o ro /lib lib
srot# mount_nullfs -o ro /libexec libexec
srot# mount_nullfs -o ro /usr/bin usr/bin 

Dovolíme uživatelům v jailu vlastní www stránky.

srot# mount_nullfs -o ro /usr/jails/10.0.0.101/etc etc
srot# mount_nullfs -o ro /usr/jails/10.0.0.101/usr/home usr/home

srot# mount_nullfs -o ro /usr/lib usr/lib
srot# mount_nullfs -o ro /usr/libexec usr/libexec
srot# mount_nullfs -o ro /usr/local usr/local
srot# mount_nullfs /var/run var/run 

Logy apache chceme číst v našem druhém jailu.

srot# mount_unionfs var/log /usr/jails/10.0.0.101/var/log 

Spouštíme apache zavřený v jailu:

srot# jail /usr/jails/apache www-test 10.0.0.103 /usr/local/sbin/apachectl start 

Můžeme zkontrolovat, zda nám jail naběhl, pomocí jls a dále případně sockstat/ netstat.

srot# jls
JID IP Address Hostname Path
6 10.0.0.103 www-test /usr/jails/apache
2 10.0.0.101 projekt /usr/jails/10.0.0.101 

Heureka, apache běží. V případě, že bychom chtěli restart apache, stačí použít:

srot# jexec 7 apachectl restart
/usr/local/sbin/apachectl restart: httpd restarted 

Toto je sice jednoduché řešení, ale kapku krkolomné.

Hard way…

Následující postup se skládá z přesného zjištění potřebných komponent pro běh démona a jejich umístění do adresářové struktury jail prostředí. Abychom mohli spouštět apache v minimálním jailu pomocí apachectl, museli bychom provést více práce… Spokojíme se tedy se spouštěním přes httpd. Nejdříve vytvoříme adresářovou strukturu. Tu můžete zjistit pomocí pkg_info -xL apache (ukáže, kam se všude nainstaloval apache) a truss(1)  – mapuje systémová volání určitého procesu, tedy přesněji:

srot# truss -o ~/log /usr/local/sbin/httpd
srot# grep open ~/log | less
open("/etc/libmap.conf",0x0,0666) ERR#2 'No such file or directory'
open("/var/run/ld-elf.so.hints",0x0,00) = 4 (0x4)
open("/lib/libcrypt.so.2",0x0,027757765604) = 4 (0x4)
open("/usr/local/lib/libmm.so.13",0x0,027757765604) = 4 (0x4)
...zkráceno... 

Z výše uvedených postupů si můžete udělat představu, jak bude vypadat adresářová struktura.

srot# cd /usr/jails/apache
srot# mkdir -p -m 755 etc dev lib libexec \
usr/local/etc/apache usr/local/lib usr/local/libexec/apache \
usr/local/sbin var/log var/run 

Zkopírujeme potřebné soubory/knihovny.

srot# cp /lib/libcrypt.so.2 /lib/libc.so.5 lib/
srot# cp /usr/local/lib/libmm.so.13 usr/local/lib/

srot# cp /var/run/ld-elf.so.hints var/run/
srot# cp /libexec/ld-elf.so.1 libexec/ 

Zkopírujeme/vyt­voříme potřebné systémové konfigurační soubory:

srot# cp /etc/resolv.conf /etc/hosts etc/

srot# cat > etc/group
www:*:80:
nogroup:*:65533:
nobody:*:65534:
srot# cat > etc/master.passwd
www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
srot# pwd_mkdb -pd etc/ etc/master.passwd
srot# rm -rf etc/master.passwd etc/spwd.db 

Nyní vlastní soubory apache, tj. jeho konfigurační soubor, moduly, document data a binárku.

srot# cp -Rp /usr/local/etc/apache/* usr/local/etc/apache/
srot# cp /usr/local/libexec/apache/* usr/local/libexec/apache/
srot# cp -Rp /usr/local/www usr/local/
srot# cp /usr/local/sbin/httpd usr/local/sbin/ 

Spustíme apache zavřený v jailu.

srot# jail /usr/jails/apache www-test 10.0.0.103 /usr/local/sbin/httpd 

Heureka podruhé, vše běží. Můžeme zkontrolovat pomocí jls (v páté řadě FreeBSD), ps a hledat J vestate nebo pomocí sockstat/ netstat.

srot# jls | grep www-test
22 10.0.0.103 www-test /usr/jails/apache 

Tak toto byl takový jednoduchý postup, jak rozchodit apache v jailu. Tento postup kvůli zeditovaným uživatelským konfiguračním souborům v /etc nebude moci použít mod_userdir… Řešením může být tedy mount_nullfs adresáře /etc jako read-only.

Dalším krokem, který by vás mohl zajímat, může být jailování mysql. Návod, který o tom pojednává, můžete nalézt zde.

Tip – SCPonly

S jailem to sice nemá nic společného, ale myslím, že za zmínku to stojí. Jestliže máte tedy apache v jailu, tak budete potřebovat nějakým způsobem dovolit vzdálený přístup do uživatelských www složek. Okolo FTP jsou mraky článků ohledně bezpečnosti a problémů se zabezpečením, tak proč konečně nenahradit FTP něčím jiným? Můžeme například použít scp a sftp, co nabízí SSH. Bohužel ne každému určitě chceme dávat na stroji klasický unixový účet. Jednoduchým řešením může být produkt SCPonly. SCPonly je „takový shell“, resp. něco jako wrapper před SSH. Můžete jím omezit používání pouze scp/sftp a zakázat tím spuštění příkazů na vzdáleném stroji. Rovněž můžete určitého uživatele chrootnout do jeho adresáře, tj. nebude moci zapisovat nikam jinam.

V případě, že budete chtít použít chrootování u scponly, nesmíte smazat work adresář, protože obsahuje skript na vytvoření nového chrootovaného uživatele.

srot# cd /usr/ports/shells/scponly
srot# make WITH_SCPONLY_CHROOT=YES install
srot# cd /usr/local/share/examples/scponly/
srot# sh setup_chroot.sh

Next we need to set the home directory for this
scponly user. please note that the user's home
directory MUST NOT be writeable by the scponly
user. this is important so that the scponly user
cannot subvert the .ssh configuration parameters.

for this reason, a writeable subdirectory will be
created that the scponly user can write into.

-en Username to install [scponly]
scptest
-en home directory you wish to set for this user [/home/scptest]
/home/sftpusers/scptest
-en name of the writeable subdirectory [incoming]
public_html
Password for 'scptest' is: TZO8oZOFru

creating /home/sftpusers/scptest/public_html
directory for uploading files

Your platform (FreeBSD) does not have a platform
specific setup script.
This install script will attempt a best guess.
If you perform customizations, please consider
sending me your changes.
Look to the templates in build_extras/arch.
- joe at sublimation dot org

please set the password for scptest:
Changing local password for scptest
New Password:
Retype New Password:
if you experience a warning with winscp regarding
groups, please install the provided hacked out fake
groups program into your chroot, like so:
cp groups /home/sftpusers/scptest/bin/groups

srot# grep scptest /etc/passwd scptest:*:1004:1001:User &:/home/sftpusers/scptest:/usr/local/sbin/scponlyc 

Nový uživatel má práva zapisovat pouze do adresáře public_html. V případě, že byste chtěli uživatele hned po přihlášení přepnout do adresáře public_html, stačí pozměnit uživatelovo home_dir na /home/sftpusers/scptest/public_html. Více  man scponly.

Cloud 24 - tip 1

Tip 2 – fbsd_jails: Webmin module

A ještě jeden tip. Jestliže rádi pracujete s webovou konfigurací, můžete využít např. modul do webminu fbsd_jails vyvinutý TheLabs.com, které vyvíjejí i JailTools. Více na domovské stránce JailTools.

Závěr

Tak to byl vlastně poslední díl našeho seriálu. Snad to vyšlo. Cílem bylo pomoci začínajícím uživatelům spřátelit se s FreeBSD a poznat jeho jednoduchou složitost :) Takže jestli vás FreeBSD trochu zaujalo, mrkněte na možnost přihlášení se do české uživatelské konference nebo se někdy připojte na #bsd.cz, #freebsd na IRCnetu nebo #freebsdhelp na Efnetu.

Byl pro vás článek přínosný?