====== Allgemein ======
Eine Jail ist ein abgeschotteter Systembereich zur Erhöhung der Systemsicherheit. Hierdurch werden Programme, bzw. Dienste ein einem getrennten Systembereich ausgeführt um das eigentliche System zu schützen. Im Prinzip ist es eine Erweiterung einer **chroot**-Umgebung. Teilweise wird es auch als Virtualisierung bezeichnet, jedoch ist eine Jail im Funktionsumfang keineswegs mit echten Virtualisierungen zu vergleichen. Genauere Details zum Sinn und der möglichen Nutzung von Jails sollen hier nicht aufgeführt werden.
Die Jail kann entweder aus den Binärpaketen installiert werden oder komplett aus den Quellen übersetzt. Beide Varianten werden hier aufgeführt, wobei die Installation aus den Binärpaketen deutlich schneller vollzogen ist.
====== Manuelle Verwaltung von Jails vs ezjail ======
Im weiteren Verlauf dieses Artikels wird gezeigt wie man von Hand Jails erstellen und verwalten kann. Dies ist, speziell wenn man mehrere Jails verwaltet, mit wachsendem Aufwand verbunden. Alternativ hierzu gibt es verschiedene Jail-Management-Programme wie z.B. //ezjail// welche diese Aufgaben stark vereinfachen können. Im Artikel [[EIn Jailsystem mit ezjail installieren]] wird die Installation und Konfiguration von //ezjail// erläutert.
====== Verzeichnisse anlegen ======
Um dem System eine gewisse Ordnung einzuhalten werden alle Jails im Folgenden unter ///usr/local/jails// erstellt. Dieser Ort ist frei wählbar und könnte z.B. auch auf einem anderen Datenträger liegen. Entsprechend sind die Verzeichnisangaben dann jedoch zu ändern.
Sollte das Verzeichnis welches die Jails halten soll noch nicht vorhanden sein wird es zunächst angelegt:
# cd /usr/local
# mkdir jails
Anschließend wird das Verzeichnis für die erste zu erstellende Jail angelegt. In diesem Beispiel trägt sie den Namen **testjail**.
# cd /usr/local/jails
# mkdir testjail
====== Installation aus Binärpaketen ======
Zur Installation der Jail aus Binärpaketen kann //bsdinstall// verwendet werden, welches bereits aus der Installation des Basissystems bekannt ist.
Wird //bsdinstall// verwendet um eine Jail zu installieren muss es wissen welche FreeBSD-Version es installieren soll. Um dies herauszufinden fragt es **uname -r** ab. Da die Installationsquellen für //bsdinstall// nur für die Veröffentlichungsversionen (z.B. 10.0-RELEASE) und nicht für darauf aufsetzende Patchversionen (z.B. 10.0-RELEASE-p7) vorhanden sind muss im Allgemeinen //bsdinstall// ein falscher Wert für **uname -r** untergeschoben werden. Hierzu kann die Umgebungsvariable **UNAME_r** gesetzt werden.
Um z.B. auf einem FreeBSD 10.0 System eine Jail zu installieren wird die Variable **UNAME_r** wie folgt gesetzt.
# sentenv UNAME_r 10.0-RELEASE
Hiermit liefert **uname -r** nun den gewünschten Wert.
Nun kann mittels //bsdinstall// die Installation begonnen werden.
# bsdinstall jail /usr/local/jails/testjail
Zunächst wird hier der Server ausgewählt von welchem die Installationsdateien heruntergeladen werden (falls nicht bereits bei einer vorherigen Installation geschehen). Anschiessend sind die zu installierenden Sets auszuwählen und der Download und deren Installation beginnt.
Nun wird noch das **root**-Kennwort gesetzt und ausgewählt welche Standarddienste in der Jail automatisch gestartet werden sollen (//dumpdev// sollte hier abgewählt werden wenn es nicht wirklich benötigt wird) und das **root**-Kennwort gesetzt. Abschliessend kann noch ein normaler Benutzeraccount angelegt werden und die Installation ist beendet.
Um das installierte Basisversion nun noch mit den aktuellen binären Patchlevel zu versorgen wird //freebsd-update// verwendet. Hierzu muss **UNAME_r** noch auf der Veröffentlichungsversion gesetzt bleiben.
# freebsd-update -b /usr/local/jails/testjail fetch install
Nun kann **UNAME_r** wieder zurückgesetzt werden, damit es in Zukunft wieder den korrekten Patchlevel liefert.
# unsetenv UNAME_r
Weiter geht es dann mit: [[Jail_erstellen#Jail_einrichten | Jail einrichten]]
====== Installation aus den Systemquellen ======
Die Installation aus den Systemquellen dauert länger und ist aufwändiger. Für ein normales System lohnt sich der Mehraufwand iA nicht so keine besonderen Kompileroptionen gewünscht werden.
===== Voraussetzungen =====
Es ist ein installiertes FreeBSD mit [[Systemquellen aktualisieren | installierten Systemquellen]] in ///usr/src// notwendig.
===== System kompilieren =====
Nachdem die Quellen der Jail vorhanden sind muss das System welches installiert werden soll kompiliert werden. Hierfür werden die Standardbefehle zum übersetzen des Basissystems verwendet. Die **make**-Befehle müssen immer unter ///usr/src// ausgeführt werden.
# cd /usr/src/
# make buildworld
Hierdurch wird das gesamte Basissystem übersetzt und in ///usr/obj// gespeichert. Dieser Vorgang kann, abhängig vom Computer, recht lange dauern. Immerhin wird ein komplettes, modernes Unix-System übersetzt.
===== System installieren =====
Das fertig kompilierte System wird nun an seinen Zielort kopiert. Dies geschieht mit folgendem Aufruf (auch hier wieder aus ///usr/src//).
# make installworld DESTDIR=/usr/local/jails/testjail
# make distribution DESTDIR=/usr/local/jails/testjail
====== Jail einrichten ======
Wurde die Jail **nicht** per //bsdinstall// installiert muss noch der Nameserver in der //etc/resolv.conf// der Jail definiert werden. Hierzu wird die Namensauflösung des Hostsystems übernommen.
cp /etc/resolv.conf /usr/local/jails/testjail/etc/resolv.conf
Nun wird noch die //adjkerntz//-Zeile in der ///usr/local/jails/testjail/etc/crontab// deaktiviert (ein # davor gesetzt):
#1,31 0-5 * * * root adjkerntz -a
Zuletzt wird das Logging so eingestellt, dass Nachrichten in eine Datei fließen und nicht in die Console. Hierzu wird in der Datei ///usr/local/jails/testjail/etc/syslogd.conf// die Zeile
*.err;kern.warning;auth.notice;mail.crit /dev/console
wie folgt geändert:
*.err;kern.warning;auth.notice;mail.crit /var/log/messages
Die Jail ist somit prinzipiell fertig.
Um die Messages von //syslog// in der Jail zu halten und sämtlichen Netzwerkverkehr von //syslogd// zu unterbinden wird die Datei ///usr/local/jails/testjail/etc/rc.conf// um die Zeile ergänzt (soll die Jail per syslogd in einen Remote-Rechner loggen - z.B. der Host - darf diese Zeile nicht gesetzt werden):
syslogd_flags="-ss"
===== Hostnamen setzen =====
Der Hostname muss noch festgelegt werden. Hierzu wird die Datei **/usr/local/jails/testjail/etc/hosts** entsprechend [[Installation#Hostnamen_in_/etc/hosts_setzen|angepasst]].
====== Anpassen des Hostsystems ======
Spätestens seit FreeBSD 10 werden Jails in einer eigenen Konfigurationsdatei des Hostsystems, der ///etc/jail.conf//, verwaltet.
===== jail.conf =====
Die //jail.conf// besteht aus einem allgemeinen Teil, der grundlegende Einstellungen für alle Jails enthält, und einem Teil der die speziellen Einstellungen jeder einzelnen Jail definiert.
##########################################
###### Allgemeine Einstellungen ######
# Jailstart
exec.start="/bin/sh /etc/rc";
# Jailstop
exec.stop="/bin/sh /etc/rc.shutdown";
# Aufraeumen
exec.clean;
# Devfs mounten
mount.devfs;
# Netzwerkkarte
interface="em0";
##########################################
###### Per Jail Einstellungen ######
testjail {
host.hostname = "testjail.example.com";
path = /usr/local/jails/testjail;
ip4.addr = "www.xxx.yyy.zzz";
}
Für jede weitere Jail wird ein neuer Abschnitt in den unteren Teil eingefügt.
===== Jail im RC-System eintragen =====
Um die Jail dem System bekannt zu machen und auf einfache Weise über das RC-System starten zu können wird die Datei ///etc/rc.conf// noch angepasst.
Es kommen folgende Einträge hinzu:
# JAILS
jail_enable="YES"
jail_list="testjail"
Der Eintrag **jail_enable** definiert ob Jails prinzipiell gestartet werden oder nicht. Unter **jail_list** wird eine durch Leerzeichen getrennte Liste von Jailnamen erwartet welche beim Systemstart automatisch gestartet werden sollen.
===== Lauschende Ports auf Host-IP beschränken =====
Da die IP der Jail ein Alias des Hostsystems ist wird auf Netzwerkanfragen auf diese IP prinzipiell das Hostsystem antworten. Um dies abzustellen müssen alle lauschenden Prozesse des Hostsystems ausschliesslich auf dessen IP lauschen.
Um die lauschenden Prozesse anzuzeigen kann der folgende Aufruf verwendet werden.
# sockstat -4
Alle Prozesse welche ***** als IP aufführen lauschen auf allen verfügbaren IPs. Um dies abzustellen müssen die Dienste entsprechend umkonfiguriert werden. Ein prominentes Beispiel ist der sshd-Server.
====== Jail starten und anhalten ======
Die Jail kann dann mit den folgenden Befehlen gestartet und wieder beendet werden.
# jail -c testjail
# jail -r testjail
Dabei steht **-c** für **create** zum Starten der Jail und **-r** für **remove** zum Beenden der Jail.
====== Jails auflisten ======
Eine Liste aller laufender Jails findet sich mit dem Befehlt **jls**. Dieser zeigt auch gleich die zur Jail zugehörigen ID **JID** die benötigt wird um z.B. über **jexec** mit der Jail zu kommunizieren.
====== In der Jail arbeiten (Shell in der Jail) ======
Um in der laufenden Jail eine Shell zu öffnen um hierin zu arbeiten wird der Befehl **jexec** verwendet. Hierzu muss die Jail laufen.
# jexec testjail /bin/sh
Alternativ kann eine Shell in der Jail mit dem folgenden Befehl gestartet werden:
# /etc/rc.d/jail console testjail
====== Rootkennwort ändern und Benutzer anlegen ======
Wurde die Jail per //bsdinstall// installiert wurde das root-Kennwort bereits gesetzt. Wurde die Installation jedoch aus den Systemquellen installiert muss noch das Kennwort des Benutzers root gesetzt werden.
Nach dem Login in die Jail per **jexec** sollte das Kennwort des **root**-Benutzers mittels **passwd** geändert werden.
Sollen noch normale Benutzer angelegt werden kann dies per **adduser** erfolgen.
Dieser kann z.B. für einen SSH-Login verwendet werden wenn man root-Logins per ssh verbieten möchte.
====== X11 verbieten ======
Da in einer Jail i.A. keine grafischen Anwendungen laufen sollte man das einkompilieren von X11-bezogenen Teilen unterbinden. Dieser Vorgang ist unter [[X11 verbieten]] beschrieben.
====== Mailsystem einrichten ======
Das Mailsystem der Jail muss noch entsprechend angepasst werden damit Mails an einen Empfänger zugestellt werden können. Hierzu muss mindestens der Hostname eingerichtet werden. Evtl. können Weiterleitungen in der Datei ///etc/mail/aliases// eingetragen werden (anschließend muss **newaliases** ausgeführt werden).
Ggf. bietet sich hier auch die Verwendung von [[ssmtp]] an.
====== Zeitzone einstellen ======
Anschließend sollte noch die Zeitzone richtig eingestellt werden. Am einfachsten geht das per **tzsetup**. Ist der Host auf UTC eingestellt sollte die Jail ebenfalls auf UTC laufen.
====== Ports-Tree verfügbar machen ======
Um Programme in der Jail zu installieren ist es sinnvoll einen Port-Tree vorliegen zu haben. Da im Allgemeinen im Hostsystem bereits ein Ports-Tree vorhanden ist kann dieser verwendet werden um nicht unnötig Speicherplatz für doppelte Datenhaltung zu verschwenden.
Durch einen **nullfs-mount** kann das Ports-Verzeichnis des Hosts in der Jail eingebunden werden. Um eine mögliche Sicherheitslücke zu vermeiden sollte der Ports-Tree schreibgeschützt in die Ports eingebunden werden.
===== Mounten des Port-Trees =====
Hierzu wird entweder per Hand der Ports-Tree read-only gemountet:
# mount_nullfs -o ro /usr/ports /usr/local/jails/testjail/usr/ports
oder automatisch beim Hochfahren über die Datei /etc/fstab des Hostsystems. Hierzu wird die **/etc/fstab** wie folgt erweitert:
/usr/ports /usr/local/jails/testjail/usr/ports nullfs ro 0 0
Zuvor muss das ports-Verzeichnis in der Jail angelegt sein.
===== make.conf anpassen =====
Damit die Ports nun auch gebaut werden können muss dem Gastsystem noch ein alternatives Verzeichnis mit Schreibrechten zugeteilt werden.
Die Datei **/etc/make.conf** hält diese Informationen. Um die gewünschte Änderung durchzuführen wird die Datei wie folgt ergänzt, oder nötigenfalls erzeugt:
WRKDIRPREFIX=/tmp
DISTDIR=/tmp/distfiles
PACKAGES=/tmp/packages
Nun werden die Arbeitsdaten der Ports unter /tmp des Gastsystems abgelegt und der Ports-Tree wird nicht durch die Ports geändert.
====== Startscript - Eigene Startbefehle festlegen ======
Soll die Jail beim Systemstart noch spezielle Befehle ausführen die nicht über //rc.conf// abgedeckt werden können, so können diese in das Startscript ///etc/rc.local// (innerhalb der Jail) aufgenommen werden.
====== Jail aktualisieren ======
Die Vorgehensweise um eine Jail zu aktualisieren wird im Artikel [[Jail aktualisieren]] beschrieben.