Proftpd Sftp mit Froxlor

Für das Übertragen von kompletten Ordnerstrukturen mithilfe von Scripten, ist FTP leider nicht zu gebrauchen. Hierfür ist scp bzw. rsync die bessere Alternative, da diese das rekursive kopieren direkt unterstützen. Da mein Server über Froxlor verwaltet wird, ist das einrichten eines SSH Zugriffs für die erstellten Kunden nur über das aktivieren der Shell für FTP-Benutzer möglich. Was nicht sehr sicher ist, weil ab dem Zeitpunkt jeder FTP-Benutzer SSH-Zugriff auf den Server haben kann. Daher zeige ich hier wie einfach mit ProFTPd ein SFTP-Server erstellt werden kann, der direkt für alle FTP-Benutzer einen Zugriff ermöglicht und komplett in ihrem Bereich eingesperrt sind.

Um den SFTP-Server zu konfigurieren muss in einigen Konfigurationsdateien Anpassungen durchgeführt werden, welche unter /etc/proftdp zu finden sind.

SFTP-Modul aktivieren

Zuerst einmal muss überprüft werden, ob die Module für sftp aktiviert sind. Diese werden in der modules.conf konfiguriert und müssen folgende Module aktiviert haben (das Hash am Zeilenanfang entfernen):

LoadModule mod_sftp.c
LoadModule mod_sftp_pam.c
LoadModule mod_sftp_sql.c

Für die Konfiguration des SFTP-Servers liegt typischerweise die sftp.conf schon ab und besitzt eine Standard-Konfiguration. Damit diese Datei beachtet wird, muss ein include in der proftpd.conf hinterlegt werden. Ich habe den Eintrag am Ende der Datei eingefügt, nach der TLS-Konfiguration, wie hier zu sehen:

...
Include /etc/proftdp/sql.conf
Include /etc/proftpd/tls.conf
Include /etc/proftdp/sftp.conf
Include /etc/proftdp/conf.d/

SFTP-Server konfigurieren

Die Konfiguration des SFTP-Servers ist wie folgt aufgebaut, die genauere Beschreibung folgt im Nachgang:

<IfModule mod_sftp.c>
# Der virtuelle Host ist notwendig, damit es unter dem eigenen Port läuft 
<VirtualHost 0.0.0.0>
  Port              2222
  RequireValidShell off
  SFTPEngine        on
  SFTPLog           /var/log/proftpd/sftp.log
  DefaultRoot       ~

  # Konfiguriere die Server-Schlüssel wie bei OpenSSH (bitte anhand der
  # vorhandenen Dateien anpassen)
  SFTPHostKey /etc/ssh/ssh_host_rsa_key
  SFTPHostKey /etc/ssh/ssh_host_dsa_key
  SFTPHostKey /etc/ssh/ssh_host_rsa_key
  SFTPHostKey /etc/ssh/ssh_host_ecdsa_key
  SFTPHostKey /etc/ssh/ssh_host_ed25519_key

  # Definiert als Authentifizerungsmethode ein private-public-key und die Passworteingabe
  SFTPAuthMethods publickey keyboard-interactive

  # Definiert die Ablage der Öffentlichen Schlüssel, wobei der Dateiname dem
  # Benutzernamen entsprechen muss (%u)
  SFTPAuthorizedUserKeys file:/etc/proftpd/authorized_keys/%u
  # Enable compression
  SFTPCompression delayed
</VirtualHost>
</IfModule>

Virtual Host

Eine der wichtigsten Einstellungen ist der VirtualHost. Durch diese kann der FTP-Server weiterhin mit TLS seine Verbindung verschlüsseln und unter den zusätzlich angegebenen Port ist der SFTP-Server erreichbar. Dies muss dann auch entsprechend an der Firewall freigegeben sein. Der Port 2222 ist der Standard-Port aus der vorhanden Konfiguration, kann aber jederzeit verändert werden.

Wenn man möchte kann der SFTP-Server im Standard-SSH-Server deaktiviert werden. Ich wollte dies nicht, da dieser nur für die FTP-Benutzer verwendet werden kann. Aber nicht für die lokalen Linux-Benutzer.

Ungültige Shell verwenden

