logo_header

icon_bubbles Forum

icon_bubbles Wiki

icon_bubbles Planet

RootForum Community » Wiki

FreeBSD minimalistisches Jail

From RootForum Community » Wiki

Jump to:navigation, search

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"