Der Abhärtungsprozess Schritt für Schritt

Eine Anleitung, die Schritt für Schritt darstellt, wie ein Debian 2.2 GNU/Linux-System nach der Installation abgehärtet wird, ist unten aufgeführt. Das ist nur eine denkbare Herangehensweise von einem solchen Vorgang. Sie ist am Absichern von Netzwerkdiensten orientiert und stellt den gesamten Anlauf der Konfiguration vor. Vergleichen Sie auch . Installieren Sie das System. Beachten Sie dabei die Informationen dieses HOWTOs bezüglich der Partitionierung. Nach der Basis-Installation nehmen Sie eine angepasste Installation vor. Wählen Sie keine Task-Pakete aus. Aktivieren Sie shadow passwords. Entfernen Sie mit dselect alle nicht benötigten aber ausgewählten Pakete, bevor Sie [I]nstallation wählen. Behalten Sie nur die absolut notwendige Software auf dem System. Aktualisieren Sie die ganze Software mit den aktuellen Paketen von security.debian.org, wie bereits unter beschrieben. Implementieren Sie die in dieser Anleitung vorgeschlagenen Maßnahmen zu User-Quotas, Ausgestaltung des Logins und Lilo. Machen Sie sich eine Liste von allen Diensten, die derzeit auf Ihrem System laufen. Versuchen Sie dazu Folgendes:

$ ps aux $ netstat -pn -l -A inet # /usr/sbin/lsof -i | grep LISTEN
Damit das dritte Kommando funktioniert, werden Sie `lsof-2.2` installieren müssen (und es als Root laufen lassen). Beachten Sie, dass lsof das Wort LISTEN passend zu Ihrer Lokalisation übersetzen kann. Um einen unnötigen Dienst zu entfernen, stellen Sie zunächst fest, wie er gestartet wird, und welches Paket ihn zur Verfügung stellt. Sie können dies ganz einfach machen, indem Sie das Programm prüfen, das auf dem Socket lauscht. Das nachfolgende Shell-Skript, das die Programme lsof und dpkg verwendet, macht genau das:
#!/bin/sh # FIXME: this is quick and dirty; replace with a more robust script snippet for i in `sudo lsof -i | grep LISTEN | cut -d " " -f 1 |sort -u` ; do pack=`dpkg -S $i |grep bin |cut -f 1 -d : | uniq` echo "Service $i is installed by $pack"; init=`dpkg -L $pack |grep init.d/ ` if [ ! -z "$init" ]; then echo "and is run by $init" fi done
Wenn Sie einen unerwünschten Dienst finden, entfernen Sie das Paket (mit dpkg --purge). Oder benutzen Sie update-rc.d (siehe ), um ihn aus dem Start-Prozess zu entfernen. Überprüfen Sie bei inetd-Diensten (werden durch den Superdaemon gestartet), welche Dienste in /etc/inetd.conf aktiviert sind. Verwenden Sie dazu Folgendes:
$ grep -v "^#" /etc/inetd.conf | sort -u
Deaktivieren Sie dann diejenigen Dienste, die Sie nicht benötigen, indem Sie die Zeile in /etc/inetd.conf auskommentieren, das Paket entfernen, oder indem Sie update-inetd benutzen. Wenn Sie Dienste eingehüllt haben (und /usr/sbin/tcpd benutzen) prüfen Sie, ob die Dateien /etc/hosts.allow und /etc/hosts.deny passend zu Ihren Richtlinien für die Dienste konfiguriert sind. Wenn der Server mehr als eine externe Schnittstelle benutzt, sollten Sie vielleicht Dienste darauf beschränken, auf bestimmten Schnittstellen zu lauschen. Ob das möglich ist, hängt aber von den Diensten ab. Wenn Sie zum Beispiel internen FTP-Zugriff erlauben wollen, lassen Sie den FTP-Daemon nur auf der internen Schnittstelle lauschen, nicht auf allen (d.h. 0.0.0.0:21). Booten Sie die Maschine neu, oder wechseln Sie in den Single-User-Modus und zurück in den Multi-User-Modus mit:
# init 1 (....) # init 2
Prüfen Sie die nun angebotenen Dienste und wiederholen Sie gegebenenfalls die letzten Schritte. Installieren Sie jetzt die benötigten Dienste, falls es noch nicht geschehen ist, und konfigurieren Sie sie passend. Prüfen Sie mit folgendem Shell-Befehl, unter welchem Nutzer die verfügbaren Dienste laufen:
# for i in `/usr/sbin/lsof -i |grep LISTEN |cut -d " " -f 1 |sort -u`; \ > do user=`ps ef |grep $i |grep -v grep |cut -f 1 -d " "` ; \ > echo "Service $i is running as user $user"; done
Überlegen Sie, ob Sie diese Dienste einem bestimmten Benutzer oder Gruppe zuweisen wollen und sie vielleicht auch in einer chroot-Umgebung einsperren wollen, um die Sicherheit zu erhöhen. Sie können dies tun, indem Sie die /etc/init.d-Skripte ändern, die den Dienst starten. Die meisten Dienste benutzen unter Debian start-stop-daemon, der die dafür Optionen (`--change-uid` und `--chroot`) zur Verfügung stellen. Ein paar warnende Worte zum Einsperren in eine chroot-Umgebung: Sie müssen alle Dateien, die durch das Paket des Dienstes installiert wurden (verwenden Sie dpkg -L), und alle Pakete, von denen es abhängt, in die Chroot-Umgebung legen. Informationen, wie das Programm ssh in eine chroot-Umgebung eingesperrt wird, finden Sie unter . Wiederholen Sie die Schritte oben um zu prüfen, ob nur die gewünschten Dienste laufen, und ob sie unter der gewünschten Nutzer/Gruppen-Kombination laufen. Testen Sie die installierten Dienste, um festzustellen, ob sie wie erwartet arbeiten. Überprüfen Sie das System, indem Sie einen Scanner zur Abschätzung der Verwundbarkeit (zum Beispiel `nessus`) benutzen, um Angriffsmöglichkeiten (Fehlkonfigurationen, alte oder nicht benötigte Dienste) zu finden. Installieren Sie Instrumente zur Entdeckung von Eindringlingen in Netzwerk und Hosts (wie `snort` und `logcheck`). Wiederholen Sie den Netzwerk-Scan und prüfen Sie, ob das System zur Erkennung von Eindringlingen funktioniert. Die richtig Paranoiden überlegen sich auch das Folgende: Fügen Sie dem System Firewall-Fähigkeiten hinzu, die eingehende Verbindungen nur zu angebotenen Diensten erlauben und ungenehmigte ausgehende Verbindungen verhindern. Überprüfen Sie erneut die Installation auf Angriffspunkte mit einem Netzwerk-Scanner. Prüfen Sie ausgehende Verbindungen vom System zu Hosts außerhalb mit einem Netzwerk-Scanner, um sicherzustellen, dass ungewollte Verbindungen keinen Weg nach draußen finden.

FIXME: this procedure considers service hardening but not system hardening at the user level, include information regarding checking user permissions, SETUID files and freezing changes in the system using the ext2 file system.

Checkliste der Konfiguration

Dieser Anhang wiederholt kurz Punkte aus anderen Abschnitten dieser Anleitung in einem verdichteten Checklisten-Format. Er ist als schnelle Zusammenfassung für Leute gedacht, die bereits diese Anleitung gelesen haben. Es gibt auch andere gute Checklisten, zum Beispiel Kurt Seifrieds und .

