Website-Verwaltung mit SFTP statt FTP

Ein Klassiker unter den Fragen, denen man immer wieder begegnet. Vor allem jetzt, da das (ur)altgediente FTP kaum noch Anwendung findet.
Wie ersetze ich das FTP (File Transfer Protocol) durch das SFTP (SSH File Transfer Protocol) und behalte den Verwaltungskomfort meiner Webseiten?

Changelog

  • 12. Dez 2014 – „umask 002“ für „sftpuser“ via SFTP

Auch in Zeiten der Web-Spionage-Paranoia, hat das FTP noch seine Daseinsberechtigung. Wie sonst schaufelt der Admin im privaten Netz so schnell Daten von A nach B? Und das vom Toaster in den Kühlschrank (Stichwort: Kompatibilität).
Natürlich ist es auch im FTP möglich, den Datenverkehr implizit (auf Anfrage) und explizit (von Beginn an) zu verschlüsseln. Doch wenn der SSH Daemon sowieso schon einen Fuß im öffentlichen Netz stehen hat, verzichte ich auf ein weiteres Angriffsziel. Zumal ein FTP-Server abhängig von der Betriebsart mindestens zwei offene Ohren ins Netz lehnt.

Geschätzt 98% der Angriffe auf die Secure Shell, lassen sich schon durch die Umlegung des öffentlichen Ports von 22 auf einen beliebigen anderen vereiteln. (Tipp: „echo ${RANDOM}“).

Ich beziehe mich im Verlauf auf OpenSSH in Debian >= Wheezy und Konsorten.

Einrichtung

Folgende Annahme:
WWW-Root: /usr/share/nginx/html
SFTP-Benutzer: sftpuser
Webroot-Besitzer: www-data

Den SFTP-Benutzer unter Zuweisung der Datei „/usr/lib/openssh/sftp-server“ als Shell im System hinzufügen:

adduser sftpuser --ingroup www-data --shell /usr/lib/openssh/sftp-server --no-create-home

Den Mitgliedern der Gruppe „www-data“ erlauben, im Verzeichnis „/usr/share/nginx/html“ zu schreiben:

chmod -R g+w /usr/share/nginx/html

Dem Benutzer „sftpuser“ einzig Zugang via SFTP in ein gesperrtes Verzeichnis geben.
Zusätzlich wird die „umask 002“ für Dateien und Ordner dieses Benutzers bestimmt. Das hat zur Folge, dass Gruppenmitglieder ebenso die von „sftpuser“ erstellten Objekte schreiben dürfen.

nano /etc/ssh/sshd_config

Am Ende hinzufügen:

Match User sftpuser
  ChrootDirectory /usr/share/nginx
  ForceCommand internal-sftp -u 002
  AllowTcpForwarding no
  PermitTunnel no
  Subsystem sftp /usr/lib/openssh/sftp-server
  X11Forwarding no
Das „ChrootDirectory“ muss „root“ gehören!

Beispiel:

/usr/share
└── [root     root    ]  ./nginx
    └── [www-data www-data]  ./nginx/html

