Ab OpenBSD 4.3 besitzt OpenSSH die neue Funktion ChrootDirectory. Dies ist eine von vielen (auch mir) lange gewünschte Funktion, die das aufsetzen einer Chroot-Umgebung für SSH beträchtlich vereinfacht. Bislang war ein Chroot-SSH nur sehr umständlich zu konfigurieren. Wie setzt man diese neue Funktion ein?
Möchte man für seine Benutzer nur SFTP Zugriff ist die Einrichtung sogar besonders einfach.
In der /etc/ssh/sshd_config muß der Parameter bei Subsystem sftp auf internal-sftp umgestellt werden:
Subsystem sftp internal-sftp
Danach kann man Benutzern oder Benutzergruppen ein Chroot-Verzeichnis zuweisen. Dies geht am besten mit der Match-Direktive von sshd:
Match Group sftpuser
ChrootDirectory /home
ForceCommand internal-sftp
AllowTCPForwarding no
In diesem Fall muß natürlich erst die Gruppe sftpuser existieren. Dann wird jeder User der Gruppe sftpuser das Verzeichnis /home, als sein /-Verzeichnis sehen. Das ChrootDirectory muß übrigens immer ein Verzeichnis sein, das root gehört und nicht schreibbar für normale User ist. Das heißt das typischerweise nicht direkt das Heimatverzeichnis eines Users sein ChrootDirectory ist, sondern ein Verzeichnis darüber
Zusätzlich kann man noch, damit der Pfad zum Heimatverzeichnis aufgelöst werden kann einen symbolischen Link setzen:
cd /home ln -s . home
Falls Benutzer nicht nur sftp benutzen können sollen, sondern auch direkt auf der Shell arbeiten können sollen, ist noch etwas zusätzliche Konfiguration notwendig. Das ForceCommand internal-sftp von oben muß hingegen entfernt werden, damit auch andere Befehle funktionieren.
Damit eine Shell benutzt werden kann, muß natürlich eine solche innerhalb des ChrootDirectory vorhanden sein. Außerdem werden auch noch ein paar Gerätedateien unter /dev benötigt. Daher müssen innerhalb des ChrootDirectory die Verzeichnisse dev und bin angelegt werden:
cd /home mkdir bin dev
Nun müssen die benötigten Gerätedateien angelegt werden. Dabei darf außerdem das ChrootDirectory nicht in einem Verzeichnis liegen welches mit der Option nodev gemountet wurde. An Gerätedateien werden arandom, null, zero, stdin, stderr, stdout und tty benötigt:
Gerätedateien auf der Partition aktivieren:
mount -u -o dev /home
Diese Änderung dauerhaft machen (entfernen der nodev-Option in der /etc/fstab):
vi /etc/fstab
Weiter auf der Shell:
cd /home/dev mknod -m 644 arandom c 45 4 mknod -m 666 null c 2 2 mknod -m 666 zero c 2 12 mknod -m 666 stderr c 22 2 mknod -m 666 stdin c 22 0 mknod -m 666 stdout c 22 1 mknod -m 666 tty c 1 0
Nun muß man noch die Shell und weitere benötigte Programme aus /bin ins ChrootDirectory kopieren. Dabei muß man unter OpenBSD keine Abhängigkeiten berücksichtigen, da alle Programme die in /bin liegen unter OpenBSD statisch kompiliert wurden:
cd /home/bin cp -p /bin/ksh . cp -p /bin/cp . cp -p /bin/ls . cp -p /bin/mkdir . cp -p /bin/mv . cp -p /bin/rm . cp -p /bin/rmdir . cp -p /bin/sleep . cp -p /bin/test . cp -p /bin/tar . ln tar cpio ln tar pax ln ksh sh ln ksh rksh ln test [
Da man meistens mit dieser geringen Grundausstattung nicht auskommen wird, wird man weitere Programme aus /usr/bin benötigen. Diese können Abhängigkeiten zu Libraries aus /usr/lib haben, die man mit dem Tool ldd prüfen kann und die dann ebenfalls kopiert werden müssen. Es kann auch sein, das manche Programme weitere Verzeichnisse und/oder Dateien benötigen wie etwa in /usr/share oder Verzeichnisse unterhalb von /var oder das tmp-Verzeichnis. Dies muß dann im Einzelfall geprüft werden. Hier erst mal ein einfaches Beispiel:
cd /home mkdir -p usr/bin mkdir usr/lib mkdir usr/libexec ldd /usr/bin/env cp -p /usr/bin/env usr/bin cp -p /usr/lib/libc.so.43.0 usr/lib cp -p /usr/libexec/ld.so usr/libexec ldd /usr/bin/grep cp -p /usr/bin/grep usr/bin cp -p /usr/lib/libz.so.4.1 usr/lib cd usr/bin ln grep egrep ln grep fgrep ln grep zgrep ln grep zegrep ln grep zfgrep
Etwas komplizierter gestaltet sich der vi-Editor. Dieser benötigt noch temporäre Verzeichnisse und die Terminal Datenbank /etc/termcap:
cd /home ldd /usr/bin/vi cp -p /usr/bin/vi usr/bin cp -p /usr/lib/libcurses.so.10.0 usr/lib cd usr/bin ln vi ex ln vi view cd ../.. mkdir etc var cp -p /etc/termcap etc mkdir -m 1777 tmp mkdir -m 1777 var/tmp
Wer außerdem möchte das mit dem ls Befehl korrekte Usernamen und Gruppen angezeigt werden kann auch noch die beiden Dateien /etc/group und /etc/pwd.db ins ChrootDirectory kopieren. Diese enthalten keine Passwörter:
cd /home cp -p /etc/group etc cp -p /etc/pwd.db etc
Wenn sich die SSH-User nicht gegenseitig in Ihre Heimatverzeichnisse blicken lassen sollen, müssen noch die Rechte auf die Heimatverzeichnisse selbst korrigiert werden:
cd /home chmod 700 username
Auf einem Webserver könnte das auch so aussehen (falls /var/www/users statt wie vorher beschrieben /home benutzt wurde):
cd /var/www/users chgrp www username chmod 710 username