Hlavní navigace

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

21. 9. 2004
Doba čtení: 9 minut

Sdílet

Jestliže někdo získá na unixovém stroji práva roota, představuje to bezpečnostní problém. Jednou z možností, kterou můžeme využít v opevnění našeho systému, je jail na FreeBSD. Jedná se o vylepšenou koncepci chrootu, která je někde na pomezí mezi starým chrootem, jemuž jsou dokázány bezpečnostní slabiny, a skutečnou virtualizací systému. O tom tedy bude tento díl.

freebsd jail

Co je jail?

Velmi jednoduše je jail vylepšený chroot. Na druhou stranu, tak jednoduše se to říct nedá :) Jail isoluje proces/skupinu procesů na filesystemu změnou kořenového adresáře, tedy podobně jako chroot. Dále však zcela isoluje proces/skupinu procesů od zbytků procesů mimo jail, po spuštění jailu není možné do jailu přidávat proces, který není potomkem nějakého již běžícího procesu v jailu – žádný proces v jailu se z něj nemůže dostat ani nijak ovlivnit procesy mimo něj. Jail je rovněž spouštěn s určitou IP adresou a veškeré služby jsou nuceny používat tuto danou IP adresu, která zevnitř jailu nemůže být změněna. Rovněž root nemůže v jailu vytvářet nové devices. Mezi další omezení v jailu patří: nemožnost měnit spuštěný kernel a nahrát moduly, měnit síťové nastavení, připojovat/od­pojovat filesystemy, měnit určité sokety, pozměňovat velkou část sysctl MIB, měnit bezpečnostní-superuživatelské příznaky souborů (flags)…

Jail pracuje na konceptu klient(jail)-server(hostitel). Změny (systémové) provedené na hostiteli, tedy na skutečném hlavním systému, se projeví i pro jail. Změny provedené v jailu jsou platné pouze pro tento daný jail.

Poznámka: Na jailu se stále pracuje, tudíž některá omezení již v novějších verzích FreeBSD neplatí. Např. do jailu v RELENG4 byla z -current přidána podpora raw soketů, tudíž nyní bude fungovat např. ping v jailu (tedy pokud máte příslušnou verzi FreeBSD). Avšak i v tomto platí: „…Though a number of security holes have been corrected, more may be present, and security.jail­.allow_raw_soc­kets should be used with care.“

Nasazení jailu

Jail se stal na FreeBSD novým bezpečnostním modelem. A taky proč ne? Do jailu můžeme uzavřít určitého síťového démona nebo tímto způsobem vytvořit něco jako virtuální stroj. V případě, že by mohl určitý démon v jailu být kompromitován a získat tak oprávnění roota, stále zůstane uzavřen v jailu a zbytek systému bude ochráněn. Kompletní jail můžeme využít např. pro virtual server hosting. Ideálním příkladem je, aby jakékoliv síťové spojení bylo směrováno do jail(ů) a na hostitelském systému běželo minimum služeb.

Příprava jailu

Jak již bylo řečeno, veškeré služby v jailu jsou spjaty s IP adresou, se kterou byl jail spuštěn. Někteří démoni se však vážou na všechny IP adresy, které jsou dostupné v systému. Takové nastavení démonů však zabraňuje korektní funkčnosti jailu, poněvadž ten musí mít výhradní přístup ke své IP adrese, resp. démon běžící v jailu musí mít výhradní přístup ke své IP adrese a portu. Jakých démonů na hostitelském systému se to tedy týká? Mezi démony, kteří se vážou na všechny dostupné IP adresy, patří syslogd (nejlépe jen na hostitelském systému zcela síť. umlčet, flag -ss), named, sendmail, inetd,sshd… Nejlépe to zjistíme buď pomocí sockstat, nebo  netstat:

srot# sockstat -4 | grep '*.*'
root sshd 150 4 tcp4 *:22 *:*
root sendmail 95 3 tcp4 127.0.0.1:25 *:* 

Zde vidíme, že sshd je svázán se všemi dostupnými IP adresami. Potřebujeme, aby byl stejně jako sendmail spjat s určitou IP adresou.

Syslogd nastavíme pomocí /etc/rc.conf: syslogd_flags="-ss" nebo syslogd_flags="-b 10.0.0.100" (příklad)

Sendmail opět pomocí /etc/rc.conf: sendmail_enable="NO", způsobí pouze to, že sendmail nebude přijímat poštu od jiných stanic, je však povoleno odesílat. Přece jenom bude lepší mít MTA jako mail server spuštěný v jailu

Inetd přes /etc/rc.conf: inetd_flags="NO", na hostiteli nepotřebujeme, aby se nám spouštěl  inetd

Sshd pomocí /etc/ssh/sshd_c­onfig: položka ListenAddress, tedy ListenAddress 10.0.0.100 (příklad)

Nakonec přidáme do systému další IP adresu, kterou přidělíme jailu a přidáme řádek do /etc/rc.conf kvůli aliasu:

srot# ifconfig lnc0 alias 10.0.0.4 netmask 255.255.255.255
ifconfig_lnc0_alias0="10.0.0.4" 

Jail na disku