FIXME: This is based on v1.4 of the manual and might need to be updated. Schränken Sie physischen Zugriff und Boot-Fähigkeiten ein. Setzen Sie im BIOS ein Passwort. Schalten Sie im BIOS das Booten von Diskette, CD-ROM, ... ab. Setzen Sie ein LILO- bzw. GRUB-Passwort (/etc/lilo.conf bzw. /boot/grub/menu.lst); stellen Sie sicher, dass die LILO- oder GRUB-Konfigurationen nicht einsehbar sind. Partitionierung: Legen Sie Daten, die von Nutzern geschrieben wurden, Daten, die nicht zum System gehören, und sich ständig ändernde Laufzeitdaten auf eigenen, getrennten Partitionen ab. Setzen Sie die Mount-Optionen `nosuid,noexec,nodev` in /etc/fstab bei ext2/3-Partitionen, die keine ausführbaren Programme enthalten sollten, wie zum Beispiel /home oder /tmp. Passwort-Hygiene und Login-Sicherheit: Wählen Sie ein gutes Root-Passwort. Benutzen Sie Shadow- und MD5-Passwörter. Installieren und benutzen Sie PAM: Fügen Sie die Unterstützung von PAM-MD5 hinzu, und stellen Sie sicher (allgemein gesprochen), dass die Einträge in den /etc/pam.d/-Dateien, die Zugriff auf die Maschine gewähren, das zweite Feld in der pam.d-Datei auf `requisite` oder `required` gesetzt haben. Ändern Sie /etc/pam.d/login, so dass nur lokale Root-Logins erlaubt werden. Markieren Sie außerdem autorisierte ttys in /etc/security/access.conf und richten Sie diese Datei überhaupt so ein, dass Root-Logins so weit wie möglich eingeschränkt werden. Fügen Sie pam_limits.so hinzu, wenn Sie Einschränkungen pro Benutzer vornehmen wollen. Ändern Sie /etc/pam.d/passwd: Erhöhen Sie die minimale Länge von Passwörtern (vielleicht sechs Zeichen) und schalten Sie MD5 ein. Wenn Sie es wünschen, fügen Sie /etc/group die Gruppe wheel hinzu; fügen Sie /etc/pam.d/su pam_wheel.so group=wheel hinzu. Für angepasste Kontrollen der einzelnen Nutzer nehmen Sie pam_listfile.so-Einträge an den passenden Stellen vor. Erstellen Sie eine Datei /etc/pam.d/other und setzen Sie sie mit strenger Sicherheit auf. Setzen Sie in /etc/security/limits.conf Schranken (beachten Sie, dass /etc/limits nicht benutzt wird, wenn Sie PAM verwenden). Nehmen Sie Einschränkungen in /etc/login.defs vor; wenn Sie MD5 oder PAM einschalten, machen Sie auch hier ebenfalls die gleichbedeutenden Änderungen. Nehmen Sie Einschränkungen in /etc/pam.d/login vor. Schalten Sie den FTP-Zugriff von Root in /etc/ftpusers ab. Schalten Sie Root-Logins über das Netzwerk ab; benutzen Sie oder (denken Sie über die Installation von `sudo` nach). Benutzen Sie PAM, um zusätzliche Auflagen auf Logins zu ermöglichen. Andere lokale Sicherheitsangelegenheiten: Kernel-Tweaks (siehe ). Kernel-Patches (siehe ). Schränken Sie die Zugriffsrechte auf Log-Dateien (/var/log/{last,fail}log, Apache-Logs) ein. Stellen Sie sicher, dass in /etc/checksecurity.conf SETUID-Checks eingeschaltet sind. Überlegen Sie sich, an Log-Dateien nur anhängen zu lassen (append-only) und Konfigurationsdateien unveränderbar (immutable) zu machen, indem Sie chattr benutzen (nur ext2/3-Dateisystem). Setzen Sie eine Integritätsprüfung des Dateisystems auf (siehe ). Installieren Sie `debsums`. Überlegen Sie, locate durch slocate zu ersetzen. Alles auf einem lokalen Drucker mitloggen? Brennen Sie Ihre Konfiguration auf eine bootbare CD und booten Sie hiervon? Abschalten von Kernel-Modulen? Einschränkung des Netzwerkzugriffs: Installieren und konfigurieren Sie ssh (Vorschlag: PermitRootLogin No in /etc/ssh/sshd_config, PermitEmptyPasswords No; beachten Sie auch die anderen Vorschläge im Text). Schalten Sie in.telnetd ab oder entfernen Sie ihn, falls er installiert ist. Deaktivieren Sie ganz allgemein alle überflüssigen Dienste in /etc/inetd.conf. Benutzen Sie dazu update-inetd --disable (oder Sie schalten inetd ganz ab oder benutzen einen Ersatz wie xinetd oder rlinetd). Schalten Sie andere überflüssige Netzwerkdienste ab. ftp, DNS, www, usw. sollten nicht laufen, wenn Sie sie nicht brauchen und nicht regelmäßig überwachen. In den meisten Fällen muss ein Mail-Server betrieben werden, sollte aber so konfiguriert sein, dass er nur lokal Mails zustellt. Installieren Sie von den Diensten, die Sie brauchen, nicht einfach das weit verbreitetste Programm, sondern schauen Sie nach sichereren Versionen, die Debian liefert (oder aus anderen Quellen). Was auch immer Sie schließlich benutzen: Stellen Sie sicher, dass Sie die Risiken verstanden haben. Setzen Sie Chroot-Gefängnisse für auswärtige Nutzer und Daemonen auf. Konfigurieren Sie die Firewall und die tcp-Wrapper (d.h. ); beachten Sie den Trick für /etc/hosts.deny im Text. Wenn Sie FTP laufen lassen, setzen Sie den ftpd-Server so auf, dass er immer in einer chroot-Umgebung im Home-Verzeichnis des Benutzers läuft. Wenn Sie X laufen lassen, schalten Sie xhost-Authentifizierung ab und benutzen Sie stattdessen ssh. Oder noch besser: Deaktivieren Sie die Weiterleitung von X komplett, falls das möglich ist (fügen Sie -nolisten tcp zu der X-Kommando-Zeile hinzu und schalten Sie XDMCP in /etc/X11/xdm/xdm-config ab, indem Sie den requestPort auf 0 setzen). Schalten Sie Zugriff von außerhalb auf den Drucker ab. Tunneln Sie alle IMAP- oder POP-Sitzungen durch SSL oder ssh. Installieren Sie stunnel, wenn Sie diesen Dienst anderen Mail-Nutzern anbieten wollen. Setzen Sie einen Log-Host auf, und konfigurieren Sie andere Maschinen, ihre Logs an diesen Host zu senden (/etc/syslog.conf) Sichern Sie BIND, Sendmail und andere komplexe Daemonen ab (starten Sie sie in einer chroot-Umgebung und als nicht-Root Pseudonutzer). Installieren Sie tiger oder ein ähnliches Werkzeug zur Erkennung von Eindringlingen in Ihr Netzwerk. Installieren Sie snort oder ein ähnliches Werkzeug zur Erkennung von Eindringlingen in Ihr Netzwerk. Verzichten Sie, falls möglich, auf NIS und RPC (Abschalten von portmap). Angelegenheiten mit Richtlinien: Klären Sie die Nutzer über das Wie und Warum Ihrer Richtlinien auf. Wenn Sie etwas verboten haben, das auf anderen Systemen normalerweise verfügbar ist, stellen Sie Dokumentation bereit, die erklärt, wie man die gleichen Resultate erreicht, indem man andere, sichere Mittel anwendet. Verbieten Sie die Nutzung von Protokollen, die Klartext-Passwörter benutzen (telnet, rsh und Freunde, ftp, imap, pop, http, ...). Verbieten Sie Programme, die SVGAlib benutzen. Benutzen Sie Disk-Quotas. Bleiben Sie über Sicherheitsangelegenheiten informiert: Abonnieren Sie sicherheitsrelevante Mailinglisten. Richten Sie Sicherheitsaktualisierungen für `apt` ein – fügen Sie /etc/apt/sources.list einen Eintrag (oder Einträge) für http://security.debian.org/ hinzu. Vergessen Sie auch nicht, regelmäßig apt-get update ; apt-get upgrade (vielleicht als Cron-Job?) laufen zu lassen, wie unter beschrieben.

Aufsetzen eines autonomen IDS

Sie können sehr leicht eine Debian-Box als eigenständiges Eindringlings-Erkennungs-System (Intrusion Detection System, IDS) aufsetzen, indem Sie `snort` benutzen und eine webbasierte Schnittstelle zur Überwachung der Alarme über Eindringlinge einrichten: Installieren Sie ein Debian-Basis-System ohne zusätzliche Pakete. Installieren Sie eine Version von Snort, die Datenbanken unterstützt, und richten Sie Snort so ein, dass die Alarme in der Datenbank protokolliert werden. Laden Sie BASE (Basic Analysis and Security Engine) oder ACID (Analysis Console for Intrusion Databases, Konsole zur Analyse für Eindringling-Datenbanken) herunter und installieren Sie es. Konfigurieren Sie es so, dass es die gleiche Datenbank wie Snort verwendet. Installieren Sie die notwendigen Pakete.

Normalerweise werden alle benötigten Pakete installiert, um Abhängigkeiten aufzulösen.

BASE wird derzeit für Debian im Paket `acidbase` geliefert, ACID im Paket `acidlab`.

Es kann auch von , oder heruntergeladen werden.
Beide stellen eine graphische WWW-Schnittstelle zur Ausgabe von Snort zur Verfügung.

Neben der Grundinstallationen benötigen Sie auch einen Webserver (wie `apache`), einen PHP-Interpreter und eine relationale Datenbank (wie `postgresql` oder `mysql`), wo Snort seine Alarme ablegen kann.

Dieses System sollte mit wenigstens zwei Netzwerk-Schnittstellen ausgestattet sein: Eine verbunden mit einem Verwaltungs-LAN (um die Resultate abzufragen und das System zu verwalten), und eine ohne IP-Adresse, das an mit dem zu beobachtenden Abschnitt des Netzwerks verbunden ist. Sie sollten den Webserver so einrichten, dass er nur auf der Schnittstelle lauscht, die mit dem Verwaltungs-LAN verbunden ist.

Sie sollten beide Schnittstellen in der Standardkonfigurationsdatei von Debian /etc/network/interfaces einrichten. Eine Adresse, nämlich die des Verwaltungs-LANs, sollten Sie wie gewöhnlich einrichten. Die andere Schnittstelle muss so konfiguriert werden, dass sie aktiviert wird, wenn das System startet, ihr darf aber keine Interface-Adresse zugewiesen sein. Eine Konfiguration der Schnittstelle könnte folgendermaßen aussehen:

auto eth0 iface eth0 inet manual up ifconfig $IFACE 0.0.0.0 up up ip link set $IFACE promisc on down ip link set $IFACE promisc off down ifconfig $IFACE down

Diese Konfiguration führt dazu, dass die Schnittstelle den gesamten Netzwerkverkehr heimlich mitliest. Damit wird verhindert, dass das NIDS in einem feindlichen Netzwerk direkt angegriffen werden kann, da die Sensoren im Netzwerk keine IP-Adresse haben. Beachten Sie aber, dass es im Lauf der Zeit Fehler im Sensorenteil des NIDS gab (z.B. im Zusammenhang mit Snort), und dass Pufferüberläufe auch entfernt durch die Verarbeitung von Netzwerkpaketen ausgelöst werden können.

Sie sollten auch einen Blick in das und in die Dokumentation auf der werfen.

Aufsetzen einer überbrückenden Firewall (bridge Firewall)

Diese Informationen trug Francois Bayart bei, um Benutzern zu helfen, eine Linux Bridge/Firewall mit 2.4.x Kernel und `iptables` aufzusetzen. Ein Kernelpatch wird nicht mehr benötigt, da der Code Standardinhalt der Linux-Kernel-Distribution wurde.

Um die notwendigen Einstellungen im Kernel vorzunehmen, rufen Sie `make menuconfig` oder `make xconfig` auf. Aktivieren Sie im Abschnitt Networking options folgende Optionen:

[*] Network packet filtering (replaces ipchains) [ ] Network packet filtering debugging (NEW) <*> 802.1d Ethernet Bridging [*] netfilter (firewalling) support (NEW)

Passen Sie auf, dass Sie dieses hier deaktiviert haben, wenn Sie Firewall-Regeln anwenden wollen. Anderenfalls wird iptables nicht funktioniert.

[ ] Network packet filtering debugging (NEW)

Anschließend müssen Sie die korrekten Optionen im Abschnitt IP: Netfilter Configuration setzen. Dann kompilieren und installieren Sie den Kernel. Wenn Sie dies auf die Debian-Art machen wollen, installieren Sie `kernel-package` und benutzen Sie make-kpkg um ein maßgeschneidertes Debian-Kernelpaket zu erstellen, das Sie mit dpkg auf Ihrem Server installieren können. Sobald der neue Kernel kompiliert und installiert ist, müssen Sie das Paket `bridge-utils` installieren.

Wenn Sie diesen Schritt abgeschlossen haben, können Sie die Konfiguration Ihrer Bridge fertigstellen. Im nächsten Abschnitt werden Ihnen zwei verschiedene mögliche Konfigurationen einer Bridge vorgestellt. Beide sind mit einer Übersicht eines hypothetischen Netzwerks und den notwendigen Befehlen versehen. Eine Bridge mit NAT- und Firewall-Fähigkeiten

Die erste Konfigurationsmöglichkeit benutzt die Bridge als Firewall mit Network Address Translation (NAT, Übersetzung der Netzwerkadressen), die einen Server und interne LAN-Clienten schützt. Unten wird eine Darstellung der Anordnung des Netzwerks gezeigt:

Internet ---- router ( 62.3.3.25 ) ---- bridge (62.3.3.26 gw 62.3.3.25 / 192.168.0.1) | | |---- WWW Server (62.3.3.27 gw 62.3.3.25) | | LAN --- Zipowz (192.168.0.2 gw 192.168.0.1)

Die folgenden Befehle zeigen, wie diese Bridge konfiguriert werden kann:

# So wird die Schnittstelle br0 erstellt: /usr/sbin/brctl addbr br0 # Hinzufügen der Ethernet-Schnittstelle, die die Bridge benutzen # soll /usr/sbin/brctl addif br0 eth0 /usr/sbin/brctl addif br0 eth1 # Starten der Ethernet-Schnittstelle /sbin/ifconfig eth0 0.0.0.0 /sbin/ifconfig eth1 0.0.0.0 # Konfigurieren der Ethernet-Bridge # Die Bridge wird korrekt und unsichtbar (transparente Firewall) sein. # In einem traceroute ist sie versteckt, und Sie behalten Ihr echtes # Gateway auf Ihren anderen Computern. Jetzt können Sie ein Gateway # auf Ihrer Bridge konfigurieren und es auf Ihren anderen Computern als # neues Gateway einsetzen /sbin/ifconfig br0 62.3.3.26 netmask 255.255.255.248 broadcast 62.3.3.31 # Ich habe diese internen IPs für mein NAT benutzt ip addr add 192.168.0.1/24 dev br0 /sbin/route add default gw 62.3.3.25
Eine Bridge mit Firewall-Fähigkeiten

