FreeBSD minimalistisches Jail
From RootForum Community » Wiki
Contents |
Einleitung
Wie hier bereits beschrieben soll eine Jail für den Betrieb von Apache eingerichtet werden. Dabei sollen nur die nötigsten Daten in der Jail Umgebung zur Verfügung stehen. Es wird davon ausgegangen dass Apache bereits konfiguriert ist. Die zukünftige Jail heißt "www" und wird in /usr/jail/www eingerichtet.
Vorbereitung auf dem Hostsystem
Auf dem Host wird zuerst ein Verzeichnis für die Jail erstellt. Hier wird davon ausgegangen dass Apache mit mod_php / mod_ssl betrieben werden soll. Weiterhin soll eine Verbindung zu einer Datenbank (MySQL) möglich sein. In diesem Verzeichnis wird folgende Strukur mit Zugriffsrechten angelegt. Der Eigentümer ist immer root:wheel
chmod 500 /usr/jail/www/bin /usr/jail/www/root /usr/jail/www/sbin /usr/jail/www/usr/bin /usr/jail/www/usr/local/etc /usr/jail/www/usr/local/libexec /usr/jail/www/usr/local/sbin chmod 555 /usr/jail/www/dev /usr/jail/www/etc /usr/jail/www/lib /usr/jail/www/libexec /usr/jail/www/usr/lib /usr/jail/www/usr/libexec /usr/jail/www/usr/local/lib /usr/jail/www/usr/local/www /usr/jail/www/var/run /usr/jail/www/var/log chmod 777 /usr/jail/www/tmp /usr/jail/www/var/tmp - oder ein Symlink auf ../tmp
In die entsprechend angelegten Verzeichnisse werden nun die benötigten Dateien kopiert. Dabei die Zugriffsrechte beachten:
/usr/jail/www/bin/kill /usr/jail/www/bin/ps /usr/jail/www/bin/sh /usr/jail/www/bin/sleep
/usr/jail/www/etc/auth.conf /usr/jail/www/etc/group /usr/jail/www/etc/hosts /usr/jail/www/etc/localtime /usr/jail/www/etc/login.conf.db /usr/jail/www/etc/nsswitch.conf /usr/jail/www/etc/master.passwd /usr/jail/www/etc/rc.conf /usr/jail/www/etc/resolv.conf /usr/jail/www/etc/termcap
Bevor fortgefahren wird, sollte die "group" Datei bearbeitet werden. Wird mod_php verwendet, kann die entsprechende "group" Datei gekürzt werden auf:
wheel:*:0 www:*:80
Die "master.passwd" sollte ebenfalls auf die benötigten User reduziert werden. Für mod_php oder statische HTML Seiten reicht:
root:*:0:0::0:0:Charlie:/root:/bin/sh www:*:80:80::0:0:Www Pseudo:/nonexistent:/sbin/nologin
Weitere User für bspw. FastCGI müssen erhalten bleiben. Sind die Änderungen beendet werden diese mit
pwd_mkdb -d /usr/jail/www/etc/ /usr/jail/www/etc/master.passwd
übernommen. Danach kann die master.passwd gelöscht werden. Nun werden weitere Dateien kopiert.
/usr/jail/www/lib/libc.so.7 /usr/jail/www/lib/libcrypt.so.4 /usr/jail/www/lib/libcrypto.so.5 /usr/jail/www/lib/libedit.so.6 /usr/jail/www/lib/libipsec.so.3 /usr/jail/www/lib/libkvm.so.4 /usr/jail/www/lib/libm.so.5 /usr/jail/www/lib/libncurses.so.7 /usr/jail/www/lib/libreadline.so.7 /usr/jail/www/lib/libthr.so.3 /usr/jail/www/lib/libutil.so.7 /usr/jail/www/lib/libz.so.4 /usr/jail/www/libexec/ld-elf.so.1 /usr/jail/www/sbin/sysctl /usr/jail/www/usr/bin/grep /usr/jail/www/usr/lib/libbz2 /usr/jail/www/usr/lib/libgnuregex.so.4 /usr/jail/www/usr/lib/libmagic.so.3 /usr/jail/www/usr/lib/libpam.so.4 /usr/jail/www/usr/lib/libssl.so.5 /usr/jail/www/usr/libexec/ld-elf.so.1 - symbolischer Link auf ../../libexec/ld-elf.so.1 /usr/jail/www/usr/local/etc/rc.d/apache22 /usr/jail/www/usr/local/lib/mysql/libmysqlclient.so.15 - nur für MySQL Datenbank Verbindung nötig. /usr/jail/www/usr/local/lib/mysql/libmysqlclient_r.so.15 /usr/jail/www/usr/local/lib/charset.alias /usr/jail/www/usr/local/lib/libapr-1.so.3 /usr/jail/www/usr/local/lib/libaprutil-1.so.3 /usr/jail/www/usr/local/lib/libcharset.so.1 /usr/jail/www/usr/local/lib/libexpat.so.6 /usr/jail/www/usr/local/lib/libiconv.so.3 /usr/jail/www/usr/local/lib/libpcre.so.0 /usr/jail/www/usr/local/lib/php - Verzeichnis, falls PHP verwendet werden soll. /usr/jail/www/usr/local/libexec/apache22 - Verzeichis, für Apache Module /usr/jail/www/usr/local/sbin/httpd
Ist dies beendet, wird noch die Apache / PHP Konfiguration in /usr/local/etc kopiert und an die Jail Umgebung angepasst (IP Addressen).
Wird PHP verwendet, sind die jeweils benötigten Bibliotheken zu kopieren. Mit:
ldd /usr/local/lib/php/openssl.so
libssl.so.5 => /usr/lib/libssl.so.5 libcrypto.so.5 => /lib/libcrypto.so.5 libc.so.7 => /lib/libc.so.7
Finden sich die benötigten Bibliotheken. Gleiches gilt für Apache, je nachdem wie Apache aus den ports / packages installiert wurde.
Konfiguration des Hostsystem
Nachdem die Dateien kopiert wurden, kann mit "chroot" überprüft werden ob alle Bibliotheken vorhanden sind.
chroot PFAD_ZUR_JAIL/usr/local/sbin/httpd -H
Gibt die Hilfe aus, falls alles funktioniert.
Auf dem Host System müssen nun noch einige letzte Änderungen getroffen werden. Zuerst ein /dev Verzeichnis für die zukünftige Jail - dazu in /etc/fstab:
devfs /usr/jail/www/dev devfs rw 0 0
Da Devices wie /dev/ad0 nichts in der Jail zu suchen haben, wird in /etc/devfs.rules ein Eintrag angelegt, damit nur die nötigsten Devices zur Verfügung stehen:
[devfsrules_unserejail=5] add include $devfsrules_hide_all add path null unhide add path zero unhide add path crypto unhide add path random unhide add path urandom unhide add path fd unhide add path 'fd/*' unhide add path stdin unhide add path stdout unhide add path stderr unhide
crypto / random / urandom werden für SSL benötigt. Soll kein SSL zum Einsatz kommen, kann auf diese Devices verzichtet werden.
Nun zum letzten Schritt - der Eintrag in /etc/rc.conf
jail_www_rootdir="/usr/jail/www" jail_www_ip="DIE_IP" jail_www_hostname="DER_HOSTNAME" jail_www_exec_start="/bin/launch" jail_www_devfs_enable="YES" jail_www_devfs_rules="devfsrules_unserejail"
Konfiguration der Jail Umgebung
Bevor die Jail Umgebung jetzt gestart werden kann, ist noch ein kleines Script anzulegen dass "init" ersetzt.
/bin/launch
#!/bin/sh /sbin/sysctl kern.securelevel=3 /usr/local/etc/rc.d/apache22 start
Nun muss noch Apache aktiviert werden in /etc/rc.conf
apache22_enable="YES"
Falls "flags" oder "limits" übergeben werden sollen, sind diese wie auf dem Hostsystem in der Jail "rc.conf" mit anzugeben.
Ist dies abgeschlossen und Apache meldet per "chroot" dass alle Bibliotheken vorhanden sind, kann noch mit:
chflags schg `find /usr/jail/www/` chflags noschg /usr/jail/www/{tmp,var/log,var/run,var/tmp}
Das System Immutable Bit gesetzt werden. Diese Bit wird für temporäre und Log Verzeichnisse wieder entfernt. Werden temporäre Verzeichnisse verwendet für Uploads z. Bsp. sollte das Bit natürlich dort auch entfernt werden. Gleiches gilt für /usr/local/www, falls dies der zukünftige Webroot sein soll. Nachdem die Seiten im Webroot platziert sind und nicht geändert werden sollen, kann das entsprechende Bit wieder gesetzt werden.
Start der Jail und letzte Änderungen auf dem Hostsystem
Falls alles gut gegangen ist kann die Jail gestart werden:
mount /usr/jail/www/dev devfs -m /usr/jail/www/dev -s 5 applyset /etc/rc.d/jail start wwww
Mit jls / telnet / ps kann überprüft werden, ob Apache erreichbar ist und die Jail läuft. Funktioniert alles, können die "pf" oder "ipfw" Regeln übernommen werden. Falls Apache neu gestart werden soll ohne die ganze Jail zu beenden und neu zu starten, kann folgendes Script benutzt werden:
#!/bin/sh case "$1" in start) jexec `jls | grep -w "/usr/jail/www" | awk '{print $1;}'` /usr/local/etc/rc.d/apache22 start ;; stop) if test -e /usr/jail/www/var/run/httpd.pid then jexec `jls | grep -w "/usr/jail/www" | awk '{print $1;}'` /usr/local/etc/rc.d/apache22 stop else echo "ERROR: pidfile /usr/jail/www/var/run/httpd.pid does not exist." fi ;; restart) if test -e /usr/jail/www/var/run/httpd.pid then jexec `jls | grep -w "/usr/jail/www" | awk '{print $1;}'` /usr/local/etc/rc.d/apache22 stop else echo "ERROR: pidfile /usr/jail/www/var/run/httpd.pid does not exist. " fi jexec `jls | grep -w "/usr/jail/www" | awk '{print $1;}'` /usr/local/etc/rc.d/apache22 start ;; configtest) jexec `jls | grep -w "/usr/jail/www" | awk '{print $1;}'` /usr/local/etc/rc.d/apache22 configtest ;; reload) echo "Performing a graceful restart (reload)" if test -e /usr/jail/www/var/run/httpd.pid then jexec `jls | grep -w "/usr/jail/www" | awk '{print $1;}'` /usr/local/etc/rc.d/apache22 reload else echo "ERROR: pidfile /usr/jail/www/apache/var/run/httpd.pid does not exist. " fi ;; gracefulstop) jexec `jls | grep -w "/usr/jail/www" | awk '{print $1;}'` /usr/local/etc/rc.d/apache22 graceful-stop ;; *) echo "Usage: ${0##*/}: { start | stop | restart | reload | gracefulstop }" >&2 exit 64 ;; esac
Mögliche Probleme
Sollte Apache nicht starten, hilft ein Blick in den "error.log" vorrausgesetzt /var/log ist, je nach Konfiguration, angelegt. Auch /var/log/jail_www_console.log kann hilfreich sein, wenn Fehlermeldungen an stdout gesendet werden. Schließlich kann mit "chroot" wenn devfs gemountet wurde, Apache manuell gestartet werden. Vorsicht: Hier die IP Addressen beachten. Fehlen Bibliotheken müssen diese noch in die Jail Umgebung kopiert werden, hier temporär mit "chflags" das Immutable Bit entfernen und dann wieder setzen.
Aktualisierung der Jail Umgebung
Da die Jail Umgebung selbst über keine Paketverwaltung verfügt, muss die Aktualisierung vom Hostsystem erfolgen. Entweder manuell mit "cp" oder indem mit "find /usr/jail/www -type f" eine Datei für rsync's "include-from" erstellt wird.
Weitere Möglichkeiten
Will man weiter minimalisieren, kann auf "sh" und die Init Dateien in /etc verzichtet werden. Die entsprechenden Bibliotheken können dann ebenfalls entfernt werden, weiterhin muss in master.passwd / group nur der "www" User vorhanden sein. Falls CGI Prozesse oder FastCGI verwendet werden soll, macht es natürlich wenig Sinn auf /bin/sh zu verzichten.
Eine entsprechende Umgebung würde ungefähr so aussehen:
/usr/jail/www/dev - null / random / urandom Devices /usr/jail/www/etc/auth.conf - falls eine Auth verwendet werden soll /usr/jail/www/etc/group /usr/jail/www/etc/hosts /usr/jail/www/etc/localtime /usr/jail/www/etc/pwd.db /usr/jail/www/etc/resolv.conf /usr/jail/www/etc/spwd.db /usr/jail/www/lib/libc.so.7 /usr/jail/www/lib/libcrypt.so.4 /usr/jail/www/lib/libcrypto.so.5 /usr/jail/www/lib/libm.so.5 /usr/jail/www/lib/libncurses.so.7 /usr/jail/www/lib/libreadline.so.7 /usr/jail/www/lib/libthr.so.3 /usr/jail/www/lib/libz.so.4 /usr/jail/www/libexec/ld-elf.so.4 /usr/jail/www/usr/lib/libcrypt.so - Symlink auf ../../lib/libcrypt.so.4 /usr/jail/www/usr/lib/libcrypto.so - Symlink auf ../../lib/libcrypo.so.5 /usr/jail/www/usr/lib/libmagic.so.3 /usr/jail/www/usr/libexec/ld-elf.so.1 - Symlink auf ../../libexec/ld-elf.so.4 /usr/jail/www/usr/local/etc - Apache / PHP Konfiguration /usr/jail/www/usr/local/lib - wie im obigen Beispiel /usr/jail/www/usr/local/libexec - wie im obigen Beispiel /usr/jail/www/usr/local/sbin - wie im obigen Beispiel
Dazu noch das Webroot /usr/local/www und die Verzeichnisse in /var. Zum Starten bzw. Stoppen der Jail muss in /etc/rc.conf noch das Kommando geändert werden.
jail_www_exec_start="/usr/local/sbin/httpd"