Nejjednodušší je samozřejmě postavit jail do obyčejného adresáře. Je to vhodné např. při jailování samotných démonů, avšak v případě kompletního jailu – tedy jakéhosi virtuálního systému – bude pravděpodobně lepší si vytvořit na disku (dalším disku) druhou slice a rozdělit ji na partitions tak, abychom mohli určité filesystemy mountovat s určitými volbami ( noexec, nosuid, nodev…).

Samotný jail zabírá o něco méně diskového prostoru, protože neobsahuje jádro a také můžete případně smazat nepotřebné soubory/adresáře.

V případě, že si nemůžete dovolit experimentovat s diskem nebo přidat nový, můžete využít pseudo-device vnode, který dovoluje použít soubor jako zařízení-disk. To s sebou přináší výhodu, že můžete buď předem definovat velikost takového souboru, nebo jej hlídat pomocí diskových kvót.

Vyzkoušíme si tedy vytvoření takového pseudo-zařízení, které poté rozdělíme na partitions pro jednotlivé filesystemy. Postup kroků bude následující: vytvoříme předem danou velikost souboru, vytvoříme auto tabulky oddílů, změníme ji pomocí disklabel, naformátujeme filesystemy a namountujeme.

srot# vnconfig -c -T -S 500M -s labels vn0 jail
srot# disklabel -r -w vn0 auto

# /dev/vn0c:
type: unknown
disk: amnesiac
label:
flags:
bytes/sector: 512
sectors/track: 32
tracks/cylinder: 64
sectors/cylinder: 2048
cylinders: 500
sectors/unit: 1024000
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0 # milliseconds
track-to-track seek: 0 # milliseconds
drivedata: 0

8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 50M * 4.2BSD
b: 100M * 4.2BSD
c: 1024000 0 unused 0 0 # (Cyl. 0 - 499)
d: 100M * 4.2BSD
e: 150M * 4.2BSD
f: * * 4.2BSD

srot# disklabel -r vn0
...zkráceno...
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 102400 0 4.2BSD 1024 8192 16 # (Cyl. 0 - 49)
b: 204800 102400 4.2BSD 1024 8192 16 # (Cyl. 50 - 149)
c: 1024000 0 unused 0 0 # (Cyl. 0 - 499)
d: 204800 307200 4.2BSD 1024 8192 16 # (Cyl. 150 - 249)
e: 307200 512000 4.2BSD 1024 8192 16 # (Cyl. 250 - 399)
f: 204800 819200 4.2BSD 1024 8192 16 # (Cyl. 400 - 499) 

Na nových oddílech vytvoříme souborový systém pomocí newfs /dev/vn0a, newfs /dev/vn0b atp. Poté si vytvořené filesystemy připojte do požadovaného adresáře, např. do /var/jails/10.0.0.4. Můžete si rovněž vytvořit soubor /etc/vntab, který je obdobou /etc/fstab pro vnode devices a připojovat tak tyto zařízení při startu. Více  man vnconfig.

Vytvoření jailu

Vytvoření jailu je podobné jako při kompilaci systému ze zdrojových kódů, např. po upgradu. Jedinou zásadní změnou je cíl umístění souborů. Jestliže jste si již systém ze zdrojových kódů kompilovali ( make buildworld), měli byste jej mít v /usr/obj. V případě, že nikoliv, budete muset provést sestavení celého systému ze zdrojových kódů (pro zkrácení cest používám symlink):

srot# cd /usr/src
srot# make world DESTDIR=/testjail 

Jestliže ale máte kompletně sestavený systém v /usr/obj, stačí pouhé:

srot# cd /usr/src && make installworld DESTDIR=/testjail 

Nemusíte samozřejmě systém sestavovat pořád dokola kvůli novým jailům, jen nemažte /usr/obj a pak jen  make installworld DESTDIR=/path/to/new_jail.

Dále je potřeba provést tyto kroky:

srot# cd /usr/src/etc && make distribution DESTDIR=/testjail NO_MAKEDEV_RUN=yes
srot# cd /testjail/dev && sh MAKEDEV jail
srot# cd /testjail && ln -sf dev/null kernel 

První řádek zkopíruje /etc soubory, druhý vytvoří zařízení pro jail a poslední udělá symlink. Existence souboru /kernel je nutná, můžete tedy udělat symlink nebo tam zkopírovat vlastní jádro, které tam bude zcela k ničemu, ale může to zmást.

Základní nastavení

Nyní máte kompletní jail. Je ale ještě potřeba udělat nějaké základní nastavení. Musíme upravit /etc/rc.conf (v jailu samozřejmě) tak, aby nám správně fungovali síť. démoni atd. Přepneme se tedy do prostředí jailu a pozměníme /etc/rc.conf.

srot# jail /testjail testjail 10.0.0.4 /bin/tcsh

portmap_enable="NO"
network_interfaces=""
syslogd_enable="YES"
syslogd_flags="-ss"
inetd_enable="NO"
sshd_enable="YES"
sendmail_enable="NO" 