Eine zweite denkbare Konfiguration ist ein System, das als transparente Firewall für ein LAN mit einer öffentlichen IP-Adresse aufgesetzt ist.

Internet ---- router (62.3.3.25) ---- bridge (62.3.3.26) | | |---- WWW Server (62.3.3.28 gw 62.3.3.25) | | |---- Mail Server (62.3.3.27 gw 62.3.3.25)

Die folgenden Kommandos zeigen, wie diese Bridge konfiguriert werden kann:

# So wird die Schnittstelle br0 erstellt: /usr/sbin/brctl addbr br0 # Hinzufügen der Ethernet-Schnittstelle, die die Bridge benutzen # soll /usr/sbin/brctl addif br0 eth0 /usr/sbin/brctl addif br0 eth1 # Starten der Schnittstelle /sbin/ifconfig eth0 0.0.0.0 /sbin/ifconfig eth1 0.0.0.0 # Konfigurieren der Ethernet-Bridge # Die Bridge wird korrekt und unsichtbar (transparente Firewall) sein. # In einem traceroute ist sie versteckt, und Sie behalten Ihr echtes # Gateway auf Ihren anderen Computern. Jetzt können Sie ein Gateway # auf Ihrer Bridge konfigurieren und es auf Ihren anderen Computern als # neues Gateway einsetzen /sbin/ifconfig br0 62.3.3.26 netmask 255.255.255.248 broadcast 62.3.3.31

Wenn Sie mit traceroute die Route des Linux-Mail-Servers verfolgen, sehen Sie die Bridge nicht. Wenn Sie mit ssh auf die Bridge zugreifen wollen, müssen Sie ein Gateway haben oder erst auf einen anderen Server wie den "Mail Server" zugreifen, um dann über die interne Netzwerkkarte auf die Bridge zuzugreifen. Grundlegende Iptables-Regeln

Dies ist ein Beispiel für grundlegende Regeln, die für beide Einstellungen benutzt werden können:

iptables -F FORWARD iptables -P FORWARD DROP iptables -A FORWARD -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -m state --state INVALID -j DROP iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # Zwei lustige Regeln, aber nicht bei klassischen Iptables. Sorry ... # Limit ICMP # iptables -A FORWARD -p icmp -m limit --limit 4/s -j ACCEPT # Übereinstimmende Strings, eine gute, einfache Methode, um Viren sehr # schnell abzublocken # iptables -I FORWARD -j DROP -p tcp -s 0.0.0.0/0 -m string --string "cmd.exe" # Abblocken aller MySQL-Verbindungen, nur um ganz sicher zu gehen iptables -A FORWARD -p tcp -s 0/0 -d 62.3.3.0/24 --dport 3306 -j DROP # Regeln für den Linux Mail Server # # Erlaube FTP-DATA (20), FTP (21), SSH (22) iptables -A FORWARD -p tcp -s 0.0.0.0/0 -d 62.3.3.27/32 --dport 20:22 -j ACCEPT # Dem Mail-Server erlauben, sich mit der Außenwelt zu verbinden # Beachten Sie: Dies ist *nicht* für die vorherigen Verbindungen # notwendig (erinnern Sie sich: stateful filtering) und könnte entfernt # werden: iptables -A FORWARD -p tcp -s 62.3.3.27/32 -d 0/0 -j ACCEPT # Regeln für den WWW-Server # # Erlaube HTTP ( 80 ) Verbindungen mit dem WWW-Server iptables -A FORWARD -p tcp -s 0.0.0.0/0 -d 62.3.3.28/32 --dport 80 -j ACCEPT # Erlaube HTTPS ( 443 ) Verbindungen mit dem WWW-Server iptables -A FORWARD -p tcp -s 0.0.0.0/0 -d 62.3.3.28/32 --dport 443 -j ACCEPT # Dem WWW-Server erlauben, sich mit der Außenwelt zu verbinden # Beachten Sie: Dies ist *nicht* für die vorherigen Verbindungen # notwendig (erinnern Sie sich: stateful filtering) und könnte entfernt # werden: iptables -A FORWARD -p tcp -s 62.3.3.28/32 -d 0/0 -j ACCEPT
Beispielskript, um die Standard-Installation von Bind zu ändern

Dieses Skript automatisiert den Vorgang, die Standardinstallation des Name-Servers bind in der Version 8 zu ändern, so dass er nicht als Root läuft. Bei bind in der Version 9 in Debian ist dies standardmäßig so.

Ab der Version 9.2.1-5, also seit der Veröffentlichung von Sarge.
Diese Version ist demnach der Version 8 von bind vorzuziehen.

Dieses Skript ist hier aus historischen Gründen aufgeführt und soll zeigen, wie man diese Art von Veränderungen systemweit automatisieren kann. Das Skript wird den Benutzer und die Gruppe für den Name-Server erstellen und /etc/default/bind und /etc/init.d/bind so ändern, dass das Programm unter diesem Benutzer läuft. Benutzen Sie es äußerst vorsichtig, da es nicht ausreichend getestet wurde.

Sie können die Benutzer auch von Hand erstellen und dann den Patch für das Standard-Init.d-Skript verwenden, der im enthalten ist.

#!/bin/sh # Change the default Debian bind v8 configuration to have it run # with a non-root user and group. # # DO NOT USE this with version 9, use debconf for configure this instead # # WARN: This script has not been tested thoroughly, please # verify the changes made to the INITD script # (c) 2002 Javier Fernández-Sanguino Peña # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 1, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # Please see the file `COPYING' for the complete copyright notice. # restore() { # Just in case, restore the system if the changes fail echo "WARN: Restoring to the previous setup since I'm unable to properly change it." echo "WARN: Please check the $INITDERR script." mv $INITD $INITDERR cp $INITDBAK $INITD } USER=named GROUP=named INITD=/etc/init.d/bind DEFAULT=/etc/default/bind INITDBAK=$INITD.preuserchange INITDERR=$INITD.changeerror AWKS="awk ' /\/usr\/sbin\/ndc reload/ { print \"stop; sleep 2; start;\"; noprint = 1; } /\\\\$/ { if ( noprint != 0 ) { noprint = noprint + 1;} } /^.*$/ { if ( noprint != 0 ) { noprint = noprint - 1; } else { print \$0; } } '" [ `id -u` -ne 0 ] && { echo "This program must be run by the root user" exit 1 } RUNUSER=`ps eo user,fname |grep named |cut -f 1 -d " "` if [ "$RUNUSER" = "$USER" ] then echo "WARN: The name server running daemon is already running as $USER" echo "ERR: This script will not do any changes to your setup." exit 1 fi if [ ! -f "$INITD" ] then echo "ERR: This system does not have $INITD (which this script tries to change)" RUNNING=`ps eo fname |grep named` [ -z "$RUNNING" ] && \ echo "ERR: In fact the name server daemon is not even running (is it installed?)" echo "ERR: No changes will be made to your system" exit 1 fi # Check if there are options already setup if [ -e "$DEFAULT" ] then if grep -q ^OPTIONS $DEFAULT; then echo "ERR: The $DEFAULT file already has options set." echo "ERR: No changes will be made to your system" fi fi # Check if named group exists if [ -z "`grep $GROUP /etc/group`" ] then echo "Creating group $GROUP:" addgroup $GROUP else echo "WARN: Group $GROUP already exists. Will not create it" fi # Same for the user if [ -z "`grep $USER /etc/passwd`" ] then echo "Creating user $USER:" adduser --system --home /home/$USER \ --no-create-home --ingroup $GROUP \ --disabled-password --disabled-login $USER else echo "WARN: The user $USER already exists. Will not create it" fi # Change the init.d script # First make a backup (check that there is not already # one there first) if [ ! -f $INITDBAK ] then cp $INITD $INITDBAK fi # Then use it to change it cat $INITDBAK | eval $AWKS > $INITD # Now put the options in the /etc/default/bind file: cat >>$DEFAULT <<EOF # Make bind run with the user we defined OPTIONS="-u $USER -g $GROUP" EOF echo "WARN: The script $INITD has been changed, trying to test the changes." echo "Restarting the named daemon (check for errors here)." $INITD restart if [ $? -ne 0 ] then echo "ERR: Failed to restart the daemon." restore exit 1 fi RUNNING=`ps eo fname |grep named` if [ -z "$RUNNING" ] then echo "ERR: Named is not running, probably due to a problem with the changes." restore exit 1 fi # Check if it's running as expected RUNUSER=`ps eo user,fname |grep named |cut -f 1 -d " "` if [ "$RUNUSER" = "$USER" ] then echo "All has gone well, named seems to be running now as $USER." else echo "ERR: The script failed to automatically change the system." echo "ERR: Named is currently running as $RUNUSER." restore exit 1 fi exit 0

Dieses Skript, wenn es auf Woodys (Debian 3.0) angepassten bind (Version 8) angewendet wird, wird die initd-Datei verändern, nachdem der Benutzer und die Gruppe "named" erstellt wurde.

Schutz der Sicherheitsaktualisierung durch eine Firewall

Nach einer Standard-Installation könnten immer noch Sicherheitslücken auf dem System vorhanden sein. Falls Sie die Aktualisierungen für die verwundbaren Paket nicht auf einem anderen System herunterladen können (oder security.debian.org zu lokalen Zwecken spiegeln können), müssen Sie sich mit dem Internet verbinden, um die Pakete herunterzuladen.

Wenn Sie sich jedoch mit dem Internet verbinden, setzen Sie Ihr System einer Gefahr aus. Wenn einer Ihrer lokalen Dienste angreifbar ist, könnten Sie kompromittiert sein, noch bevor die Aktualisierung beendet ist! Sie mögen dies paranoid finden, aber eine Analyse vom zeigt tatsächlich, dass ein System in weniger als drei Tagen kompromittiert werden kann, sogar wenn das System gar nicht der Öffentlichkeit bekannt ist (d.h. nicht in DNS-Einträgen auftaucht).

Wenn Sie eine Aktualisierung Ihres Systems durchführen, das nicht von einem externen System (z.B. einer Firewall) geschützt ist, können Sie trotzdem eine lokale Firewall so konfigurieren, dass Sie nur die Sicherheitsaktualisierung selbst erlaubt. Das Beispiel unten zeigt, wie die lokalen Firewall-Fähigkeiten aufgesetzt werden müssen, um ein eingeschränktes Setup zu erreichen, in dem nur Verbindungen zu security.debian.org erlaubt werden, während der Rest geloggt wird.

Im nachfolgenden Beispiel wird ein strenges Regelwerk für eine Firewall dargestellt. Führen Sie diese Befehle auf einer lokalen Konsole aus (und nicht auf einer entfernten), um das Risiko zu verringern, sich aus Ihrem System auszusperren.

# iptables -F # iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination # iptables -A OUTPUT -d security.debian.org --dport 80 -j ACCEPT # iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # iptables -A INPUT -p icmp -j ACCEPT # iptables -A INPUT -j LOG # iptables -A OUTPUT -j LOG # iptables -P INPUT DROP # iptables -P FORWARD DROP # iptables -P OUTPUT DROP # iptables -L Chain INPUT (policy DROP) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 LOG all -- anywhere anywhere LOG level warning Chain FORWARD (policy DROP) target prot opt source destination Chain OUTPUT (policy DROP) target prot opt source destination ACCEPT 80 -- anywhere security.debian.org LOG all -- anywhere anywhere LOG level warning

