<?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <!-- The FreeBSD Documentation Project The FreeBSD German Documentation Project $FreeBSD$ $FreeBSDde: de-docproj/books/handbook/jails/chapter.sgml,v 1.23 2011/05/25 20:42:25 jkois Exp $ basiert auf: 1.27 --> <chapter id="jails"> <chapterinfo> <authorgroup> <author> <firstname>Matteo</firstname> <surname>Riondato</surname> <contrib>Beigetragen von </contrib> </author> </authorgroup> <authorgroup> <author> <firstname>Oliver</firstname> <surname>Peter</surname> <contrib>Übersetzt von </contrib> </author> <author> <firstname>Dirk</firstname> <surname>Arlt</surname> </author> <author> <firstname>Johann</firstname> <surname>Kois</surname> </author> </authorgroup> </chapterinfo> <title>Jails</title> <indexterm><primary>jails</primary></indexterm> <sect1 id="jails-synopsis"> <title>Übersicht</title> <para>Dieses Kapitel erklärt, was &os;-Jails sind und wie man sie einsetzt. Jails, manchmal als Ersatz für <emphasis>chroot-Umgebungen</emphasis> bezeichnet, sind ein sehr mächtiges Werkzeug für Systemadministratoren, jedoch kann deren grundlegende Verwendung auch für fortgeschrittene Anwender nützlich sein.</para> <para>Nachdem Sie dieses Kapitel gelesen haben, werden Sie</para> <itemizedlist> <listitem> <para>Wissen, was eine Jail ist und welche Verwendungszwecke es dafür unter &os; gibt.</para> </listitem> <listitem> <para>Wissen, wie man eine Jail erstellt, startet und und anhält.</para> </listitem> <listitem> <para>Die Grundlagen der Jail-Administration (sowohl innerhalb als auch ausserhalb des Jails) kennen.</para> </listitem> </itemizedlist> <para>Weitere nützliche Informationen über Jails sind beispielsweise in folgenden Quellen zu finden:</para> <itemizedlist> <listitem> <para>Der &man.jail.8; Manualpage. Diese umfassende Referenz beschreibt, wie man unter &os; eine Jail startet, anhält und kontrolliert.</para> </listitem> <listitem> <para>Den Mailinglisten und deren Archive. Die Archive der Mailingliste &a.questions; und anderen Mailinglisten, welche vom &a.mailman.lists; bereitgestellt werden, beinhalten bereits umfangreiche Informationen zu Jails. Daher ist es sinnvoll, bei Problemen mit Jails zuerst die Archive der Mailinglisten zu durchsuchen, bevor Sie eine neue Anfrage auf der Mailingliste &a.questions.name; stellen.</para> </listitem> </itemizedlist> </sect1> <sect1 id="jails-terms"> <title>Jails - Definitionen</title> <para>Um die für den Einsatz von Jails benötigten FreeBSD-Funktionen, deren Interna sowie die Art und Weise, mit der diese mit anderen Teilen des Betriebssystems interagieren, zu erläutern, werden in diesem Kapitel folgende Definitionen verwendet:</para> <variablelist> <varlistentry> <term>&man.chroot.8; (-Befehl)</term> <listitem> <para>Ein Werkzeug, das den &os;-Systemaufruf &man.chroot.2; verwendet, um das Wurzelverzeichnis eines Prozesses und all seiner Nachkömmlinge zu ändern.</para> </listitem> </varlistentry> <varlistentry> <term>&man.chroot.2; (-Umgebung)</term> <listitem> <para>Die Umgebung eines Prozesses, der in einem <quote>chroot</quote> läuft. Diese beinhaltet Ressourcen, wie zum Beispiel sichtbare Abschnitte des Dateisystems, verfügbare Benutzer- und Gruppenkennungen, Netzwerkschnittstellen und weitere IPC-Mechanismen und so weiter.</para> </listitem> </varlistentry> <varlistentry> <term>&man.jail.8; (-Befehl)</term> <listitem> <para>Das Systemadministrationswerkzeug, welches es erlaubt, Prozesse innerhalb der Jail-Umgebung zu starten.</para> </listitem> </varlistentry> <varlistentry> <term>Host (-Benutzer, -Prozess, -System)</term> <listitem> <para>Das verwaltende System einer Jail-Umgebung. Das Host-System hat Zugriff auf alle verfügbaren Hardwareressourcen und kann sowohl innerhalb als auch ausserhalb der Jail-Umgebung Prozesse steuern. Einer der wichtigsten Unterschiede des Host-System einer Jails ist, dass die Einschränkungen, welche für die Superuser-Prozesse innerhalb eines Jails gelten, nicht für die Prozesse des Host-Systems gelten.</para> </listitem> </varlistentry> <varlistentry> <term>Gast (-Benutzer, -Prozess, -System)</term> <listitem> <para>Ein Prozess, ein Benutzer oder eine andere Instanz, deren Zugriff durch eine &os;-Jail eingeschränkt ist.</para> </listitem> </varlistentry> </variablelist> </sect1> <sect1 id="jails-intro"> <title>Einführung</title> <para>Da die Systemadministration oft eine schwierige Aufgabe ist, wurden viele mächtige Werkzeuge entwickelt, die Administratoren bei Installation, Konfiguration und Wartung ihrer Systeme unterstützen sollen. Eine wichtige Aufgabe eines Administrators ist es, Systeme so abzusichern, dass es im regulären Betrieb zu keinen Sicherheitsverstößen kommt.</para> <para>Eines der Werkzeuge, mit dem die Sicherheit eines &os;-Systems verbessert werden kann, sind Jails. Jails wurden schon in &os; 4.X von &a.phk; eingeführt, wurden jedoch mit &os; 5.X stark verbessert, sodass sie inzwischen zu einem mächtigen und flexiblen Subsystem herangereift sind. Trotzdem geht die Entwicklung nach wie vor weiter. Wichtige Ziele sind derzeit: Bessere Zweckmäßigkeit, Leistung, Ausfallsicherheit und allgemeine Sicherheit.</para> <sect2 id="jails-what"> <title>Was ist eine Jail?</title> <para>BSD-ähnliche Betriebssysteme besitzen seit den Zeiten von 4.2BSD &man.chroot.2;. Das Werkzeug &man.chroot.2; kann dazu benutzt werden, das root-Verzeichnis einer Reihe von Prozessen zu ändern, um so eine seperate sichere Umgebung (abgeschnitten vom Rest des Systems) zu schaffen. Prozesse, die in einer chroot-Umgebung erstellt wurden, können nicht auf Dateien oder Ressourcen zugreifen, die sich ausserhalb der Umgebung befinden. Dadurch ist es einem kompromittierten Dienst nicht möglich, das gesamte System zu kompromittieren. &man.chroot.8; eignet sich für einfache Aufgaben, die keine flexiblen, komplexen oder fortgeschrittenen Funktionen benötigen. Obwohl seit der Entwicklung des chroot-Konzepts zahlreiche Sicherheitslöcher geschlossen wurden, die es einem Prozess erlauben konnten, aus einer Jail auszubrechen, war seit langer Zeit klar, dass &man.chroot.2; nicht die ideale Lösung ist, einen Dienst sicher zu machen.</para> <para>Dies ist einer der Hauptgründe, warum <emphasis>Jails</emphasis> entwickelt wurden.</para> <para>Jails setzen auf dem traditionellen &man.chroot.2;-Konzept auf und verbessern es auf unterschiedlichste Art und Weise. In einer traditionellen &man.chroot.2;-Umgebung sind Prozesse auf den Bereich des Dateisystems beschränkt, auf den sie zugreifen können. Der Rest der Systemressourcen (wie zum Beispiel eine Reihe von Systembenutzern, die laufenden Prozesse oder das Netzwerk-Subsystem) teilen sich die chroot-Prozesse mit dem Host-System. Jails dehnen dieses Modell nicht nur auf die Virtualisierung des Zugriffs auf das Dateisystem, sondern auch auf eine Reihe von Benutzern, das Netzwerk-Subsystem des &os;-Kernels und weitere Bereiche aus. Eine ausführlichere Übersicht der ausgefeilten Bedienelemente zur Konfiguration einer Jail-Umgebung finden Sie im Abschnitt <xref linkend="jails-tuning"/> des Handbuchs.</para> <para>Eine Jail zeichnet sich durch folgende Merkmale aus:</para> <itemizedlist> <listitem> <para>Einen Unterverzeichnisbaum, der die Jail enthält. Einem Prozess, der innerhalb der Jail läuft, ist es nicht mehr möglich, aus diesem auszubrechen. Von der traditionellen &man.chroot.2;-Umgebung bekannte Sicherheitsprobleme existieren bei &os;-Jails nicht mehr.</para> </listitem> <listitem> <para>Einen Hostname, der innerhalb der Jail verwendet wird. Jails werden vor allem dazu verwendet, Netzwerkdienste anzubieten, daher ist es für Systemadministratoren von großem Nutzen, dass jede Jail einen beschreibenden Hostname haben kann.</para> </listitem> <listitem> <para>Eine <acronym>IP</acronym> Adresse, die der Jail zugewiesen wird und nicht verändert werden kann, solange das Jail läuft. Die IP-Adresse einer Jails ist üblicherweise ein Adress-Alias auf eine existierende Netzwerkschnittstelle. Dies ist jedoch nicht zwingend erforderlich.</para> </listitem> <listitem> <para>Einen Befehl (genauer den Pfad einer ausführbaren Datei) der innerhalb der Jail ausgeführt werden soll. Dieser Pfad wird relativ zum root-Verzeichnis einer Jail-Umgebung angegeben und kann sehr unterschiedlich aussehen (je nachdem, wie die Jail-Umgebung konfiguriert wurde).</para> </listitem> </itemizedlist> <para>Unabhängig davon können Jails eine Reihe eigener Benutzer und einen eigenen Benutzer <username>root</username> haben. Selbstverständlich sind die Rechte des Benutzers <username>root</username> nur auf die Jail-Umgebung beschränkt. Aus der Sicht des Host-Systems ist der Benutzer <username>root</username> der Jail-Umgebung kein allmächtiger Benutzer, da der Benutzer <username>root</username> der Jail-Umgebung nicht dazu berechtigt ist, kritische Operationen am System ausserhalb der angebundenen &man.jail.8;-Umgebung durchzuführen. Weitere Informationen über die Einsatzmöglichkeiten und Beschränkungen des Benutzers <username>root</username> werden im Abschnitt <xref linkend="jails-tuning"/> des Handbuchs besprochen.</para> </sect2> </sect1> <sect1 id="jails-build"> <title>Einrichtung und Verwaltung von Jails</title> <para>Einige Administratoren unterscheiden zwei verschiedene Jail-Arten: <quote>Komplette</quote> Jails, die ein echtes &os; darstellen und Jails für einen bestimmten <quote>Dienst</quote>, die nur einer bestimmten Anwendung oder einem Dienst (der möglicherweise mit besonderen Privilegien laufen soll) gewidmet sind. Dies ist aber nur eine konzeptuelle Unterscheidung, die Einrichtung einer Jail bleibt davon gänzlich unberührt.</para> <screen>&prompt.root; <userinput>setenv D <replaceable>/hier/ist/die/jail</replaceable></userinput> &prompt.root; <userinput>mkdir -p $D</userinput> <co id="jailpath"/> &prompt.root; <userinput>cd /usr/src</userinput> &prompt.root; <userinput>make buildworld</userinput> <co id="jailbuildworld"/> &prompt.root; <userinput>make installworld DESTDIR=$D</userinput> <co id="jailinstallworld"/> &prompt.root; <userinput>make distribution DESTDIR=$D</userinput> <co id="jaildistrib"/> &prompt.root; <userinput>mount -t devfs devfs $D/dev</userinput> <co id="jaildevfs"/></screen> <calloutlist> <callout arearefs="jailpath"> <para>Das Festlegen des Installationsorts für das Jail eignet sich am besten als Startpunkt. Hier wird sich die Jail innerhalb des Host-Dateisystems befinden. Eine gute Möglichkeit wäre etwa <filename class="directory">/usr/jail/<replaceable>name_der_jail</replaceable></filename>, wobei <replaceable>name_der_jail</replaceable> den Hostname darstellt, über den die Jail identifiziert werden soll. Das Dateisystem unterhalb von <filename class="directory">/usr/</filename> stellt normalerweise aussreichend Platz für eine Jail zur Verfügung (bedenken Sie, dass eine <quote>komplette</quote> Jail ein Replikat einer jeden Datei der Standardinstallation des &os;-Basissystems enthält.</para> </callout> <callout arearefs="jailbuildworld"> <para>Wenn Sie bereits ihre Systemanwendungen mittels <command>make world</command> oder <command>make buildworld</command> neu erstellt haben, können Sie diesen Schritt überspringen und die Systemanwendungen in die neue Jail installieren.</para> </callout> <callout arearefs="jailinstallworld"> <para>Dieser Befehl wird den Verzeichnisbaum mit allen notwendigen Binärdateien, Bibliotheken, Manualpages usw. erstellen.</para> </callout> <callout arearefs="jaildistrib"> <para>Der <maketarget>distribution</maketarget>-Befehl lässt <application>make</application> alle benötigten Konfigurationsdateien installieren, es werden also alle installierbaren Dateien aus <filename class="directory">/usr/src/etc/</filename> in das Verzeichnis <filename class="directory">/etc</filename> der Jail installiert (also nach <filename class="directory">$D/etc/</filename>).</para> </callout> <callout arearefs="jaildevfs"> <para>Das Einhängen des &man.devfs.8;-Dateisystems innerhalb der Jail ist nicht unbedingt notwendig. Allerdings benötigt fast jede Anwendung Zugriff auf wenigstens ein Gerät. Es ist daher sehr wichtig, den Zugriff auf Devices aus der Jail heraus zu kontrollieren, da unsaubere Einstellungen es einem Angreifer erlauben könnten, in das System einzudringen. Die Kontrolle über &man.devfs.8; erfolgt durch die in den Manualpages &man.devfs.8; und &man.devfs.conf.5; beschriebenen Regeln.</para> </callout> </calloutlist> <para>Ist eine Jail einmal erst erstellt, kann sie durch &man.jail.8; gestartet werden. &man.jail.8; benötigt zwingend mindestens vier Argumente, die im Abschnitt <xref linkend="jails-what"/> des Handbuchs beschrieben sind. Weitere Argumente sind möglich, um beispielsweise die Jail mit den Berechtigungen eines bestimmten Benutzers laufen zu lassen. Das Argument <option><replaceable>command</replaceable></option> hängt vom Typ der Jail ab; für ein <emphasis>virtuelles System</emphasis> ist <filename>/etc/rc</filename> eine gute Wahl, da dies dem Startvorgang eines echten &os;-Systems entspricht. Bei einer <emphasis>Service</emphasis>-Jail hängt dieses von der Art des Dienstes ab, der in der Jail laufen soll.</para> <para>Jails werden häufig mit dem Betriebssystem gestartet, da der <filename>rc</filename>-Mechanismus von &os; dafür eine einfach zu realisierende Möglichkeit bietet.</para> <procedure> <step> <para>Eine Liste der Jails, die mit dem Betriebssystem gestartet werden sollen, wird in die Datei &man.rc.conf.5; geschrieben:</para> <programlisting>jail_enable="YES" # Set to NO to disable starting of any jails jail_list="<replaceable>www</replaceable>" # Space separated list of names of jails</programlisting> <note> <para>Die Namen der Jails in der <varname>jail_list</varname> sollten nur alphanumerische Zeichen enthalten.</para> </note> </step> <step> <para>Für jede Jail in der <varname>jail_list</varname> sollten in &man.rc.conf.5; einige Einstellungen vorgenommen werden:</para> <programlisting>jail_<replaceable>www</replaceable>_rootdir="/usr/jail/www" # jail's root directory jail_<replaceable>www</replaceable>_hostname="<replaceable>www</replaceable>.example.org" # jail's hostname jail_<replaceable>www</replaceable>_ip="192.168.0.10" # jail's IP address jail_<replaceable>www</replaceable>_devfs_enable="YES" # mount devfs in the jail jail_<replaceable>www</replaceable>_devfs_ruleset="<replaceable>www_ruleset</replaceable>" # devfs ruleset to apply to jail</programlisting> <para>Beim Start einer in &man.rc.conf.5; konfigurierten Jail wird das <filename>/etc/rc</filename>-Skript der Jail (das "annimmt", dass es sich in einem kompletten System befindet) aufgerufen. Für Service-Jails sollten die Startskripte der Jail durch das Setzen der Option <varname>jail_<replaceable>jailname</replaceable>_exec_start</varname> entsprechend angepasst werden.</para> <note> <para>Eine vollständige Liste der Optionen findet sich in der Manualpage zu &man.rc.conf.5;.</para> </note> </step> </procedure> <para>Das <filename>/etc/rc.d/jail</filename>-Skript kann zum manuellen Starten und Stoppen der Jail genutzt werden, wenn ein Eintrag in <filename>rc.conf</filename> angelegt wurde:</para> <screen>&prompt.root; <userinput>/etc/rc.d/jail start <replaceable>www</replaceable></userinput> &prompt.root; <userinput>/etc/rc.d/jail stop <replaceable>www</replaceable></userinput></screen> <para>Es gibt momentan keinen sauberen Weg, eine &man.jail.8; zu stoppen. Dies liegt daran, dass die Kommandos zum sauberen Herunterfahren eines Systems innerhalb einer Jail nicht ausgeführt werden können. Der beste Weg eine Jail zu beenden ist es daher, innerhalb der Jail den folgenden Befehl auszuführen (alternativ können Sie auch &man.jexec.8; von außerhalb der Jail aufrufen):</para> <screen>&prompt.root; <userinput>sh /etc/rc.shutdown</userinput></screen> <para>Weitere Informationen zu diesem Thema finden Sie in der Manualpage &man.jail.8;.</para> </sect1> <sect1 id="jails-tuning"> <title>Feinabstimmung und Administration</title> <para>Es gibt verschiedene Optionen, die für jede Jail gesetzt werden können und verschiedene Wege, ein &os;-Host-System mit Jails zu kombinieren. Dieser Abschnitt zeigt Ihnen:</para> <itemizedlist> <listitem> <para>Einige zur Verfügung stehende Optionen zur Abstimmung des Verhaltens und der Sicherheitseinstellungen, die mit einer Jail-Installation ausgeführt werden können.</para> </listitem> <listitem> <para>Einige der Anwendungsprogramme für das Jail-Management, die über die &os; Ports-Sammlung verfügbar sind und genutzt werden können, um Jail-basierte Lösungen allumfassend umzusetzen.</para> </listitem> </itemizedlist> <sect2 id="jails-tuning-utilities"> <title>Systemwerkzeuge zur Feinabstimmung von Jails in &os;</title> <para>Die Feinabstimmung einer Jail-Konfiguration erfolgt zum Großteil durch das Setzen von &man.sysctl.8;-Variablen. Es gibt einen speziellen sysctl-Zweig, der als Basis für die Organisation aller relevanten Optionen dient: Die <varname>security.jail.*</varname>-Hierarchie der &os;-Kerneloptionen. Die folgende Liste enthält alle jail-bezogenen sysctls (inklusiver ihrer Voreinstellungen). Die Namen sollten selbsterklärend sein, für weitergehende Informationen lesen Sie bitte die Manualpages &man.jail.8; und &man.sysctl.8;.</para> <itemizedlist> <listitem> <para><varname>security.jail.set_hostname_allowed: 1</varname></para> </listitem> <listitem> <para><varname>security.jail.socket_unixiproute_only: 1</varname></para> </listitem> <listitem> <para><varname>security.jail.sysvipc_allowed: 0</varname></para> </listitem> <listitem> <para><varname>security.jail.enforce_statfs: 2</varname></para> </listitem> <listitem> <para><varname>security.jail.allow_raw_sockets: 0</varname></para> </listitem> <listitem> <para><varname>security.jail.chflags_allowed: 0</varname></para> </listitem> <listitem> <para><varname>security.jail.jailed: 0</varname></para> </listitem> </itemizedlist> <para>Diese Variablen können vom Administrator des <emphasis>Host-Systems</emphasis> genutzt werden, um Beschränkungen hinzuzufügen oder aufzuheben, die dem Benutzer <username>root</username> als Vorgabe auferlegt sind. Beachten Sie, dass es einige Beschränkungen gibt, die nicht verändert werden können. Der Benutzer <username>root</username> darf innheralb der &man.jail.8; keine Dateisysteme mounten und unmounten. Ebenso ist es ihm untersagt, das &man.devfs.8;-Regelwerk zu laden oder zu entladen. Er darf weder Firewallregeln setzen, noch administrative Aufgaben erledigen, die Modifikationen am Kernel selbst erfordern (wie bespielsweise das Setzen des <varname>Securelevels</varname> des Kernel.</para> <para>Das &os;-Basissystem enthält einen Basissatz an Werkzeugen, um Informationen über aktive Jails zu erlangen und einer Jail administrative Befehle zuzuordnen. Die Befehle &man.jls.8; und &man.jexec.8; sind Teil des &os;-Basissystems und können für folgende Aufgaben verwendet werden:</para> <itemizedlist> <listitem> <para>Das Anzeigen einer Liste der aktiven Jails und ihrer zugehörigen Jail Identifier (<acronym>JID</acronym>), ihrer <acronym>IP</acronym>-Addresse, ihres Hostnames und ihres Pfades.</para> </listitem> <listitem> <para>Das Herstellen einer Verbindung mit einer laufenden Jail, das Starten eines Befehls aus dem gastgebenen System heraus oder das Ausführen einer administrativen Aufgabe innerhalb der Jail selbst. Dies ist insbesondere dann nützlich, wenn der Benutzer <username>root</username> die Jail sauber herunterfahren möchte. &man.jexec.8; kann auch zum Starten einer Shell innerhalb der Jail genutzt werden, um adminstrative Aufgaben durchzuführen:</para> <screen>&prompt.root; <userinput>jexec <replaceable>1</replaceable> tcsh</userinput></screen> </listitem> </itemizedlist> </sect2> <sect2 id="jails-tuning-admintools"> <title>High-Level-Werkzeuge zur Jail-Administration in der &os; Ports-Sammlung</title> <para>Unter den zahlreichen Fremdwerkzeugen für die Administration von Jails sind die <filename role="package">sysutils/jailutils</filename> die vollständigsten und brauchbarsten. Dabei handelt es sich um eine Sammlung kleiner Anwendungen, die das &man.jail.8;-Management vereinfachen. Weitere Informationen zu diesen Werkzeugen finden Sie auf den entsprechenden Internetseiten.</para> </sect2> </sect1> <sect1 id="jails-application"> <title>Anwendung von Jails</title> <sect2 id="jails-service-jails"> <sect2info> <authorgroup> <author> <firstname>Daniel</firstname> <surname>Gerzo</surname> <contrib>Beigetragen von </contrib> <!-- 15. May 2007 --> </author> </authorgroup> </sect2info> <title>Service-Jails</title> <para>Dieser Abschnitt basiert auf einer von &a.simon; auf <ulink url="http://simon.nitro.dk/service-jails.html"></ulink> präsentierten Idee und einem aktualisierten Artikel von Ken Tom (<email>locals@gmail.com</email>). Er beschreibt, wie ein &os;-System durch Benutzung der &man.jail.8;-Funktion mit zusätzlichen Sicherheitsebenen ausgestattet werden kann. Es wird dabei angenommen, dass auf Ihrem &os;-System RELENG_6_0 oder neuer installiert ist und dass Sie die Informationen aus den vorangehenden Abschnitten gelesen und verstanden haben.</para> <sect3 id="jails-service-jails-design"> <title>Design</title> <para>Eines der Hauptprobleme bei Jails ist das Management ihres Upgrade-Prozesses. Dieser neigt dazu, problematisch zu sein, da jede Jail bei jedem Upgrade komplett neu gebaut werden muss. Das stellt normalerweise kein Problem dar, wenn es sich um eine einzelne Jail handelt, da der Upgrade-Prozess recht einfach ist. Verwenden Sie aber eine größere Anzahl von Jails, kann dieser Prozess sehr zeitaufwendig werden.</para> <warning> <para>Diese Konfiguration erfordert fortgeschrittene Kenntnisse im Umgang mit &os; sowie der Benutzung seiner Funktionen. Sollten die unten vorgestellten Schritte zu kompliziert wirken, wird empfohlen, sich einfachere Verfahren wie <filename role="package">sysutils/ezjail</filename> anzusehen, da diese einfachere Methoden zur Administration von Jails verwenden und daher nicht so anspruchsvoll sind wie der hier beschriebene Aufbau.</para> </warning> <para>Diese Konfiguration basiert darauf, Jails so weit als möglich gemeinsam zu verwalten. Dies passiert auf sichere Art und Weise durch den Einsatz von &man.mount.nullfs.8;-Mounts (read-only). Dadurch werden Aktualisierungen erleichtert und das Verteilen von verschiedenen Diensten auf verschiedene Jails wird attraktiver. Außerdem bietet dieses Verfahren einen einfachen Weg, Jails hinzuzufügen, zu entfernen und zu aktualisieren.</para> <note> <para>Beispiele für Dienste sind in diesem Zusammenhang: Ein <acronym>HTTP</acronym>-Server, ein <acronym>DNS</acronym>-Server, ein <acronym>SMTP</acronym>-Server und so weiter.</para> </note> <para>Die Ziele des in diesem Abschnitt beschriebenen Aufbaus sind:</para> <itemizedlist> <listitem> <para>Das Erstellen einer einfachen und gut verständlichen Struktur von Jails. Dies beinhaltet, <emphasis>nicht</emphasis> für jede Jail ein vollständiges installworld laufen lassen zu müssen.</para> </listitem> <listitem> <para>Es einfach zu machen, neue Jails zu erstellen oder alte zu entfernen.</para> </listitem> <listitem> <para>Es einfach zu machen, bestehende Jails zu aktualisieren.</para> </listitem> <listitem> <para>Es einfach zu machen, einen angepassten &os;-Zweig zu nutzen.</para> </listitem> <listitem> <para>Paranoid bezüglich Sicherheit zu sein und Angriffsmöglickeiten weitgehend zu reduzieren.</para> </listitem> <listitem> <para>Soviel Platz und Inodes wie möglich einzusparen.</para> </listitem> </itemizedlist> <para>Wie bereits erwähnt, ist dieses Design stark darauf angewiesen, dass eine read-only-Hauptvorlage in jede Jail hinein gemountet wird (bekannt als <application>nullfs</application>), und dass jede Jail über wenigstens ein beschreibbares Gerät verfügt. Das Gerät kann hierbei eine separate physikalische Platte oder ein vnode unterstütztes &man.md.4;-Gerät sein. Im folgenden Beispiel wird ein <application>nullfs</application>-Mount genutzt, auf den nur Lesezugriff erlaubt ist.</para> <para>Das Layout des Dateisystems wird in der folgenden Liste beschrieben:</para> <itemizedlist> <listitem> <para>Jede Jail wird unterhalb des <filename class="directory">/home/j</filename>-Verzeichnisses gemountet.</para> </listitem> <listitem> <para><filename class="directory">/home/j/mroot</filename> ist die Vorlage für jede Jail und die nur lesbare Partition für alle Jails.</para> </listitem> <listitem> <para>Unterhalb von <filename class="directory">/home/j</filename> wird für jede Jail ein leeres Verzeichnis angelegt.</para> </listitem> <listitem> <para>Jede Jail bekommt ein <filename class="directory">/s</filename>-Verzeichnis, das zum read/write-Teilbereich des Systems verlinkt wird.</para> </listitem> <listitem> <para>Jede Jail bekommt ihr eigenes read/write-System, das auf <filename class="directory">/home/j/skel</filename> basiert.</para> </listitem> <listitem> <para>Jeder Jailbereich (genauer der read/write-Teilbereich jeder Jail) wird in <filename class="directory">/home/js</filename> erstellt.</para> </listitem> </itemizedlist> <note> <para>Es wird angenommen, dass die Jails sich unterhalb des <filename class="directory">/home</filename> Verzeichnisses befinden. Dieser Ort kann von Ihnen natürlich geändert werden. Allerdings müssen die Pfade in den folgenden Beispielen dann entsprechend angepasst werden.</para> </note> <!-- Insert an image or drawing here to illustrate the example. --> </sect3> <sect3 id="jails-service-jails-template"> <title>Erstellen der Vorlage</title> <para>Dieser Abschnitt beschreibt die Schritte, die zum Erstellen der Hauptvorlage (die den nur lesbaren Bereich für alle weiteren Jails darstellt) notwendig sind.</para> <para>Es ist immer eine gute Idee, &os; auf den aktuellen -RELEASE-Zweig zu aktualisieren. Lesen Sie das entsprechende <ulink url="&url.books.handbook;/makeworld.html">Kapitel</ulink> des Handbuchs für Informationen zu diesem Thema. Selbst wenn Sie auf eine Aktualisierung des Betriebssystems verzichten, müssen Sie dennoch ein buildworld durchführen, um fortfahren zu können. Außerdem müssen Sie das Paket <filename role="package">sysutils/cpdup</filename> installiert sein. In diesem Beispiel wird &man.portsnap.8; verwendet, um die aktuelle &os; Ports-Sammlung herunterzuladen. Der Abschnitt <ulink url="&url.books.handbook;/portsnap.html">Portsnap</ulink> des Handbuchs beschreibt, wie Sie dieses Werkzeug effektiv einsetzen.</para> <procedure> <step> <para>Zuerst erstellen wir eine Verzeichnissstruktur für das read-only-Dateisystem, das die &os;-Binärdateien für unsere Jails enthalten wird. Anschließend wechseln wir in den &os;-Quellcodebaum und installieren das read-only-Dateisystem in die (Vorlage-)Jail.</para> <screen>&prompt.root; <userinput>mkdir /home/j /home/j/mroot</userinput> &prompt.root; <userinput>cd /usr/src</userinput> &prompt.root; <userinput>make installworld DESTDIR=/home/j/mroot</userinput></screen> </step> <step> <para>Als nächstes bereiten wir die Ports-Sammlung fü die Jails vor und kopieren den &os; Quellcodebaum in die Jail, da dieser für <application>mergemaster</application> benötigt wird:</para> <screen>&prompt.root; <userinput>cd /home/j/mroot</userinput> &prompt.root; <userinput>mkdir usr/ports</userinput> &prompt.root; <userinput>portsnap -p /home/j/mroot/usr/ports fetch extract</userinput> &prompt.root; <userinput>cpdup /usr/src /home/j/mroot/usr/src</userinput></screen> </step> <step> <para>Danach wird die Struktur für den read/write-Bereich des Systems erstellt:</para> <screen>&prompt.root; <userinput>mkdir /home/j/skel /home/j/skel/home /home/j/skel/usr-X11R6 /home/j/skel/distfiles</userinput> &prompt.root; <userinput>mv etc /home/j/skel</userinput> &prompt.root; <userinput>mv usr/local /home/j/skel/usr-local</userinput> &prompt.root; <userinput>mv tmp /home/j/skel</userinput> &prompt.root; <userinput>mv var /home/j/skel</userinput> &prompt.root; <userinput>mv root /home/j/skel</userinput></screen> </step> <step> <para>Nutzen Sie <application>mergemaster</application>, um fehlende Konfigurationsdateien zu installieren. Anschließend werden die von <application>mergemaster</application> erstellten Extra-Verzeichnisse entfernt:</para> <screen>&prompt.root; <userinput>mergemaster -t /home/j/skel/var/tmp/temproot -D /home/j/skel -i</userinput> &prompt.root; <userinput>cd /home/j/skel</userinput> &prompt.root; <userinput>rm -R bin boot lib libexec mnt proc rescue sbin sys usr dev</userinput></screen> </step> <step> <para>Nun wird das read/write-Dateisystem mit dem read-only-Dateisystem verlinkt. Bitte vergewissern Sie sich, dass die symbolischen Links an den korrekten <filename class="directory">s/</filename> Positionen erstellt werden. Echte Verzeichnisse oder an falschen Positionen erstellte Verzeichnisse lassen die Installation fehlschlagen.</para> <screen>&prompt.root; <userinput>cd /home/j/mroot</userinput> &prompt.root; <userinput>mkdir s</userinput> &prompt.root; <userinput>ln -s s/etc etc</userinput> &prompt.root; <userinput>ln -s s/home home</userinput> &prompt.root; <userinput>ln -s s/root root</userinput> &prompt.root; <userinput>ln -s ../s/usr-local usr/local</userinput> &prompt.root; <userinput>ln -s ../s/usr-X11R6 usr/X11R6</userinput> &prompt.root; <userinput>ln -s ../../s/distfiles usr/ports/distfiles</userinput> &prompt.root; <userinput>ln -s s/tmp tmp</userinput> &prompt.root; <userinput>ln -s s/var var</userinput></screen> </step> <step> <para>Zuletzt erstellen Sie eine allgemeine <filename>/home/j/skel/etc/make.conf</filename> mit folgendem Inhalt:</para> <programlisting>WRKDIRPREFIX?= /s/portbuild</programlisting> <para>Ein gesetztes <literal>WRKDIRPREFIX</literal> erlaubt es, die &os;-Ports innerhalb jeder Jail zu kompilieren. Das Ports-Verzeichnis ist Teil des read-only System. Der angepasste Pfad des <literal>WRKDIRPREFIX</literal> macht es möglich, innerhalb des read/write-Bereichs der Jail Ports zu bauen.</para> </step> </procedure> </sect3> <sect3 id="jails-service-jails-creating"> <title>Jails erstellen</title> <para>Da nun eine komplette &os;-Jailvorlage vorliegt, sind wir nun in der Lage, Jails einrichten und in <filename>/etc/rc.conf</filename> zu konfigurieren. Dieses Beispiel zeigt das Erstellen von drei Jails: <quote>NS</quote>, <quote>MAIL</quote> und <quote>WWW</quote>.</para> <procedure> <step> <para>Fügen Sie die folgenden Zeilen in <filename>/etc/fstab</filename> ein, damit die read-only-Vorlage und der read/write-Bereich für alle Jails verfügbar sind:</para> <programlisting>/home/j/mroot /home/j/ns nullfs ro 0 0 /home/j/mroot /home/j/mail nullfs ro 0 0 /home/j/mroot /home/j/www nullfs ro 0 0 /home/js/ns /home/j/ns/s nullfs rw 0 0 /home/js/mail /home/j/mail/s nullfs rw 0 0 /home/js/www /home/j/www/s nullfs rw 0 0</programlisting> <note> <para>Mit der Pass-Nummer 0 markierte Partitionen werden beim Booten des Systems nicht von &man.fsck.8; geprüft, mit 0 als Dump-Nummer markierte Partitonen werden von &man.dump.8; nicht gesichert. Wir wollen nicht, dass <application>fsck</application> unsere <application>nullfs</application>-Mounts prüft oder dass <application>dump</application> die nur lesbaren nullfs-Mounts unserer Jails sichert. Deshalb werden diese Bereiche in den letzten beiden Spalten der obenstehenden <filename>fstab</filename> mit <quote>0 0</quote> markiert.</para> </note> </step> <step> <para>Konfigurieren Sie die Jails in <filename>/etc/rc.conf</filename>:</para> <programlisting>jail_enable="YES" jail_set_hostname_allow="NO" jail_list="ns mail www" jail_ns_hostname="ns.example.org" jail_ns_ip="192.168.3.17" jail_ns_rootdir="/usr/home/j/ns" jail_ns_devfs_enable="YES" jail_mail_hostname="mail.example.org" jail_mail_ip="192.168.3.18" jail_mail_rootdir="/usr/home/j/mail" jail_mail_devfs_enable="YES" jail_www_hostname="www.example.org" jail_www_ip="62.123.43.14" jail_www_rootdir="/usr/home/j/www" jail_www_devfs_enable="YES"</programlisting> <warning> <para>Der Grund dafür, dass die Variablen <varname>jail_<replaceable>name</replaceable>_rootdir</varname> nach <filename class="directory">/usr/home</filename> statt nach <filename class="directory">/home</filename> zeigen, liegt darin, dass der physikalische Pfad des <filename class="directory">/home</filename>-Verzeichnisses unter &os; <filename class="directory">/usr/home</filename> lautet. Die Variable <varname>jail_<replaceable>name</replaceable>_rootdir</varname> darf im Pfad aber <emphasis>keinen symbolischen Link</emphasis> enthalten, weil das Jail ansonsten nicht gestartet werden kann. Verwenden Sie &man.realpath.1;, um den korrekten Wert für diese Variable zu bestimmen. Weitere Informationen finden Sie im Security Advisory &os;-SA-07:01.jail.</para> </warning> </step> <step> <para>Erstellen Sie die notwendigen Mountpunkte für die nur lesbaren Bereiche jeder Jail:</para> <screen>&prompt.root; <userinput>mkdir /home/j/ns /home/j/mail /home/j/www</userinput></screen> </step> <step> <para>Installieren Sie die read/write-Vorlage in jede Jail. Benutzen Sie hierfür <filename role="package">sysutils/cpdup</filename>, welches es erleichtert, eine korrekte Kopie jedes Verzeichnisses zu erstellen:</para> <!-- keramida: Why is cpdup required here? Doesn't cpio(1) already include adequate functionality for performing this job *and* have the advantage of being part of the base system of FreeBSD? --> <screen>&prompt.root; <userinput>mkdir /home/js</userinput> &prompt.root; <userinput>cpdup /home/j/skel /home/js/ns</userinput> &prompt.root; <userinput>cpdup /home/j/skel /home/js/mail</userinput> &prompt.root; <userinput>cpdup /home/j/skel /home/js/www</userinput></screen> </step> <step> <para>An dieser Stelle werden die Jails erstellt und fü den Betrieb vorbereitet. Zuerst mounten Sie die notwendigen Dateisysteme für jede Jail und starten diese dann mit dem Skript <filename>/etc/rc.d/jail</filename>:</para> <screen>&prompt.root; <userinput>mount -a</userinput> &prompt.root; <userinput>/etc/rc.d/jail start</userinput></screen> </step> </procedure> <para>Die Jails sollten nun laufen. Um zu prüfen, ob sie korrekt gestartet wurden, verwenden Sie &man.jls.8;. Nach dem Aufruf dieses Befehls sollten Sie eine Ausgabe ähnlich der folgenden erhalten:</para> <screen>&prompt.root; <userinput>jls</userinput> JID IP Address Hostname Path 3 192.168.3.17 ns.example.org /home/j/ns 2 192.168.3.18 mail.example.org /home/j/mail 1 62.123.43.14 www.example.org /home/j/www</screen> <para>An diesem Punkt sollte es möglich sein, sich an jeder Jail anzumelden, Benutzer anzulegen und Dienste zu konfigurieren. Die Spalte <literal>JID</literal> gibt die Jail-Identifikationsnummer jeder laufenden Jail an. Nutzen Sie den folgenden Befehl, um administrative Aufgaben in der Jail mit der <literal>JID</literal> 3 durchzuführen:</para> <screen>&prompt.root; <userinput>jexec 3 tcsh</userinput></screen> </sect3> <sect3 id="jails-service-jails-upgrading"> <title>Jails aktualisieren</title> <para>Mit der Zeit wird es notwendig sein, das System auf eine neuere Version von &os; zu aktualisieren. Zum einen aus Sicherheitsgründen, zum anderen, um neu eingeführte Funktionen nutzen zu können, die für die bestehenden Jails sinnvoll sind. Das Design dieses Aufbaus bietet einen einfachen Weg, bestehende Jails zu aktualisieren. Zudem reduziert es die Downtime, da die Jails erst im allerletzten Schritt gestoppt werden müssen. Außerdem bietet es die Möglichkeit, zu älteren Versionen zurückzukehren, falls irgendwelche Probleme auftreten.</para> <procedure> <step> <para>Im ersten Schritt wird das Host-System aktualisiert. Anschließend wird eine temporäre neue read-only Vorlage <filename class="directory">/home/j/mroot2</filename> erstellt.</para> <screen>&prompt.root; <userinput>mkdir /home/j/mroot2</userinput> &prompt.root; <userinput>cd /usr/src</userinput> &prompt.root; <userinput>make installworld DESTDIR=/home/j/mroot2</userinput> &prompt.root; <userinput>cd /home/j/mroot2</userinput> &prompt.root; <userinput>cpdup /usr/src usr/src</userinput> &prompt.root; <userinput>mkdir s</userinput></screen> <para>Der <maketarget>installworld</maketarget>-Durchlauf erzeugt einige unnötige Verzeichnisse, die nun entfernt werden sollten:</para> <screen>&prompt.root; <userinput>chflags -R 0 var</userinput> &prompt.root; <userinput>rm -R etc var root usr/local tmp</userinput></screen> </step> <step> <para>Erzeugen Sie neue symbolische Links für das Hauptdateisystem:</para> <screen>&prompt.root; <userinput>ln -s s/etc etc</userinput> &prompt.root; <userinput>ln -s s/root root</userinput> &prompt.root; <userinput>ln -s s/home home</userinput> &prompt.root; <userinput>ln -s ../s/usr-local usr/local</userinput> &prompt.root; <userinput>ln -s ../s/usr-X11R6 usr/X11R6</userinput> &prompt.root; <userinput>ln -s s/tmp tmp</userinput> &prompt.root; <userinput>ln -s s/var var</userinput></screen> </step> <step> <para>Nun ist es an der Zeit, die Jails zu stoppen:</para> <screen>&prompt.root; <userinput>/etc/rc.d/jail stop</userinput></screen> </step> <step> <para>Unmounten des originalen Dateisystems:</para> <!-- keramida: Shouldn't we suggest a short script-based loop here, instead of tediously copying the same commands multiple times? --> <screen>&prompt.root; <userinput>umount /home/j/ns/s</userinput> &prompt.root; <userinput>umount /home/j/ns</userinput> &prompt.root; <userinput>umount /home/j/mail/s</userinput> &prompt.root; <userinput>umount /home/j/mail</userinput> &prompt.root; <userinput>umount /home/j/www/s</userinput> &prompt.root; <userinput>umount /home/j/www</userinput></screen> <note> <para>Die read/write-Systeme sind an das read-only System angehängt (<filename class="directory">/s</filename>), das daher zuerst ausgehängt werden muss.</para> </note> </step> <step> <para>Verschieben Sie das alte read-only-Dateisystem und ersetzen Sie es durch das neue Dateisystem. Das alte Dateisystem kann so als Backup dienen, falls etwas schief geht. Die Namensgebung entspricht hier derjenigen bei der Erstellung eines neuen read-only-Dateisystems. Verschieben Sie die originale &os; Ports-Sammlung in das neue Dateisystem, um Platz und Inodes zu sparen:</para> <screen>&prompt.root; <userinput>cd /home/j</userinput> &prompt.root; <userinput>mv mroot mroot.20060601</userinput> &prompt.root; <userinput>mv mroot2 mroot</userinput> &prompt.root; <userinput>mv mroot.20060601/usr/ports mroot/usr</userinput></screen> </step> <step> <para>Nun ist die neue read-only-Vorlage fertig. Sie müssen daher nur noch die Dateisysteme erneut mounten und die Jails starten:</para> <screen>&prompt.root; <userinput>mount -a</userinput> &prompt.root; <userinput>/etc/rc.d/jail start</userinput></screen> </step> </procedure> <para>Nutzen Sie &man.jls.8; um zu prüfen, ob die Jails korrekt gestartet wurden. Vergessen Sie nicht, innerhalb jeder Jail <command>mergemaster</command> laufen zu lassen. Die Konfigurationsdateien müssen (ebenso wie die rc.d-Skripten) aktualisiert werden.</para> </sect3> </sect2> </sect1> </chapter>