5 Antworten auf “Website-Verwaltung mit SFTP statt FTP

  1. iamauser

    Eine Sache möchte ich kurz zu passwortabgesicherten SSH Logins sagen.
    Wenn ich von überall auf meinen SSH Zugang Zugang haben möchte, werde ich ein Passwort brauchen. Ich habe noch nie jemanden gesehen, der einen private Key immer mit sich führt.

    Dazu kann ich aber sagen, dass man das ganze sehr gut mit TOTP absichern kann. Jeder hat heutzutage ein Smartphone mit, wo er dann den TOTP Key zusätzlich bekommt.

  2. Lars

    Hi, ich würde das mit dem Port-Umbiegen nicht so unterschreiben, zumindest nicht wenn man sich nicht noch ein paar andere Gedanken dazu gemacht hat, da es wirklich sehr einfach ist festzustellen welcher Dienst gerade hinter welchem Port steckt z.B.: „nmap -v -sV -O -p- http://www.debinux.de„. Dies ist ungefähr so hilfreich wie wenn man ICMP-Pakete blockt, um sich vor Angriffen zu schützen. Scriptkiddies kann man in vielen Fällen bereits z.B. via fail2ban aufhalten, ansonsten würde ich in sicherheitsrelevanten Fällen SSH nur via Schlüssel-Authentifizierung (keine Passworteingabe) zulassen.

    Wenn man einen Server nicht nur private, sondern in einer Firma verwendet empfiehlt sich immer eine Firewall ggf. die öffentliche IP-Adresse für SSH oder nur über einen anderen Server via Port-Weiterleitung via SSH erlauben. PS: so kann man auch eine gesicherte Verbindung zu z.B. MySQL aufbauen

    Zusammenfassung für sichere SSH-Logins: (sicherheitsrelevant in absteigender Reihenfolge)
    – SSH Port ändern, wenn man eine Firewall einsetzt würde ich diesen Schritt auslassen (Port [ ${RANDOM} && >= 1024 ])
    – keine SSH Login via „root“ (PermitRootLogin no)
    – installiere „fail2ban“ (apt-get install fail2ban)
    – Schlüssel-Authentifizierung (PubkeyAuthentication yes)
    – keine Passwort-Authentifizierung (PasswordAuthentication no ; UsePAM no)
    – Firewall && [feste IP-Adresse || anderen Server]

    Mfg Lars

    1. André P. Autor

      Hi,
      danke für deinen ausführlichen Kommentar. :-) Ich habe diesen Beitrag seit einer Woche in der Queue und wirklich lange gezögert, ihn zu veröffentlichen. Einerseits wollte ich keine halben Sachen zur allgemeinen (!) Konfiguration des OpenSSHd von mir lassen, wo die Konzentration wirklich nur auf das Subsystem SFTP fällt. Andererseits wollte ich keine Diskussion dazu auslösen. Close enough.
      Ich habe mich dann doch dazu durchgerungen den Beitrag zu veröffentlichen und mindestens den Hinweis zum umbiegen des Ports gegeben. Ursprünglich stand hier auch der Hinweis „> well-known“ und noch einige weitere Kleinigkeiten; alles ausgelassen.
      Die typische Vorgehensweise ist meiner Erfahrung nach der massenweise Portscan einer dicken IP-Range und dann das automatisierte Bruteforcen der gefundenen Hosts auf Port 22. Wenn sich jemand die Arbeit macht, meinen Server erst auf potentielle SSHd Ports zu scannen, muss er es schon auf mich abgesehen haben, glaube ich. :-) Und klar, dann ist einerseits Fail2ban super (wobei der SSHd-Port auch hier angepasst werden muss an die Konfiguration) oder eine Tarpit (dazu wollte ich demnächst etwas schreiben).
      Dafür dass du die wichtigen Parameter wie PermitRootLogin (wobei mir hier persönlich schon „without-password“ reicht, arghh ich schweife wieder ab…) etc. ansprichst, bin ich dir dennoch dankbar.
      Beste Grüße
      André

      1. Gerald

        Security by obscurity is no security at all…

        Warum nicht einfache Firewall-Regeln?

        Variante 1: Port stellt sich nach 3 Fehlversuchen für eine Minute tot. Diese Minute beginnt natürlich mit jedem neuen Versuch neu zu laufen, dh. ein Brute-Force-Angreifer sieht nie wieder ein „lebendes“ Port.

        /sbin/iptables -A INPUT -p tcp -m tcp –dport 22 -m state –state NEW -m recent –set –name SSH –rsource
        /sbin/iptables -A INPUT -p tcp -m tcp –dport 22 -m state –state NEW -m recent –update –seconds 60 –hitcount 4 –name SSH –rsource -j DROP

        Variante 2: Du willst nur von dezitierten IP-Adressen zugreifen:
        /sbin/iptables -A INPUT -i eth2 -s 192.168.1.175 -p tcp –dport 22 -j ACCEPT
        /sbin/iptables -A INPUT -i eth2 -s 10.68.1.15 -p tcp –dport 22 -j ACCEPT
        /sbin/iptables -A INPUT -i eth2 -p tcp –dport 22 -j DROP

        Wichtig ist aus meiner Sicht das „DROP“ statt des meist empfohlenen „REJECT“. Warum? Weil dann das Ziel aus Sicht des Angreifers tot ist, während eine Reject-Nachricht ungefährt das bedeutet: „Hörst du mich?“ – „Nein!“ ;-) Das heißt also, der Angreifer weiß nach wie vor, dass sich dahinter ein Ziel verbirgt und wird es ggf. mit anderen Methoden weiter versuchen. Außerdem muss der Angreifer sein volles Timeout abwarten, wenn das Paket einfach verworfen wird, denn eine Antwort könnte ja auch verzögert eintreffen. DROP ist also der maximalste Aufwand für den Angreifer beim minimalsten Aufwand für den Angegriffenen und gleichzeitiger Reduktion des Netzwerktraffics.

        Oder natürlich: OpenVPN installieren… Dann brauchst du nicht mal mehr SSH oder SFTP im Internet offen haben. Natürlich gehört OpenVPN genauso per Firewall abgesichert.

      2. Lars

        Hi André, wollte auch keine Grundsatzdiskusion zum Thema Sicherheit erhöffnen, jedoch das mit dem Port umbiegen nicht so einsam da stehen lassen.

        PS: bei dem eigentlichen Thema FTP zu ersetzen kann ich nur Zustimmen. :) Wer Dinge für’s Web programmiert und deployed sollte sich ggf. ganz von ftp etc. verabschieden. Lokal Programmieren ist immer schneller (ggf. via Vagrant), mit Jenkins testen/protokollieren lassen und automatisch via git deployen! Man weiß immer welcher Stand auf dem Server ist, man kann jederzeit Änderungen nachvollziehen und Rückgang mache und das für verschiedene Webs auf unterschiedlichen Servern ausführen lassen. Außerdem macht das mehr Spaß… Happy Coding :D

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.