Hinweis: Es ist die vorzugswürdige Verfahrensweise, die Policy-Regel DROP für die Input-Kette zu verwenden. Seien Sie aber äußerst vorsichtig, wenn Sie dies bei einer entfernten Verbindung unternehmen. Wenn Sie das Regelwerk Ihrer Firewall aus der Ferne testen, ist es am besten, wenn Sie ein Skript mit dem Regelwerk laufen lassen (anstatt jede Regel Zeile für Zeile von der Befehlszeile aus einzugeben) und sich vorsorglich eine Hintertür

Wie z.B. knockd. Alternativ dazu können Sie auch eine separate Konsole öffnen und das System nachfragen lassen, ob sich jemand auf der Gegenseite befindet. Wenn keine Eingabe erfolgt, werden die Firewall-Regeln zurückgesetzt. Ein Beispiel dafür ist:
#!/bin/bash while true; do read -n 1 -p "Are you there? " -t 30 ayt if [ -z "$ayt" ] ; then break fi done # Reset the firewall chain, user is not available echo echo "Resetting firewall chain!" iptables -F iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT exit 1

Selbstverständlich müssen Sie alle Hintertüren abschalten, ehe Sie Ihr System in Betrieb nehmen.

offen halten, so dass Sie wieder Zugriff auf Ihr System bekommen, wenn Sie einen Fehler gemacht haben. Auf diese Weise müssen Sie sich nicht auf den Weg zum entfernten Rechner machen, um die Firewall-Regel, mit der Sie sich ausgeschlossen haben, zu korrigieren.

FIXME: This needs DNS to be working properly since it is required for security.debian.org to work. You can add security.debian.org to /etc/hosts but now it is a CNAME to several hosts (there is more than one security mirror)

FIXME: this will only work with HTTP URLs since ftp might need the ip_conntrack_ftp module, or use passive mode.

Chroot-Umgebung für SSH

Es ist eine schwere Aufgabe, eine eingeschränkte Umgebung für SSH zu erstellen. Das liegt zum einen an seinen Abhängigkeiten und zum anderen daran, dass SSH im Gegensatz zu anderen Servern den Benutzern eine entfernte Shell zur Verfügung stellt. Daher müssen Sie sich überlegen, welche Programme Benutzer in der Umgebung verwenden sollen.

Sie haben zwei Möglichkeiten, eine beschränkte entfernte Shell einzurichten: die SSH-Benutzer in ein Chroot-Gefängnis einsperren: Dazu müssen Sie den SSH-Daemon so konfigurieren, dass er Benutzer nach der Authentifizierung in ein Chroot-Gefängnis einsperrt, bevor sie eine Shell bekommen. Jeder Benutzer kann seine eigene Umgebung haben. den SSH-Server in ein Chroot-Gefängnis einsperren: Wenn die SSH-Anwendung sich selbst in einer Chroot-Umgebung befindet, sind auch alle Benutzer in diese Umgebung eingesperrt.

Die erste Möglichkeit hat den Vorteil, dass es möglich ist, sowohl unbeschränkte als auch beschränkte Benutzer zu haben. Falls Sie keine Setuid-Anwendungen in der Chroot-Umgebung zur Verfügung stellen, wird es schwieriger, aus dem Gefängnis auszubrechen. Allerdings müssen Sie gegebenenfalls Chroot-Umgebungen für jeden Benutzer einzeln einrichten. Außerdem ist die Konfiguration schwieriger, da es Zusammenarbeit mit dem SSH-Server erfordert. Die zweite Möglichkeit ist leichter zu verwirklichen und schützt vor dem Ausnutzen eines Exploits des SSH-Servers, da auch dieser im Chroot-Gefängnis ist. Jedoch müssen alle Benutzer die gleiche Chroot-Umgebung verwenden. Verschiedene Umgebungen für verschiedene Benutzer sind nicht möglich. SSH-Benutzer in ein Chroot-Gefängnis einsperren

Sie können den SSH-Server so einrichten, dass er bestimmte Benutzer in eine Chroot-Umgebung einsperrt, so dass sie eine Shell mit nur einer beschränkten Anzahl von Anwendungen zur Verfügung haben.

Einsatz von `libpam-chroot`

Der wahrscheinlich leichteste Weg ist, das Paket `libpam-chroot`, das in Debian vorhanden ist, zu verwenden. Wenn Sie es installiert haben, müssen Sie: /etc/pam.d/ssh verändern, um dieses PAM-Modul zu verwenden. Fügen Sie dazu als letzte Zeile Folgendes ein

Sie können die Option debug verwenden. Damit wird der Fortschritt des Moduls unter authpriv.notice protokolliert.
:
session required pam_chroot.so
eine passende Chroot-Umgebung für die Benutzer einrichten. Sie können versuchen, die Skripte unter /usr/share/doc/libpam-chroot/examples/ zu verwenden, das Programm `makejail` benutzen
Mit folgendem Python-Aufruf können Sie eine sehr eingeschränkte Bash-Umgebung für makejail erstellen. Erstellen Sie das Verzeichnis /var/chroots/users/foo und eine Datei mit dem Namen bash.py und folgendem Inhalt:
chroot="/var/chroots/users/foo" cleanJailFirst=1 testCommandsInsideJail=["bash ls"]
Führen Sie dann makejail bash.py aus, um eine Benutzer-Umgebung unter /var/chroots/users/foo zu erstellen. So testen Sie die Umgebung:
# chroot /var/chroots/users/foo/ ls bin dev etc lib proc sbin usr
oder eine minimale Debian-Umgebung mit `debootstrap` aufsetzen. Stellen Sie sicher, dass die Umgebung die notwendigen Geräte enthält.
Unter Umständen benötigen Sie die Geräte /dev/ptmx und /dev/pty* und das Unterverzeichnis /dev/pts/. Es sollte ausreichen, MAKEDEV im /dev-Verzeichnis der Chroot-Umgebung auszuführen, um sie zu erstellen, falls sie nicht existieren. Wenn Sie einen Kernel einsetzen, der die Gerätedateien dynamisch erstellt (Version 2.6), müssen Sie die Dateien /dev/pts/ selbst erstellen und mit den passenden Rechten ausstatten.
/etc/security/chroot.conf bearbeiten, damit die ausgewählten Nutzer in das Verzeichnis eingesperrt werden, das Sie zuvor eingerichtet haben. Sie sollten unabhängige Verzeichnisse für verschiedene Nutzer haben, damit sie weder das ganze System noch sich gegenseitig sehen können. SSH konfigurieren: Je nach der eingesetzten OpenSSH-Version funktioniert die Chroot-Umgebung sofort. Seit 3.6.1p2 wird die Funktion do_pam_session() aufgerufen, nachdem sshd seine Rechte abgelegt hat. Da chroot() Root-Rechte benötigt, wird es mit Rechtetrennung nicht funktionieren. Allerdings wurde in neueren OpenSSH-Versionen der PAM-Code verändert, so dass do_pam_session vor dem Ablegen der Rechte aufgerufen wird. Daher funktioniert es auch mit aktivierter Rechtetrennung. Falls Sie sie abschalten müssen, müssen Sie /etc/ssh/sshd_config so verändern:
UsePrivilegeSeparation no

Beachten Sie, dass das die Sicherheit Ihres Systems verringern wird, da dann der OpenSSH-Server als Root laufen wird. Das bedeutet, dass wenn eine Angriffsmöglichkeit aus der Ferne gegen OpenSSH entdeckt wird, ein Angreifer Root-Rechte anstatt nur Sshd-Rechte erlangen wird und somit das gesamte System kompromittiert.

Wenn Sie einen Kernel verwenden, der Mandatory-Access-Control (RSBAC/SElinux) unterstützt, müssen Sie die Konfiguration nicht ändern, wenn Sie dem Sshd-Benutzer die notwendigen Rechte einräumen, um den Systemaufruf chroot() ausführen zu können.

Wenn Sie die Rechtetrennung nicht deaktivieren, brauchen Sie im Chroot-Gefängnis /etc/passwd, welches die Benutzer-UID enthält, damit die Rechtetrennung funktioniert.

Wenn Sie die Option Rechtetrennung auf yes gesetzt haben und Ihre Version von OpenSSH nicht richtig läuft, müssen Sie sie abschalten. Wenn Sie das unterlassen, werden Benutzer, die sich mit Ihrem Server verbinden wollen und von diesem Modul in eine Chroot-Umgebung eingesperrt werden sollen, Folgendes zu sehen bekommen:

$ ssh -l user server user@server's password: Connection to server closed by remote host. Connection to server closed.

Dies geschieht, weil der SSH-Daemon, der als 'sshd' läuft, nicht den Systemaufruf chroot() ausführen kann. Um die Rechtetrennung abzuschalten, müssen Sie die Konfigurationsdatei /etc/ssh/sshd_config wie oben beschrieben verändern.

Beachten Sie, dass, wenn Folgendes fehlt, sich die Benutzer nicht in der Chroot-Umgebung anmelden können: Das Dateisystem /proc muss in der Chroot-Umgebung des Benutzers gemountet sein. Die notwendigen Geräte unter /dev/pts/ müssen vorliegen. Falls diese Dateien automatisch vom Kernel erstellt werden, müssen Sie sie von Hand unter /dev/ in der Chroot-Umgebung erstellen. Das Home-Verzeichnis des Benutzers muss in der Chroot-Umgebung existieren. Ansonsten wird der SSH-Daemon nicht fortfahren.

Sie können diese Probleme mit dem Schlüsselwort debug in der PAM-Konfiguration /etc/pam.d/ssh debuggen. Falls Sie auf Probleme stoßen, kann es sich als nützlich erweisen, auch den Debugging-Modus des SSH-Clients zu aktivieren.

Hinweis: Diese Informationen sind auch in /usr/share/doc/libpam-chroot/README.Debian.gz enthalten (und vielleicht aktueller). Bitte überprüfen Sie, ob dort aktualisierte Informationen vorhanden sind, bevor Sie die oben aufgezeigten Schritte ausführen.

Patchen des ssh-Servers

Debians sshd gestattet nicht, die Bewegungen eines Benutzer durch den Server zu beschränken, da er keine Chroot-Funktionalität besitzt. Diese ist im Gegensatz dazu Bestandteil des kommerziellen Programms sshd2 (es verwendet 'ChrootGroups' oder 'ChrootUsers', siehe ). Allerdings gibt es einen Patch, der sshd um diese Funktion erweitert. Den Patch erhalten Sie unter (wurde in nachgefragt). Der Patch könnte Bestandteil von zukünftigen Veröffentlichungen des OpenSSH-Pakets werden. Emmanuel Lacour bietet ssh-Pakete als Debs mit diesen Fähigkeiten für Sarge an. Sie sind unter verfügbar. Beachten Sie aber, dass sie nicht aktuell sein müssen, daher wird empfohlen, den Weg der Kompilierung zu gehen.

Nachdem Sie den Patch angewendet haben, müssen Sie /etc/passwd anpassen und darin das Home-Verzeichnis der Benutzer ändern (mit dem speziellen `/./` Kürzel).