Určite povolte sshd, je to nejlepší možnost pro správu jailu. Konfiguraci síťového rozhraní budeme ignorovat. Pro funkčnost jailu je nutná existence souboru /etc/fstab, i když jail nemá vládu nad připojováním souborových systémů.

srot# touch /etc/fstab 

V případě, že byste chtěli spustit sendmail, tak je potřeba ještě spustit newaliases na vytvoření nové databáze. Rovněž si nastavte nové a odlišné heslo od hostitelského systému pro superuživatele, pozměňte si /etc/login.conf, /etc/ssh/sshd_c­onfig, zvolte správnou časovou zónu – tzsetup, nadefinujte správné DNS servery – /etc/resolv.conf a založte uživatele. Dále zakomentujte tento řádek v  /etc/crontab:

#1.310-5 * * * root adjkerntz -a

Spouštění jailu

Oficiální postup pro spuštění jailu se skládá z připojení procfs a spuštění rc skriptů přes příkaz  jail:

srot# mount -t procfs proc /testjail/proc
srot# jail /testjail testjail 10.0.0.4 /bin/sh /etc/rc 

A tohle vidíme v jailu:

testjail# ps ax
PID TT STAT TIME COMMAND
18649 ?? IsJ 0:00.02 /usr/sbin/syslogd -ss
18659 ?? SsJ 0:00.04 /usr/sbin/cron
18661 ?? IsJ 0:00.06 /usr/sbin/sshd
18664 ?? SsJ 0:00.05 sendmail: accepting connections (sendmail)
18666 ?? IsJ 0:00.02 sendmail: Queue runner@00:30:00 for /var/spool/client
18689 ?? IJ 0:00.10 sshd: hospodin [priv] (sshd)
18692 ?? SJ 0:00.21 sshd: hospodin@ttyp2 (sshd)
18693 p2 IsJ 0:00.06 -tcsh (tcsh)
18701 p2 SJ 0:00.12 _su (csh)
18727 p2 R+J 0:00.00 ps ax 

Zastavování jailu

Zastavování jailu je trochu složitější. Vně jailu příkazy jako shutdown nefungují. Jail je tvořen procesy, a jestliže je ukončen i poslední proces, sám jail zanikne. Jestliže tedy chcete zastavit jail, můžete použít následující příkaz (pro zastavení určitých aplikací použijte ale vlastní skript):

testjail# kill -TERM -1 

Upozornění!!! Toto se zadává v jailu!!!

Pomocníci při správě jailu

Určitě jste už zjistili, že některé příkazy nefungují. Proč tedy tyto soubory neodstranit? Na internetové stránce jednoho z vývojářů pomocných aplikací pro správu jailů najdete seznam souborů (podle vaší verze FreeBSD), které mohou být odstraněny. Na další stránce tohoto vývojáře najdete rovněž sadu programů jailutils a jailer.

Jailutils

Jailutils se instalují na hostitelský systém a dovolují příjemnější spouštění, zastavování nebo vypsání běžících jailů. Ve verzi pro novou řadu, 5.x, jsou přidány i další obslužné prográmky, např. jps (wrapper k ps, který ukazuje, k jakému jailu proces patří).

srot# less /usr/ports/sysutils/jailutils/pkg-descr
Several utilies for managing jails.

4.x:

killjail shutdown or restart a jail (when used with jailer)
jails list the jails running on a system
jstart start up a jail securely

5.x:

jps List processes in a jail
jid Print id of a jail
jstart Start up a jail securily
jkill Shutdown a jail in an orderly fashion
jails List running jails

WWW: http://memberwebs.com/nielsen/freebsd/jails/jailutils/ 

Jailer

Jailer se instaluje do jailu a používá je jako prostředník před spuštěním samotných rc skriptů. Umí zastavovat procesy uvnitř jailu, restartovat celý jail nebo jej celý zastavit. Jailutils s jailerem mohou spolupracovat na ještě efektivnějším ukončování procesů.

root_podpora

Jailadmin

Jailadmin je asi nejzajímavějším hráčem na tomto poli. Umí velmi zajímavě spouštět a zastavovat jail, např. jde udělat skupinu jailů, třeba webservers, a mohou být tak spouštěny určité skupiny, a má podporu SNMP. Část konfiguračního souboru:

server1
ip: 10.0.1.2
hostname: www.domain1.com
# Appending (number) to the end of a mountpoint causes the system to
# pause for that many seconds after mounting it. Useful for adding
# a slight delay after NFS mounts so that they have time to become
# live before other filesystems are mounted inside them.
mount: /usr/ports(1),/usr/ports/distfiles,/dev 

Závěr

Snad se vám toto strohé představení jailu líbilo. Pro bližší interní věci se podívejte na článek na DaemonNews nebo zde. Rovněž jsem si všiml, že BSDHound má mirror na bsd.box.sk, kde můžete najít spousty zajímavých článků. Jinak opět se jednalo o FreeBSD 4.10, takže některé věci už mohou být v 5. řadě vylepšeny. V příštím dílu se ještě jednou podíváme na jaily, jailování samotných démonů a různé techniky propojování jailů. Poté přijde ukončující díl, který bude obsahovat souhrn a ukázky konfiguračních souborů, které jsme v seriálu použili.

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