Vor zwei Jahren wollte ich mehrere 100 MB an Fotos mit ein paar Freunden teilen, die sich nach einem gemeinsamen Urlaub angesammelt hatten. Damals waren Dropbox und ähnliche Dienste noch nicht ganz so präsent wie heute. Außerdem war es eine gute Gelegenheit mehr über FTP- und SSH-Server zu lernen und manch bekennenden Windowsnutzer ordentlich zu verwirren: "Ja, du musst ssh benutzen. Es gibt keine andere Möglichkeit um an die Fotos zu gelangen." haha 😈
Zu dieser Zeit sollte es unbedingt ein sftp-Server sein, da ich für viele andere Aufgaben sowieso schon ssh einsetzte. Damit spart man sich das Einrichten eines zusätzlichen ftp-Servers und erhält gleichzeitig noch eine sichere Methode zum Datenaustausch dazu.
Die folgende Anleitung beschreibt die Einrichtung eines ssh-Servers, der für eine Gruppe von Benutzern nur als sftp-Server zugänglich sein soll. Alle User werden dabei in einer chroot-Umgebung eingesperrt und Shell-Zugriff verwehrt um die Sicherheit auf dem Server zu erhöhen. Als Beispiel dient mir der Benutzer mika und die Gruppe freunde. Das HowTo sollte mit jeder auf Debian basierenden Distribution funktionieren und sich mit jeder anderen nachvollziehen lassen.
Installation
aptitude install ssh
Anlegen der für sftp berechtigten Nutzer und der Gruppe freunde
adduser mika
addgroup freunde
adduser mika freunde
Absichern des Chroot Verzeichnisses
chown root.root /home/mika
Mikas Heimverzeichnis sollte im Besitz von root sein, damit er effektiv darin eingesperrt ist und er standardmäßig keine Dateien auf dem Server hochladen kann. Da aber ein Datenaustausch auch manchmal in umgekehrter Richtung sinnvoll sein kann, genügt es, einen Ordner wie upload in diesem Verzeichnis zu erstellen und ihn Mika mit
chown mika.mika /home/mika/upload
zu überantworten.
Konfiguration von /etc/ssh/sshd_config
Notwendige Sicherheitsvorkehrungen
- Port 42123
Der Standardport für SSH ist 22. Mit dieser Variablen lässt sich der Listen Port z.B. auf 42123 für den Server ändern. Das macht den Server zwar kein bisschen sicherer (security through obscurity), hilft aber unter Umständen die Existenz des ssh-Servers zu verschleiern.
- PermitRootLogin no
Wenn ein Angreifer root werden möchte, muss er mit dieser Einstellung mindestens noch das Passwort eines weiteren Users auf dem Server kennen.
- PermitEmptyPasswords no
SSH-Nutzer ohne Passwort sind natürlich ein Unding. Obwohl ich mir gut vorstellen kann, dass man das als eine weitere Möglichkeit zu "Was man mit alten Computern machen kann" hinzufügen könnte. Anstatt selbst zu lernen wie man in den eigenen alten Rechner einbricht, könnte man das doch auch andere tun lassen... 😉
- Subsystem sftp internal-sftp
Das aktiviert sshds internen sftp-Service. Normalerweise verweist Subsystem sftp auf eine ausführbare Binärdatei wie z.B. /usr/lib/openssh/sftp-server. Diese muss durch den internen Dienst ersetzt werden.
Am Ende der /etc/ssh/sshd_config sollte dann folgender Match-Eintrag hinzugefügt werden.
Match group freunde ChrootDirectory /home/%u X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp
Der Match-Block gilt nur für die Gruppe freunde und jeden Nutzer, der sich darin befindet. Mika kann sich deswegen nur per sftp mit dem Server verbinden und landet danach im festgelegten Chroot-Verzeichnis. Der Shell Zugriff mit ssh wird effektiv unterbunden. Das Chroot muss nicht zwangsläufig mit Mikas Homeverzeichnis übereinstimmen und kann beliebig gewählt werden. Der Parameter %u wird durch den eingeloggten Nutzer ersetzt.
Der erste Test
Jetzt ist es an der Zeit den OpenSSH-Server neuzustarten. Als SFTP-Klienten eignen sich später z.B. das Firefox Addon Fireftp, Filezilla, WinSCP für Windows oder ganz einfach das Kommandozeilenprogramm sftp.
/etc/init.d/ssh restart
Danach sollte der sftp-Zugriff für Mika am Beispielrechner 192.168.0.200 funktionieren.
sftp -P 42123 mika@192.168.0.200
und der ssh-Zugriff verwehrt werden
ssh -p 42123 mika@192.168.0.200
DynDNS.org
Es ist zwar schön, dass der Server nun in unserem internen Netzwerk funktioniert, aber irgendwie müssen die Freunde von außerhalb darauf zugreifen können. Die meisten werden sicherlich eine dynamische IP vom Provider zugewiesen bekommen, weshalb es Sinn macht einen kostenlosen DNS-Dienst wie z.B. dyndns.org zu benutzen, um eine leicht zu merkende URL wie z.B. 4freunde.dyndns.org zu erhalten.
Nachdem man sich bei dyndns.org angemeldet hat, muss man dem Dienst auf irgendeine Art noch mitteilen wie die aktuelle IP-Adresse des Heimservers lautet. Dazu bietet sich z.B. ddclient an. Bei der Installation wird man nach Login und Passwort bei dyndns.org gefragt und kann ansonsten die Standardeinstellungen verwenden.
Sollte man eine Firewall einsetzen oder wie ich einen Router mit eingebauter Firewall haben, dann muss nur noch der SSH-Dienst mit Hilfe von PortForwarding an den Zielserver und Port 42123 weitergeleitet werden. Danach kann sich dann Mika von überall auf der Welt mit
sftp -P 42123 mika@4freunde.dyndns.org
auf dem Heimserver einloggen.
Last but not least - Denyhosts
Wenn man seinen Server eine Weile laufen lässt und spaßeshalber mal die Datei /var/log/auth.log öffnet, fallen einem die regen Zugriffsversuche auf...die allesamt nicht von den Freunden stammen. Willkommen im Internet! John Doh und Nihao versuchen mit Brute-Force-Attacken in den ssh-Server einzubrechen. Eine wirksame Methode das zu unterbinden ist z.B. denyhosts oder noch besser gleich den SSH-Port ändern und auf SSH-Schlüssel umstellen.
Bei Debian konnte ich nach der Installation mit den Voreinstellungen sehr gut leben. Die Datei /etc/denyhosts.conf ist aber hervorragend kommentiert und lässt sich leicht an die eigenen Wünsche anpassen. Das Programm registriert fehlgeschlagene Logins und setzt die IP Adresse des Angreifers nach einer festgelegten Anzahl von Versuchen in die Datei /etc/hosts.deny, womit jeder weitere Loginversuch verwehrt wird. Es gibt noch viele weitere Möglichkeiten einen Mißbrauch zu verhindern. Ich fand damals diesen Heise-Artikel zum Thema sehr lesenswert. Wenn man sehr restriktiv ist und vielleicht sogar die IP-Adresse der Freunde kennt, kann man auch alle Zugriffe mit Hilfe von /etc/hosts.allow und /etc/hosts.deny verbieten und nur ausgewählte IPs erlauben.
SSH ist ein ausgesprochen vielseitiges und nützliches Werkzeug. Als Beweis, dass ich nicht der Einzige bin, der positive Erfahrungen mit ssh gemacht hat, hier mal ein Link zu keros Artikel "sperr mich ein baby".
Ajo, danke fuer die Erwaehnung…aber den Match Block sollte man mit Match am Ende abschliessen. Merkt man spaetestens wenn man darunter noch was an die config Datei anhaengen will ;-).
Kein Problem. Nachdem ich deinen Post gelesen hatte und du erwähntest, dass das bei dir mit mehreren 100 Usern funktioniert, konnte ich es nicht ignorieren. 😉
Das mit dem Match Block ist witzig. Irgendwo habe ich gelesen, dass alle Match Blöcke an das Ende der sshd_config gehören, womit es mit meinem Beispiel kein Problem geben sollte. Alle anderen Config Variablen sollen davor stehen.
Kommt ein neuer Match Block dazu, ist das sozusagen sowohl Anfang des neuen Blocks als auch das Ende des alten und es treten keine Probleme auf. Ich werde es trotzdem im Text nochmal erwähnen. Dankö!
Die Anleitung ist gut.
Ich habe sie ca. 10 Mail probiert. Am Ende sogar mit mika und freunde. Als root.
Aug 13 13:24:11 nameserver sshd[4038]: Received disconnect from 192.168.3.106: 11: disconnected by user
Und auf der anderen Seite schreibt er nach Eingabe des Passworts nur connection closed.
Warum nur? Ich kann nicht mehr!