joeuser:x:1099:1099:Joe Random User:/home/joe/./:/bin/bash

Dies wird sowohl den Fernzugriff auf die Shell als auch Fernkopien über den ssh-Kanal einschränken.

Gehen Sie sicher, dass Sie alle benötigten Programme und Bibliotheken in den Chroot-Pfaden der Benutzer haben. Diese Dateien sollten Root als Eigentümer haben, um Manipulationen durch den Benutzer zu verhindern (zum Beispiel um das chroot-Gefängnis zu verlassen). Ein Beispiel könnte so aussehen:

./bin: total 660 drwxr-xr-x 2 root root 4096 Mar 18 13:36 . drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 .. -r-xr-xr-x 1 root root 531160 Feb 6 22:36 bash -r-xr-xr-x 1 root root 43916 Nov 29 13:19 ls -r-xr-xr-x 1 root root 16684 Nov 29 13:19 mkdir -rwxr-xr-x 1 root root 23960 Mar 18 13:36 more -r-xr-xr-x 1 root root 9916 Jul 26 2001 pwd -r-xr-xr-x 1 root root 24780 Nov 29 13:19 rm lrwxrwxrwx 1 root root 4 Mar 30 16:29 sh -> bash
./etc: total 24 drwxr-xr-x 2 root root 4096 Mar 15 16:13 . drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 .. -rw-r--r-- 1 root root 54 Mar 15 13:23 group -rw-r--r-- 1 root root 428 Mar 15 15:56 hosts -rw-r--r-- 1 root root 44 Mar 15 15:53 passwd -rw-r--r-- 1 root root 52 Mar 15 13:23 shells
./lib: total 1848 drwxr-xr-x 2 root root 4096 Mar 18 13:37 . drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 .. -rwxr-xr-x 1 root root 92511 Mar 15 12:49 ld-linux.so.2 -rwxr-xr-x 1 root root 1170812 Mar 15 12:49 libc.so.6 -rw-r--r-- 1 root root 20900 Mar 15 13:01 libcrypt.so.1 -rw-r--r-- 1 root root 9436 Mar 15 12:49 libdl.so.2 -rw-r--r-- 1 root root 248132 Mar 15 12:48 libncurses.so.5 -rw-r--r-- 1 root root 71332 Mar 15 13:00 libnsl.so.1 -rw-r--r-- 1 root root 34144 Mar 15 16:10 libnss_files.so.2 -rw-r--r-- 1 root root 29420 Mar 15 12:57 libpam.so.0 -rw-r--r-- 1 root root 105498 Mar 15 12:51 libpthread.so.0 -rw-r--r-- 1 root root 25596 Mar 15 12:51 librt.so.1 -rw-r--r-- 1 root root 7760 Mar 15 12:59 libutil.so.1 -rw-r--r-- 1 root root 24328 Mar 15 12:57 libwrap.so.0
./usr: total 16 drwxr-xr-x 4 root root 4096 Mar 15 13:00 . drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 .. drwxr-xr-x 2 root root 4096 Mar 15 15:55 bin drwxr-xr-x 2 root root 4096 Mar 15 15:37 lib
./usr/bin: total 340 drwxr-xr-x 2 root root 4096 Mar 15 15:55 . drwxr-xr-x 4 root root 4096 Mar 15 13:00 .. -rwxr-xr-x 1 root root 10332 Mar 15 15:55 env -rwxr-xr-x 1 root root 13052 Mar 15 13:13 id -r-xr-xr-x 1 root root 25432 Mar 15 12:40 scp -rwxr-xr-x 1 root root 43768 Mar 15 15:15 sftp -r-sr-xr-x 1 root root 218456 Mar 15 12:40 ssh -rwxr-xr-x 1 root root 9692 Mar 15 13:17 tty
./usr/lib: total 852 drwxr-xr-x 2 root root 4096 Mar 15 15:37 . drwxr-xr-x 4 root root 4096 Mar 15 13:00 .. -rw-r--r-- 1 root root 771088 Mar 15 13:01 libcrypto.so.0.9.6 -rw-r--r-- 1 root root 54548 Mar 15 13:00 libz.so.1 -rwxr-xr-x 1 root root 23096 Mar 15 15:37 sftp-server
Einsperren des SSH-Servers in einem Chroot-Gefängnis

Wenn Sie eine Chroot-Umgebung erstellen, welche die Dateien des SSH-Servers enthält, z.B. unter /var/chroot/ssh, sollten Sie den im chroot-Gefängnis eingesperrten ssh-Server mit diesem Befehl starten:

# chroot /var/chroot/ssh /sbin/sshd -f /etc/sshd_config

Das führt dazu, dass der sshd-Daemon innerhalb des Chroot-Gefängnisses gestartet wird. Dazu müssen Sie zunächst dafür sorgen, dass das Verzeichnis /var/chroot/ssh den SSH-Server und die Werkzeuge enthält, die Benutzer benötigen, die mit dem Server verbunden sind. Wenn Sie das vorhaben, sollten Sie sicherstellen, dass OpenSSH Rechtetrennung (Privilege Separation) einsetzt (was standardmäßig so ist). Dazu muss in der Konfigurationsdatei /etc/ssh/sshd_config folgende Zeile enthalten sein:

UsePrivilegeSeparation yes

Dadurch wird der entfernte Daemon so wenig Dinge wie möglich als Root ausführen. Wenn er also einen Fehler enthalten sollte, kann damit nicht aus dem Chroot-Gefängnis ausgebrochen werden. Beachten Sie, dass, anders als wenn Sie eine Chroot-Umgebung für jeden Benutzer einzeln einrichten, in diesem Fall der SSH-Daemon im selben Chroot-Gefängnis wie die Benutzer läuft. Es gibt also mindestens einen Prozess in der Chroot-Umgebung, der als Root läuft. Mit ihm ist es möglich, aus dem Chroot-Gefängnis auszubrechen.

Beachten Sie auch, dass SSH nur funktioniert, wenn die Partition, auf der die Chroot-Umgebung eingerichtet wurde, nicht mit der Option nodev gemountet wurde. Wenn Sie diese Option verwenden, bekommen Sie folgende Fehlermeldung: PRNG is not seeded, weil /dev/urandom nicht in der Chroot-Umgebung funktioniert.

Einrichten eines minimalen Systems (der wirklich leichte Weg)

Sie können mit `debootstrap` eine minimale Umgebung einrichten, die ausschließlich den SSH-Server enthält. Dafür müssen Sie nur eine Chroot-Umgebung einrichten, wie es im beschrieben wird. Diese Vorgehensweise ist idiotensicher (Sie werden alle für die Chroot-Umgebung notwendigen Bestandteile erhalten), aber dies geht auf Kosten von Plattenspeicher. Eine minimale Installation von Debian benötigt einige hundert Megabyte. Dieses minimale System könnte auch Setuid-Dateien enthalten, mit denen ein Benutzer aus dem Chroot-Gefängnis ausbrechen könnte, wenn sie eine Rechteerweiterung zulassen.

Automatisches Erstellen der Umgebung (der leichte Weg)

Mit dem Paket `makejail` können Sie leicht eine eingeschränkte Umgebung erstellen, da es automatisch den Trace des Server-Daemons verfolgt (mit strace) und dafür sorgt, dass er in der eingeschränkten Umgebung läuft.

Der Vorteil von Programmen, die automatisch die chroot-Umgebung einrichten, liegt darin, dass sie im Stande sind, Pakete in die chroot-Umgebung zu kopieren (und verfolgen sogar die Abhängigkeiten der Pakete, um sicherzustellen, dass sie vollständig sind). Dadurch wird das Bereitstellen von Anwendungen für Benutzer leichter.

Um ein Chroot-Gefängnis aus den von makejail zur Verfügung gestellten Beispielen einzurichten, müssen Sie /var/chroot/sshd erstellen und folgenden Befehl ausführen:

# makejail /usr/share/doc/makejail/examples/sshd.py

Dies wird eine Chroot-Umgebung im Verzeichnis /var/chroot/sshd erstellen. Beachten Sie, dass diese Chroot-Umgebung nicht voll funktionstüchtig ist, bis Sie:

Das Dateisystem procfs in /var/chroot/sshd/proc eingebunden haben. Makejail wird es für Sie einbinden. Aber nach einem Neustart werden Sie es erneut einbinden müssen:

# mount -t proc proc /var/chroot/sshd/proc

Es kann auch automatisch eingebunden werden. Dazu müssen Sie /etc/fstab bearbeiten und folgende Zeile eintragen:

proc-ssh /var/chroot/sshd/proc proc none 0 0
Syslog auf das Geräte /dev/log in der Chroot-Umgebung horchen lassen. Dazu müssen Sie /etc/default/syslogd ändern und -a /var/chroot/sshd/dev/log zur Definition der Variablen SYSLOGD hinzufügen.

Sehen Sie sich die Beispielsdatei an, um herauszufinden, welche Änderungen an der Umgebung vorgenommen werden müssen. Einige diese Änderungen können nicht automatisch vorgenommen werden, wie z.B. das Kopieren des Home-Verzeichnisses eines Benutzers. Außerdem sollten Sie die Gefährdung von sensiblen Informationen begrenzen, indem Sie nur die Daten bestimmter Benutzer aus den Dateien /etc/shadow und /etc/group kopieren. Beachten Sie, dass, falls Sie Rechtetrennung verwenden, der Benutzer sshd in diesen Dateien vorhanden sein muss.

Die folgende Beispielumgebung wurde (ein wenig) unter Debian 3.0 getestet. Sie basiert auf der Konfigurationsdatei, die mit dem Paket geliefert wird, und beinhaltet das Paket `fileutils`.

