Chroot
Chroot byl na rootu již jednou popsán, takže se mu budu věnovat jen krátce. Název „chroot“ vznikl ze slov „change root“, to znamená, že pomocí něho můžeme spustit procesy pod jiným kořenovým adresářem, než je ten standardní. Soubory jsou pak k dipozici pouze tomu procesu, kterému patří. Samozřejmostí je také přístup z aplikací, které běží s původním rootem.
Pokud takto chceme spustit program, tak musíme najít způsob, jak zjistit, které knihovny tento program potřebuje. Další věc, která nám nesmí uniknout jsou konfigurační a jiné soubory, které program využívá.
Vytvoření kvalitního chrootu může být během na dlouhou trať, ale nakonec máme program běžící v prostředí izolovaném od okolí. Nejedná se o kompletní zabezpečení ale spíše o překážku, kterou je nutné překonat.
Nejčastěji se v chrootu spouštění serverové programy jako je Apache, Postfix, Bind atd. Jeho využití se ale najde i jinde. Například při instalaci nebo opravě unixového operačního systému.
Ruční kopírování a spouštění
Možností, jak se dostat k funkčnímu chrootu, je několik. My si dnes ukážeme, jak vytvořit chroot ručně postupným zjišťováním závislostí a také si ukážeme nástroj Jailkit, který se o vše postará sám. Uživatelé distribuce Debian mohou použít program Jailer. Ten umí instalovat do jakéhokoli adresáře balíček a jeho závislosti. Nutno podotknout, že vyladění vytvářecího procesu chvíli trvá a těžko díky němu najdeme ideální hranici zbytečných a užitečných souborů.
Nejefektivnější je zkopírovat si všechny soubory ručně. V tomto případě musíme spoléhat na hlášení programu o chybějících knihovnách a důležitých souborech. K zjištění závislostí použijeme program „ldd“.
cx@godie ~ $ ldd /bin/bash
linux-gate.so.1 => (0xffffe000)
libncurses.so.5 => /lib/libncurses.so.5 (0xb7ed0000)
libdl.so.2 => /lib/libdl.so.2 (0xb7ecc000)
libc.so.6 => /lib/libc.so.6 (0xb7d9c000)
/lib/ld-linux.so.2 (0xb7f28000)
Knihovny mohou využít další knihovny. Po takovémto hlášení nakopírujeme vyžádané knihovny včetně adresářové struktury do nějakého adresáře a zkoušíme další závislosti. Můžeme si na to napsat skript. Níže uvidíme, že ruční vytváření není nutné a na tuto práci existují nástroje.
Jailkit
Jailkit je balík programů, které zautomatizují nepohodlnou práci a nechají nás soustředit se na to důležité. Také disponuje několika konfiguračními možnostmi, které umožní jedním příkazem vytvořit funkční jail (malý systém běžící v chrootu) například pro ssh. Projekt najdeme na této adrese odkud je možné stáhnout i zdrojové kódy.
Nebudeme to dlouho zdržovat a přejdeme rovnou k instalaci. Jailkit není součástí Ubuntu, Gentoo a CentOSu. Za ostatní distribuce nemůžu mluvit. V mém případě jsem musel jít přímo ke kompilaci ze zdroje, kde stačí svatá trojice.
wget http://olivier.sessink.nl/jailkit/jailkit-2.5.tar.bz2
tar xf jailkit-2.5.tar.bz2
cd jailkit-2.5
./configure
make
make install
Pokud máme nainstalováno, můžeme zkusit zkopírovat bash a spustit si náš první chroot.
mkdir /home/jail1
jk_cp -j /home/jail1 /bin/bash
chroot /home/jail1
Společně se souborem /bin/bash se zkopírují všechny knihovny, které bash potřebuje a zachovají se také práva. Jailkit obsahuje řadů nástrojů, z nichž ty nejdůležitější jsou tyto:
jk_init Rychlé vytvoření jailu s konkrétní
aplikací podle nastaveného profilu.
jk_check Hledání potenciálních bezpečnostních
problémů
jk_socketd Démon zajišťující logy ze všech jailů.
jk_chrootlaunch Spuštění aplikace, která se neumí
chrootvat sama.
jk_update Aktualizace jailu podle originálního
systému.
jk_cp Kopírování knihoven a binárních souborů
včetně závislostí.
Pokud nastavujeme jaily často, tak jk_init bude velmi vítaným pomocníkem. Konfigurační soubor /etc/jailkit/jk_init.ini obsahuje profily různých aplikací, které můžeme umístit do chrootu napsáním:
jk_init -j <adresář s jailem> <profil>
Z konfiguračního souboru se načte seznam souborů a knihoven, které jsou nutné pro spuštění vybraného programu a automaticky se zkopírují do zadaného adresáře s jailem.
Zmíněný konfigurační soubor je klasického ini formátu a vypadá takto:
[Název profilu]
comment = <Komentář>
executables = <Spustitelné soubory>
regularfiles = <Normální soubory>
libraries = <Zahrnuté knihovny>
users = <Uživatelé, kteří se mají zkopírovat do jailu>
groups = <To samé, ale se skupinami>
includesections = <Zahrnutí dalších profilů>
Více hodnot se odděluje čárkou. Ani jeden z řádků není povinný. Příklady skutečných aplikací se dodávají společně se zdrojovým kódem a mnoho jich je již nastaveno. Bohužel nesedí na všechny distribuce.
Sock soubory
Nejrychlejší spojení na lokální databázi vede cestou přes *.sock soubory. Pokud je chceme mít ve všech jailech, můžeme k tomu použít hardlinky např. takto:
ln /var/run/mysqld/mysqld.sock /home/jail1/var/run/mysqld/
/proc a /dev
Adresáře /proc a /dev můžeme připojit do našeho nového rootu.
mount -t proc none /home/jail1/proc
mount -o bind /dev /home/jail1/dev
Nepotřebují je všechny programy a oba dva snižují bezpečnost jailu, proto bychom se měli nejdříve ujistit, že je programy v našem jailu potřebují. Pokud není nutný celý adresář /dev, můžeme tam nakopírovat jen některé soubory.
Příklad s Pythonem
Rozhození Pythonu pomocí jailkitu je velmi jednoduché a výsledek pak můžeme použít například pro spouštění CGI skriptů z chrootu lighttpd nebo Apache.
mkdir /home/jail1
jk_cp -j /home/jail1 /usr/bin/python2.5
jk_cp -j /home/jail1 /usr/lib/python2.5
Testování funkčností provedeme tímto způsobem:
chroot /home/jail1 /usr/bin/python2.5
Spustí se nám Python ve verzi 2.5 uzavřený ve vlastním prostředí.
Příklad s Apachem
Běh programu pod chrootem je doménou hlavně serverů a Apache je jedním z nejlepších zástupců, které z této skupiny programů máme. Je také roztahán do množství jiných souborů, takže proto nám bude dobrý i jako ukázka.
Pro změnu si vytvoříme profil v soubru jk_init.ini, abychom mohli nastavení použít i pohodlně i na jiných strojích.
[apache]
comments = apache web server
executables = /usr/sbin/apache2, /usr/sbin/apache2ctl, /etc/init.d/apache2, /bin/sh, /usr/bin/env, /bin/mkdir, /usr/bin/install, /bin/rm, /lib/lsb/init-functions
directories = /etc/apache2, /var/www, /usr/share/apache2, /usr/lib/apache2/, /var/log/apache2
libraries = /lib/libnsl.so.1, /lib64/libnsl.so.1, /lib/libnss*.so.2, /lib64/libnss*.so.2
devices = /dev/null
users = root, www-data
groups = root, www-data
Ve výchozím stavu sice již jeden založen je, ale ten nesedí na mnou zkoušeném Ubuntu, takže pravděpodobně stejně budeme muset vytvořit nový.
Máme-li nakonfigurováno, spustíme:
jk_init -j /home/jail1 apache
Tím vytvoříme kompletní jail a můžeme spustit Apache uvnitř:
jk_chrootlaunch -j /home/jail1 -x /usr/sbin/apache2ctl -- start
Nebo to můžeme také zkusit ručně pokud nakopírujeme třeba /bin/bash do jailu a použijeme program chroot.
jk_cp -j /home/jail1 /bin/bash
chroot /home/jail1
apache2ctl start
Závěr
Ještě jednou zdůrazňuji, že chroot není stoprocentní bezpečnostní řešení, ale jen komplikace pro případného útočníka. Přítomnost adresářů /proc a /dev bezpečnost snižuje ještě více. Režie chrootu je komplikace, ale jsou případy, kdy se vyplatí. Jailkit je v tomto ohledu velmi pohodlným pomocníkem a kopíruje jen to, co je opravdu potřeba pro běh programu.