Der Parameter RequireValidShell ist notwendig, damit keine gültige Shell, wie z.B. /bin/bash hinterlegt sein muss. Dies ist in meinem Fall nicht gewünscht, da sonst eine Anmeldung via SSH ermöglicht werden würde.

Wurzel-Verzeichnis festlegen

Damit die Benutzer in ihrem freigebenen Verzeichnis eingesperrt sind, muss der Parameter DefaultRoot auf ~ gesetzt sein. Damit wird dem Benutzer das Standarverzeichnis inklusive des hitnerlegten Pfades als Root-Verzeichnis hinterlegt.

Authentifizierungsmetoden

Für meinen Fall möchte ich die Möglichkeit haben, dass die Benutzer sich mit Passwort oder mit einer Schlüsseldatei anmelden kann. Letzteres wird für die Verwendung innerhalb von Script benötigt. Damit dies Möglich ist, muss bei SFTPAuthMethods der Wert publickey für die Schlüsseldateien angegeben werden und keyboard-interactive für die Passworteingabe.

Zusätzlich wird mit SFTPAuthorizedUserKeys definiert, wo der Öffentliche Schlüssel für die Benutzer zu finden ist. Diese liegen in einem Unterordner im Konfigurationsverzeichnis und der Dateiname muss dem Benutzername entsprechen.

Prüfen und neustarten

Nach den Anpassungen an der Konfiugration ist es am einfachsten über dem ersten Befehl die Konfiguration zu überprüfen und die aufgezeigten Fehler zu beheben. Danach kann mit dem zweiten Befehl der Server neugestartet werden.

proftpd -t
systemctl restart proftpd

Anmeldung via Schlüsseldatei

Für die Anmeldung mit einer Schlüsseldatei, muss zuerst diese mit dem nachfolgendem Befehle erstellt werden:

ssh-keygen -t ed25519

Die erste Abfrage definiert den Ablagepfad der Schlüsseldatei und sollte entsprechend angepasst werden, weil sonst die eigenen Schlüsseldateien überswchrieben werden. Danach wird nach dem Phassprase gefragt, welcher direkt zweimal mit Enter bestätigt wird, damit kein Passwort auf der Schlüsseldatei liegt.

Der öffentliche Teil muss noch mit dem nachfolgenden Befehl ins RFC4719 Format konvertiert werden, damit es vom ProFTPd-Server verstanden wird:

ssh-keygen -e -f /path/to/pub/id > /etc/proftpd/authorized_keys/<ftp-username>

Verbindung zum SFTP-Server

Um nun Daten an den Server zu übertragen gibt es verschiedene Wege.

Via scp

Um den Inhalt eines kompletten Ordners hochzuladen, ist scp die einfachste Möglichkeit, Mit dem nachfolgenden Befehlt wird der komplette Inhalt von in den kopiert.

scp -i /path/to/private/id -P 2222 -r <upload-folder>/. <ftp-username>@<servername>:/<remote-folder>

Der Ordner auf der Remote-Seite kann auch weggelassen werden, damit werden die Dateien direkt in den Hauptordner abgelegt. Und der Port muss entsprechend der Konfiguration angepasst werden.

Der größte Nachteil von scp ist, dass der Zielordner am Server existieren muss.

Via sftp

Ein einfachs kopieren wie im obigen Beispiel ist über sftp ebenfalls möglich:

sftp -i /path/to/private/id -P 2222 <ftp-username>@<servername> <<< EOF
cd <remote-folder>
put -r ./<upload-folder>/.
bye
EOF

Hierbei könnte vor dem Wechseln in das Zielverzeichnis diese mit mkdir noch erstellt werden. In dieser Schreibweise kann es auch gut in Skripten verwendet werden.

Sehr gut ist noch der Befehlt symlink mit dem symbolische Links im Verzeichnis erstellt werden können.

Bekannte Probleme

Aber auch bei SFTP ist nicht alles gut. Mein größtestes Problem mit dem Server ist, dass das entfernen eines kompletten Ordners inklusive des Inhalts nicht Möglich ist. Hierfür müssen erst alle Dateien und Unterordner entfernt werden bevor der Ordner gelöscht werden kann.