. |-- bin | |-- ash | |-- bash | |-- chgrp | |-- chmod | |-- chown | |-- cp | |-- csh -> /etc/alternatives/csh | |-- dd | |-- df | |-- dir | |-- fdflush | |-- ksh | |-- ln | |-- ls | |-- mkdir | |-- mknod | |-- mv | |-- rbash -> bash | |-- rm | |-- rmdir | |-- sh -> bash | |-- sync | |-- tcsh | |-- touch | |-- vdir | |-- zsh -> /etc/alternatives/zsh | `-- zsh4 |-- dev | |-- null | |-- ptmx | |-- pts | |-- ptya0 (...) | |-- tty | |-- tty0 (...) | `-- urandom |-- etc | |-- alternatives | | |-- csh -> /bin/tcsh | | `-- zsh -> /bin/zsh4 | |-- environment | |-- hosts | |-- hosts.allow | |-- hosts.deny | |-- ld.so.conf | |-- localtime -> /usr/share/zoneinfo/Europe/Madrid | |-- motd | |-- nsswitch.conf | |-- pam.conf | |-- pam.d | | |-- other | | `-- ssh | |-- passwd | |-- resolv.conf | |-- security | | |-- access.conf | | |-- chroot.conf | | |-- group.conf | | |-- limits.conf | | |-- pam_env.conf | | `-- time.conf | |-- shadow | |-- shells | `-- ssh | |-- moduli | |-- ssh_host_dsa_key | |-- ssh_host_dsa_key.pub | |-- ssh_host_rsa_key | |-- ssh_host_rsa_key.pub | `-- sshd_config |-- home | `-- userX |-- lib | |-- ld-2.2.5.so | |-- ld-linux.so.2 -> ld-2.2.5.so | |-- libc-2.2.5.so | |-- libc.so.6 -> libc-2.2.5.so | |-- libcap.so.1 -> libcap.so.1.10 | |-- libcap.so.1.10 | |-- libcrypt-2.2.5.so | |-- libcrypt.so.1 -> libcrypt-2.2.5.so | |-- libdl-2.2.5.so | |-- libdl.so.2 -> libdl-2.2.5.so | |-- libm-2.2.5.so | |-- libm.so.6 -> libm-2.2.5.so | |-- libncurses.so.5 -> libncurses.so.5.2 | |-- libncurses.so.5.2 | |-- libnsl-2.2.5.so | |-- libnsl.so.1 -> libnsl-2.2.5.so | |-- libnss_compat-2.2.5.so | |-- libnss_compat.so.2 -> libnss_compat-2.2.5.so | |-- libnss_db-2.2.so | |-- libnss_db.so.2 -> libnss_db-2.2.so | |-- libnss_dns-2.2.5.so | |-- libnss_dns.so.2 -> libnss_dns-2.2.5.so | |-- libnss_files-2.2.5.so | |-- libnss_files.so.2 -> libnss_files-2.2.5.so | |-- libnss_hesiod-2.2.5.so | |-- libnss_hesiod.so.2 -> libnss_hesiod-2.2.5.so | |-- libnss_nis-2.2.5.so | |-- libnss_nis.so.2 -> libnss_nis-2.2.5.so | |-- libnss_nisplus-2.2.5.so | |-- libnss_nisplus.so.2 -> libnss_nisplus-2.2.5.so | |-- libpam.so.0 -> libpam.so.0.72 | |-- libpam.so.0.72 | |-- libpthread-0.9.so | |-- libpthread.so.0 -> libpthread-0.9.so | |-- libresolv-2.2.5.so | |-- libresolv.so.2 -> libresolv-2.2.5.so | |-- librt-2.2.5.so | |-- librt.so.1 -> librt-2.2.5.so | |-- libutil-2.2.5.so | |-- libutil.so.1 -> libutil-2.2.5.so | |-- libwrap.so.0 -> libwrap.so.0.7.6 | |-- libwrap.so.0.7.6 | `-- security | |-- pam_access.so | |-- pam_chroot.so | |-- pam_deny.so | |-- pam_env.so | |-- pam_filter.so | |-- pam_ftp.so | |-- pam_group.so | |-- pam_issue.so | |-- pam_lastlog.so | |-- pam_limits.so | |-- pam_listfile.so | |-- pam_mail.so | |-- pam_mkhomedir.so | |-- pam_motd.so | |-- pam_nologin.so | |-- pam_permit.so | |-- pam_rhosts_auth.so | |-- pam_rootok.so | |-- pam_securetty.so | |-- pam_shells.so | |-- pam_stress.so | |-- pam_tally.so | |-- pam_time.so | |-- pam_unix.so | |-- pam_unix_acct.so -> pam_unix.so | |-- pam_unix_auth.so -> pam_unix.so | |-- pam_unix_passwd.so -> pam_unix.so | |-- pam_unix_session.so -> pam_unix.so | |-- pam_userdb.so | |-- pam_warn.so | `-- pam_wheel.so |-- sbin | `-- start-stop-daemon |-- usr | |-- bin | | |-- dircolors | | |-- du | | |-- install | | |-- link | | |-- mkfifo | | |-- shred | | |-- touch -> /bin/touch | | `-- unlink | |-- lib | | |-- libcrypto.so.0.9.6 | | |-- libdb3.so.3 -> libdb3.so.3.0.2 | | |-- libdb3.so.3.0.2 | | |-- libz.so.1 -> libz.so.1.1.4 | | `-- libz.so.1.1.4 | |-- sbin | | `-- sshd | `-- share | |-- locale | | `-- es | | |-- LC_MESSAGES | | | |-- fileutils.mo | | | |-- libc.mo | | | `-- sh-utils.mo | | `-- LC_TIME -> LC_MESSAGES | `-- zoneinfo | `-- Europe | `-- Madrid `-- var `-- run |-- sshd `-- sshd.pid 27 directories, 733 files

Bei Debian 3.1 müssen Sie sicherstellen, dass das Gefängnis auch die Dateien für PAM enthält. Falls es nicht schon makejail für Sie erledigt hat, müssen Sie folgende Dateien in die Chroot-Umgebung kopiert:

$ ls /etc/pam.d/common-* /etc/pam.d/common-account /etc/pam.d/common-password /etc/pam.d/common-auth /etc/pam.d/common-session
Die Chroot-Umgebung von Hand erstellen (der schwierige Weg)

Es ist möglich, eine Umgebung mit der Trial-and-Error-Methode zu erstellen. Dazu müssen Sie die Traces und die Logdateien des sshd-Servers überwachen, um die notwendigen Dateien herauszufinden. Die folgende Umgebung, die von José Luis Ledesma zur Verfügung gestellt wurde, ist eine beispielhafte Auflistung der Dateien in einer chroot-Umgebung für ssh unter Debian 3.0:

Beachten Sie, dass keine SETUID-Dateien vorhanden sind. Das erschwert es entfernten Benutzern, aus der chroot-Umgebung auszubrechen. Es verhindert allerdings auch, dass Nutzer ihr Passwort ändern, da passwd nicht die Dateien /etc/passwd und /etc/shadow verändern kann.
.: total 36 drwxr-xr-x 9 root root 4096 Jun 5 10:05 ./ drwxr-xr-x 11 root root 4096 Jun 3 13:43 ../ drwxr-xr-x 2 root root 4096 Jun 4 12:13 bin/ drwxr-xr-x 2 root root 4096 Jun 4 12:16 dev/ drwxr-xr-x 4 root root 4096 Jun 4 12:35 etc/ drwxr-xr-x 3 root root 4096 Jun 4 12:13 lib/ drwxr-xr-x 2 root root 4096 Jun 4 12:35 sbin/ drwxr-xr-x 2 root root 4096 Jun 4 12:32 tmp/ drwxr-xr-x 2 root root 4096 Jun 4 12:16 usr/ ./bin: total 8368 drwxr-xr-x 2 root root 4096 Jun 4 12:13 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ -rwxr-xr-x 1 root root 109855 Jun 3 13:45 a2p* -rwxr-xr-x 1 root root 387764 Jun 3 13:45 bash* -rwxr-xr-x 1 root root 36365 Jun 3 13:45 c2ph* -rwxr-xr-x 1 root root 20629 Jun 3 13:45 dprofpp* -rwxr-xr-x 1 root root 6956 Jun 3 13:46 env* -rwxr-xr-x 1 root root 158116 Jun 3 13:45 fax2ps* -rwxr-xr-x 1 root root 104008 Jun 3 13:45 faxalter* -rwxr-xr-x 1 root root 89340 Jun 3 13:45 faxcover* -rwxr-xr-x 1 root root 441584 Jun 3 13:45 faxmail* -rwxr-xr-x 1 root root 96036 Jun 3 13:45 faxrm* -rwxr-xr-x 1 root root 107000 Jun 3 13:45 faxstat* -rwxr-xr-x 1 root root 77832 Jun 4 11:46 grep* -rwxr-xr-x 1 root root 19597 Jun 3 13:45 h2ph* -rwxr-xr-x 1 root root 46979 Jun 3 13:45 h2xs* -rwxr-xr-x 1 root root 10420 Jun 3 13:46 id* -rwxr-xr-x 1 root root 4528 Jun 3 13:46 ldd* -rwxr-xr-x 1 root root 111386 Jun 4 11:46 less* -r-xr-xr-x 1 root root 26168 Jun 3 13:45 login* -rwxr-xr-x 1 root root 49164 Jun 3 13:45 ls* -rwxr-xr-x 1 root root 11600 Jun 3 13:45 mkdir* -rwxr-xr-x 1 root root 24780 Jun 3 13:45 more* -rwxr-xr-x 1 root root 154980 Jun 3 13:45 pal2rgb* -rwxr-xr-x 1 root root 27920 Jun 3 13:46 passwd* -rwxr-xr-x 1 root root 4241 Jun 3 13:45 pl2pm* -rwxr-xr-x 1 root root 2350 Jun 3 13:45 pod2html* -rwxr-xr-x 1 root root 7875 Jun 3 13:45 pod2latex* -rwxr-xr-x 1 root root 17587 Jun 3 13:45 pod2man* -rwxr-xr-x 1 root root 6877 Jun 3 13:45 pod2text* -rwxr-xr-x 1 root root 3300 Jun 3 13:45 pod2usage* -rwxr-xr-x 1 root root 3341 Jun 3 13:45 podchecker* -rwxr-xr-x 1 root root 2483 Jun 3 13:45 podselect* -r-xr-xr-x 1 root root 82412 Jun 4 11:46 ps* -rwxr-xr-x 1 root root 36365 Jun 3 13:45 pstruct* -rwxr-xr-x 1 root root 7120 Jun 3 13:45 pwd* -rwxr-xr-x 1 root root 179884 Jun 3 13:45 rgb2ycbcr* -rwxr-xr-x 1 root root 20532 Jun 3 13:45 rm* -rwxr-xr-x 1 root root 6720 Jun 4 10:15 rmdir* -rwxr-xr-x 1 root root 14705 Jun 3 13:45 s2p* -rwxr-xr-x 1 root root 28764 Jun 3 13:46 scp* -rwxr-xr-x 1 root root 385000 Jun 3 13:45 sendfax* -rwxr-xr-x 1 root root 67548 Jun 3 13:45 sendpage* -rwxr-xr-x 1 root root 88632 Jun 3 13:46 sftp* -rwxr-xr-x 1 root root 387764 Jun 3 13:45 sh* -rws--x--x 1 root root 744500 Jun 3 13:46 slogin* -rwxr-xr-x 1 root root 14523 Jun 3 13:46 splain* -rws--x--x 1 root root 744500 Jun 3 13:46 ssh* -rwxr-xr-x 1 root root 570960 Jun 3 13:46 ssh-add* -rwxr-xr-x 1 root root 502952 Jun 3 13:46 ssh-agent* -rwxr-xr-x 1 root root 575740 Jun 3 13:46 ssh-keygen* -rwxr-xr-x 1 root root 383480 Jun 3 13:46 ssh-keyscan* -rwxr-xr-x 1 root root 39 Jun 3 13:46 ssh_europa* -rwxr-xr-x 1 root root 107252 Jun 4 10:14 strace* -rwxr-xr-x 1 root root 8323 Jun 4 10:14 strace-graph* -rwxr-xr-x 1 root root 158088 Jun 3 13:46 thumbnail* -rwxr-xr-x 1 root root 6312 Jun 3 13:46 tty* -rwxr-xr-x 1 root root 55904 Jun 4 11:46 useradd* -rwxr-xr-x 1 root root 585656 Jun 4 11:47 vi* -rwxr-xr-x 1 root root 6444 Jun 4 11:45 whoami* ./dev: total 8 drwxr-xr-x 2 root root 4096 Jun 4 12:16 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ crw-r--r-- 1 root root 1, 9 Jun 3 13:43 urandom ./etc: total 208 drwxr-xr-x 4 root root 4096 Jun 4 12:35 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ -rw------- 1 root root 0 Jun 4 11:46 .pwd.lock -rw-r--r-- 1 root root 653 Jun 3 13:46 group -rw-r--r-- 1 root root 242 Jun 4 11:33 host.conf -rw-r--r-- 1 root root 857 Jun 4 12:04 hosts -rw-r--r-- 1 root root 1050 Jun 4 11:29 ld.so.cache -rw-r--r-- 1 root root 304 Jun 4 11:28 ld.so.conf -rw-r--r-- 1 root root 235 Jun 4 11:27 ld.so.conf~ -rw-r--r-- 1 root root 88039 Jun 3 13:46 moduli -rw-r--r-- 1 root root 1342 Jun 4 11:34 nsswitch.conf drwxr-xr-x 2 root root 4096 Jun 4 12:02 pam.d/ -rw-r--r-- 1 root root 28 Jun 4 12:00 pam_smb.conf -rw-r--r-- 1 root root 2520 Jun 4 11:57 passwd -rw-r--r-- 1 root root 7228 Jun 3 13:48 profile -rw-r--r-- 1 root root 1339 Jun 4 11:33 protocols -rw-r--r-- 1 root root 274 Jun 4 11:44 resolv.conf drwxr-xr-x 2 root root 4096 Jun 3 13:43 security/ -rw-r----- 1 root root 1178 Jun 4 11:51 shadow -rw------- 1 root root 80 Jun 4 11:45 shadow- -rw-r----- 1 root root 1178 Jun 4 11:48 shadow.old -rw-r--r-- 1 root root 161 Jun 3 13:46 shells -rw-r--r-- 1 root root 1144 Jun 3 13:46 ssh_config -rw------- 1 root root 668 Jun 3 13:46 ssh_host_dsa_key -rw-r--r-- 1 root root 602 Jun 3 13:46 ssh_host_dsa_key.pub -rw------- 1 root root 527 Jun 3 13:46 ssh_host_key -rw-r--r-- 1 root root 331 Jun 3 13:46 ssh_host_key.pub -rw------- 1 root root 883 Jun 3 13:46 ssh_host_rsa_key -rw-r--r-- 1 root root 222 Jun 3 13:46 ssh_host_rsa_key.pub -rw-r--r-- 1 root root 2471 Jun 4 12:15 sshd_config ./etc/pam.d: total 24 drwxr-xr-x 2 root root 4096 Jun 4 12:02 ./ drwxr-xr-x 4 root root 4096 Jun 4 12:35 ../ lrwxrwxrwx 1 root root 4 Jun 4 12:02 other -> sshd -rw-r--r-- 1 root root 318 Jun 3 13:46 passwd -rw-r--r-- 1 root root 546 Jun 4 11:36 ssh -rw-r--r-- 1 root root 479 Jun 4 12:02 sshd -rw-r--r-- 1 root root 370 Jun 3 13:46 su ./etc/security: total 32 drwxr-xr-x 2 root root 4096 Jun 3 13:43 ./ drwxr-xr-x 4 root root 4096 Jun 4 12:35 ../ -rw-r--r-- 1 root root 1971 Jun 3 13:46 access.conf -rw-r--r-- 1 root root 184 Jun 3 13:46 chroot.conf -rw-r--r-- 1 root root 2145 Jun 3 13:46 group.conf -rw-r--r-- 1 root root 1356 Jun 3 13:46 limits.conf -rw-r--r-- 1 root root 2858 Jun 3 13:46 pam_env.conf -rw-r--r-- 1 root root 2154 Jun 3 13:46 time.conf ./lib: total 8316 drwxr-xr-x 3 root root 4096 Jun 4 12:13 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ -rw-r--r-- 1 root root 1024 Jun 4 11:51 cracklib_dict.hwm -rw-r--r-- 1 root root 214324 Jun 4 11:51 cracklib_dict.pwd -rw-r--r-- 1 root root 11360 Jun 4 11:51 cracklib_dict.pwi -rwxr-xr-x 1 root root 342427 Jun 3 13:46 ld-linux.so.2* -rwxr-xr-x 1 root root 4061504 Jun 3 13:46 libc.so.6* lrwxrwxrwx 1 root root 15 Jun 4 12:11 libcrack.so -> libcrack.so.2.7* lrwxrwxrwx 1 root root 15 Jun 4 12:11 libcrack.so.2 -> libcrack.so.2.7* -rwxr-xr-x 1 root root 33291 Jun 4 11:39 libcrack.so.2.7* -rwxr-xr-x 1 root root 60988 Jun 3 13:46 libcrypt.so.1* -rwxr-xr-x 1 root root 71846 Jun 3 13:46 libdl.so.2* -rwxr-xr-x 1 root root 27762 Jun 3 13:46 libhistory.so.4.0* lrwxrwxrwx 1 root root 17 Jun 4 12:12 libncurses.so.4 -> libncurses.so.4.2* -rwxr-xr-x 1 root root 503903 Jun 3 13:46 libncurses.so.4.2* lrwxrwxrwx 1 root root 17 Jun 4 12:12 libncurses.so.5 -> libncurses.so.5.0* -rwxr-xr-x 1 root root 549429 Jun 3 13:46 libncurses.so.5.0* -rwxr-xr-x 1 root root 369801 Jun 3 13:46 libnsl.so.1* -rwxr-xr-x 1 root root 142563 Jun 4 11:49 libnss_compat.so.1* -rwxr-xr-x 1 root root 215569 Jun 4 11:49 libnss_compat.so.2* -rwxr-xr-x 1 root root 61648 Jun 4 11:34 libnss_dns.so.1* -rwxr-xr-x 1 root root 63453 Jun 4 11:34 libnss_dns.so.2* -rwxr-xr-x 1 root root 63782 Jun 4 11:34 libnss_dns6.so.2* -rwxr-xr-x 1 root root 205715 Jun 3 13:46 libnss_files.so.1* -rwxr-xr-x 1 root root 235932 Jun 3 13:49 libnss_files.so.2* -rwxr-xr-x 1 root root 204383 Jun 4 11:33 libnss_nis.so.1* -rwxr-xr-x 1 root root 254023 Jun 4 11:33 libnss_nis.so.2* -rwxr-xr-x 1 root root 256465 Jun 4 11:33 libnss_nisplus.so.2* lrwxrwxrwx 1 root root 14 Jun 4 12:12 libpam.so.0 -> libpam.so.0.72* -rwxr-xr-x 1 root root 31449 Jun 3 13:46 libpam.so.0.72* lrwxrwxrwx 1 root root 19 Jun 4 12:12 libpam_misc.so.0 -> libpam_misc.so.0.72* -rwxr-xr-x 1 root root 8125 Jun 3 13:46 libpam_misc.so.0.72* lrwxrwxrwx 1 root root 15 Jun 4 12:12 libpamc.so.0 -> libpamc.so.0.72* -rwxr-xr-x 1 root root 10499 Jun 3 13:46 libpamc.so.0.72* -rwxr-xr-x 1 root root 176427 Jun 3 13:46 libreadline.so.4.0* -rwxr-xr-x 1 root root 44729 Jun 3 13:46 libutil.so.1* -rwxr-xr-x 1 root root 70254 Jun 3 13:46 libz.a* lrwxrwxrwx 1 root root 13 Jun 4 12:13 libz.so -> libz.so.1.1.3* lrwxrwxrwx 1 root root 13 Jun 4 12:13 libz.so.1 -> libz.so.1.1.3* -rwxr-xr-x 1 root root 63312 Jun 3 13:46 libz.so.1.1.3* drwxr-xr-x 2 root root 4096 Jun 4 12:00 security/ ./lib/security: total 668 drwxr-xr-x 2 root root 4096 Jun 4 12:00 ./ drwxr-xr-x 3 root root 4096 Jun 4 12:13 ../ -rwxr-xr-x 1 root root 10067 Jun 3 13:46 pam_access.so* -rwxr-xr-x 1 root root 8300 Jun 3 13:46 pam_chroot.so* -rwxr-xr-x 1 root root 14397 Jun 3 13:46 pam_cracklib.so* -rwxr-xr-x 1 root root 5082 Jun 3 13:46 pam_deny.so* -rwxr-xr-x 1 root root 13153 Jun 3 13:46 pam_env.so* -rwxr-xr-x 1 root root 13371 Jun 3 13:46 pam_filter.so* -rwxr-xr-x 1 root root 7957 Jun 3 13:46 pam_ftp.so* -rwxr-xr-x 1 root root 12771 Jun 3 13:46 pam_group.so* -rwxr-xr-x 1 root root 10174 Jun 3 13:46 pam_issue.so* -rwxr-xr-x 1 root root 9774 Jun 3 13:46 pam_lastlog.so* -rwxr-xr-x 1 root root 13591 Jun 3 13:46 pam_limits.so* -rwxr-xr-x 1 root root 11268 Jun 3 13:46 pam_listfile.so* -rwxr-xr-x 1 root root 11182 Jun 3 13:46 pam_mail.so* -rwxr-xr-x 1 root root 5923 Jun 3 13:46 pam_nologin.so* -rwxr-xr-x 1 root root 5460 Jun 3 13:46 pam_permit.so* -rwxr-xr-x 1 root root 18226 Jun 3 13:46 pam_pwcheck.so* -rwxr-xr-x 1 root root 12590 Jun 3 13:46 pam_rhosts_auth.so* -rwxr-xr-x 1 root root 5551 Jun 3 13:46 pam_rootok.so* -rwxr-xr-x 1 root root 7239 Jun 3 13:46 pam_securetty.so* -rwxr-xr-x 1 root root 6551 Jun 3 13:46 pam_shells.so* -rwxr-xr-x 1 root root 55925 Jun 4 12:00 pam_smb_auth.so* -rwxr-xr-x 1 root root 12678 Jun 3 13:46 pam_stress.so* -rwxr-xr-x 1 root root 11170 Jun 3 13:46 pam_tally.so* -rwxr-xr-x 1 root root 11124 Jun 3 13:46 pam_time.so* -rwxr-xr-x 1 root root 45703 Jun 3 13:46 pam_unix.so* -rwxr-xr-x 1 root root 45703 Jun 3 13:46 pam_unix2.so* -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_acct.so* -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_auth.so* -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_passwd.so* -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_session.so* -rwxr-xr-x 1 root root 9726 Jun 3 13:46 pam_userdb.so* -rwxr-xr-x 1 root root 6424 Jun 3 13:46 pam_warn.so* -rwxr-xr-x 1 root root 7460 Jun 3 13:46 pam_wheel.so* ./sbin: total 3132 drwxr-xr-x 2 root root 4096 Jun 4 12:35 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ -rwxr-xr-x 1 root root 178256 Jun 3 13:46 choptest* -rwxr-xr-x 1 root root 184032 Jun 3 13:46 cqtest* -rwxr-xr-x 1 root root 81096 Jun 3 13:46 dialtest* -rwxr-xr-x 1 root root 1142128 Jun 4 11:28 ldconfig* -rwxr-xr-x 1 root root 2868 Jun 3 13:46 lockname* -rwxr-xr-x 1 root root 3340 Jun 3 13:46 ondelay* -rwxr-xr-x 1 root root 376796 Jun 3 13:46 pagesend* -rwxr-xr-x 1 root root 13950 Jun 3 13:46 probemodem* -rwxr-xr-x 1 root root 9234 Jun 3 13:46 recvstats* -rwxr-xr-x 1 root root 64480 Jun 3 13:46 sftp-server* -rwxr-xr-x 1 root root 744412 Jun 3 13:46 sshd* -rwxr-xr-x 1 root root 30750 Jun 4 11:46 su* -rwxr-xr-x 1 root root 194632 Jun 3 13:46 tagtest* -rwxr-xr-x 1 root root 69892 Jun 3 13:46 tsitest* -rwxr-xr-x 1 root root 43792 Jun 3 13:46 typetest* ./tmp: total 8 drwxr-xr-x 2 root root 4096 Jun 4 12:32 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ ./usr: total 8 drwxr-xr-x 2 root root 4096 Jun 4 12:16 ./ drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../ lrwxrwxrwx 1 root root 7 Jun 4 12:14 bin -> ../bin// lrwxrwxrwx 1 root root 7 Jun 4 11:33 lib -> ../lib// lrwxrwxrwx 1 root root 8 Jun 4 12:13 sbin -> ../sbin//
Chroot-Umgebung für Apache Einleitung

Das Programm chroot wird häufig dazu benutzt, einen Daemon in einen beschränkten Verzeichnisbaum einzusperren. Sie können es dazu verwenden, um Dienste von anderen abzuschirmen, so dass Sicherheitsprobleme mit einem Softwarepaket den ganzen Server gefährden können. Durch die Verwendung des Skripts makejail wird es viel leichter, einen Verzeichnisbaum in einer chroot-Umgebung einzurichten und zu aktualisieren.

FIXME: Apache can also be chrooted using which is available in `libapache-mod-security` (for Apache 1.x) and `libapache2-mod-security` (for Apache 2.x).

Lizenz

Dieses Dokument ist urheberrechtlich von Alexandre Ratti (2002) geschützt. Es steht unter einer doppelten Lizenz, nämlich der GPL Version 2 (GNU General Public License) und der GNU-FDL 1.2 (GNU Free Documentation Licence). Es wurde in dieses Handbuch mit seiner ausdrücklichen Genehmigung aufgenommen. (Siehe auch das )

Installation des Servers

Diese Vorgehensweise wurde auf Debian GNU/Linux 3.0 (Woody) mit makejail 0.0.4-1 (in Debian/Testing) getestet.

Melden Sie sich als Root an und erstellen Sie ein neues Verzeichnis für das Gefängnis:

$ mkdir -p /var/chroot/apache

Erstellen Sie einen neuen Nutzer und eine neue Gruppe. Der Apache in der chroot-Umgebung wird als dieser Nutzer und Gruppe laufen, die für nichts anderes auf dem System verwendet wird. In dem Beispiel heißen sowohl Nutzer als auch Gruppe chrapach.

$ adduser --home /var/chroot/apache --shell /bin/false \ --no-create-home --system --group chrapach

FIXME: is a new user needed? (Apache already runs as the apache user)

Installieren Sie ganz normal Apache auf Debian: `apt-get install apache` Richten Sie Apache ein (z.B. definieren Sie Ihrer Subdomains usw.). Weisen Sie in der Konfigurationsdatei /etc/apache/httpd.conf den Optionen Group und User `chrapach` zu. Starten Sie Apache neu und stellen Sie sicher, dass der Server korrekt funktioniert. Danach halten Sie den Server wieder an. Installieren Sie makejail (ist fürs Erste in Debian/Testing vorhanden). Sie sollten auch wget und lynx installieren, da sie von makejail benutzt werden, um den Server in der chroot-Umgebung zu testen: `apt-get install makejail wget lynx`. Kopieren Sie die Beispielkonfigurationsdatei für Apache ins Verzeichnis /etc/makejail:
# cp /usr/share/doc/makejail/examples/apache.py /etc/makejail/
Bearbeiten Sie /etc/makejail/apache.py. Sie müssen die Optionen chroot, users und groups verändern. Um diese Version von makejail laufen zu lassen, können Sie auch die Option packages hinzufügen. Vergleichen Sie die . Die Konfigurationsdatei könnte beispielsweise so aussehen:
chroot="/var/chroot/apache" testCommandsInsideJail=["/usr/sbin/apachectl start"] processNames=["apache"] testCommandsOutsideJail=["wget -r --spider http://localhost/", "lynx --source https://localhost/"] preserve=["/var/www", "/var/log/apache", "/dev/log"] users=["chrapach"] groups=["chrapach"] packages=["apache", "apache-common"] userFiles=["/etc/password", "/etc/shadow"] groupFiles=["/etc/group", "/etc/gshadow"] forceCopy=["/etc/hosts", "/etc/mime.types"]

FIXME: some options do not seem to work properly. For instance, /etc/shadow and /etc/gshadow are not copied, whereas /etc/password and /etc/group are fully copied instead of being filtered.

Erstellen Sie den Verzeichnisbaum für chroot: `makejail /etc/makejail/apache.py`. Falls /etc/password und /etc/group vollständig kopiert wurden, geben Sie Folgendes ein, um sie mit gefilterten Fassungen zu ersetzen:
$ grep chrapach /etc/passwd > /var/chroot/apache/etc/passwd $ grep chrapach /etc/group > /var/chroot/apache/etc/group
Kopieren Sie die Webseiten und die Logs ins Gefängnis. Diese Dateien werden nicht automatisch mitkopiert (sehen Sie sich dazu die Option preserve in der Konfigurationsdatei von makejail an).
# cp -Rp /var/www /var/chroot/apache/var # cp -Rp /var/log/apache/*.log /var/chroot/apache/var/log/apache
Editieren Sie das Startskript für den Logging-Daemon des Systems so, dass er auch den Socket /var/chroot/apache/dev/log beobachtet. Ersetzen Sie in /etc/default/syslogd `SYSLOGD=""` mit `SYSLOGD=" -a /var/chroot/apache/dev/log"` und starten Sie den Daemon neu (`/etc/init.d/sysklogd restart`). Editieren Sie das Startskript von Apache (/etc/init.d/apache). Sie müssen vielleicht ein paar Änderung am Standardstartskript vornehmen, damit des richtig in einem Verzeichnisbaum in einer chroot-Umgebung läuft. Da wäre: Legen Sie die Variable CHRDIR am Anfang der Datei neu fest. Bearbeiten Sie die Abschnitte start, stop, reload etc. Fügen Sie eine Zeile hinzu, um das /proc-Dateisystem innerhalb des Gefängnisses zu mounten und abzumounten.
#! /bin/bash # # apache Start the apache HTTP server. # CHRDIR=/var/chroot/apache NAME=apache PATH=/bin:/usr/bin:/sbin:/usr/sbin DAEMON=/usr/sbin/apache SUEXEC=/usr/lib/apache/suexec PIDFILE=/var/run/$NAME.pid CONF=/etc/apache/httpd.conf APACHECTL=/usr/sbin/apachectl trap "" 1 export LANG=C export PATH test -f $DAEMON || exit 0 test -f $APACHECTL || exit 0 # ensure we don't leak environment vars into apachectl APACHECTL="env -i LANG=${LANG} PATH=${PATH} chroot $CHRDIR $APACHECTL" if egrep -q -i "^[[:space:]]*ServerType[[:space:]]+inet" $CONF then exit 0 fi case "$1" in start) echo -n "Starting web server: $NAME" mount -t proc proc /var/chroot/apache/proc start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON \ --chroot $CHRDIR ;; stop) echo -n "Stopping web server: $NAME" start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" --oknodo umount /var/chroot/apache/proc ;; reload) echo -n "Reloading $NAME configuration" start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" \ --signal USR1 --startas $DAEMON --chroot $CHRDIR ;; reload-modules) echo -n "Reloading $NAME modules" start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" --oknodo \ --retry 30 start-stop-daemon --start --pidfile $PIDFILE \ --exec $DAEMON --chroot $CHRDIR ;; restart) $0 reload-modules exit $? ;; force-reload) $0 reload-modules exit $? ;; *) echo "Usage: /etc/init.d/$NAME {start|stop|reload|reload-modules|force-reload|restart}" exit 1 ;; esac if [ $? == 0 ]; then echo . exit 0 else echo failed exit 1 fi

FIXME: should the first Apache process be run as another user than root (i.e. add --chuid chrapach:chrapach)? Cons: chrapach will need write access to the logs, which is awkward.

Ersetzen Sie in /etc/logrotate.d/apache `/var/log/apache/*.log` durch `/var/chroot/apache/var/log/apache/*.log`. Starten Sie Apache (/etc/init.d/apache start) und überprüfen Sie, was im Protokoll des Gefängnisses gemeldet wird (/var/chroot/apache/var/log/apache/error.log). Wenn Ihre Einstellung komplexer sein sollte (z.B. wenn Sie auch PHP und MySQL einsetzen), werden wahrscheinlich Dateien fehlen. Wenn einige Dateien nicht automatisch von makejail kopiert werden, können Sie diese in den Optionen forceCopy (um Dateien direkt zu kopieren) oder packages (um ganze Pakete mit ihren Abhängigkeiten zu kopieren) in der Konfigurationsdatei /etc/makejail/apache.py aufführen.

Geben Sie `ps aux | grep apache` ein, um sicherzustellen, dass Apache läuft. Sie sollten etwas in dieser Art sehen:

root 180 0.0 1.1 2936 1436 ? S 04:03 0:00 /usr/sbin/apache chrapach 189 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache chrapach 190 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache chrapach 191 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache chrapach 192 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache chrapach 193 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
Stellen Sie sicher, dass die Apache-Prozesse in einer chroot-Umgebung laufen. Betrachten Sie dazu das /proc-Dateisystem: `ls -la /proc/process_number/root/.`, wobei process_number einer der PID-Nummern ist, die oben aufgeführt wurden (z.B. 189 in der zweiten Reihe). Die Einträge des eingeschränkten Verzeichnisbaums sollten Sie sich auflisten lassen:
drwxr-sr-x 10 root staff 240 Dec 2 16:06 . drwxrwsr-x 4 root staff 72 Dec 2 08:07 .. drwxr-xr-x 2 root root 144 Dec 2 16:05 bin drwxr-xr-x 2 root root 120 Dec 3 04:03 dev drwxr-xr-x 5 root root 408 Dec 3 04:03 etc drwxr-xr-x 2 root root 800 Dec 2 16:06 lib dr-xr-xr-x 43 root root 0 Dec 3 05:03 proc drwxr-xr-x 2 root root 48 Dec 2 16:06 sbin drwxr-xr-x 6 root root 144 Dec 2 16:04 usr drwxr-xr-x 7 root root 168 Dec 2 16:06 var

Um diesen Test zu automatisieren, geben Sie `ls -la /proc/`cat /var/chroot/apache/var/run/apache.pid`/root/.` ein.

FIXME: Add other tests that can be run to make sure the jail is closed?

Ich mag das, da es so nicht sehr schwierig ist, das Gefängnis einzurichten, und der Server mit nur zwei Zeilen aktualisiert werden kann:

apt-get update && apt-get install apache makejail /etc/makejail/apache.py
Weiterführende Informationen

Wenn Sie nach weiteren Informationen suchen, sehen Sie sich die Quellen an, auf denen diese Anleitung beruht: Die . Diese Programm wurde von Alain Tesio geschrieben. Das von Jonathan A. Zdziarski, 12/03/2003