Dateien-App oder eine eigene App
Die Dateien-App hat den Befehl „Mit Server verbinden“, aber der ist für Dateiserver wie SMB-Freigaben gedacht. SFTP bietet sie nicht an, für den Zugriff auf einen Server über SSH brauchen Sie also eine SFTP-Client-App.
Apps unterscheiden sich darin, wie sie sich in die Dateien-App einfügen. Manche fügen einen eigenen Ort hinzu, sodass Sie den Server direkt in Dateien durchsuchen können. Andere legen Downloads in einem eigenen Ordner ab, der unter „Auf meinem iPhone“ erscheint. Prüfen Sie, welche Variante Sie bekommen, denn davon hängt ab, wie Sie eine Datei in anderen Apps öffnen.
Worauf Sie bei einer App achten sollten
- Anmeldung per Schlüssel, mit Ed25519-Schlüsseln und Passphrase.
- Prüfung des Host-Schlüssels, mit Stopp, wenn sich der Schlüssel ändert.
- Uploads aus Fotos und Dateien, denn dort liegen die Dateien auf dem Telefon.
- Verhalten im Hintergrund. iOS kann eine App anhalten, die den Bildschirm verlässt, eine große Übertragung kann also abbrechen. Finden Sie heraus, was die App tut, und testen Sie mit einer großen Datei.
- Fortsetzen, damit ein fehlgeschlagener Upload bei schwacher Verbindung nicht von vorn beginnen muss.
- Wo sie Geheimnisse speichert und ob sie eine App-Sperre hat.
Was SFTP auf dem Server braucht
SFTP läuft innerhalb von SSH. Wenn SSH funktioniert, brauchen Sie nur noch eines: das sftp-Subsystem. Prüfen Sie es:
sudo sshd -T | grep -i '^subsystem'
Unter Debian erscheint subsystem sftp /usr/lib/openssh/sftp-server. Erscheint nichts, scheitern SFTP-Clients so:
subsystem request failed on channel 0
Connection closed
Zur Behebung fügen Sie Subsystem sftp internal-sftp in die sshd_config ein und laden sshd neu. Wie Sie von einem Telefon aus einen privaten Server erreichen, steht in SSH vom iPhone. Der Netzwerkweg ist derselbe.
Ein Benutzer, der SFTP nur in einem Ordner nutzen kann
Ihr Telefon braucht keine Shell auf dem Server, um Fotos hochzuladen. Ein eigener Benutzer begrenzt den Schaden, wenn das Telefon oder sein Schlüssel verloren geht. Legen Sie Gruppe, Benutzer und Ordner an:
sudo groupadd sftponly
sudo useradd -g sftponly -s /usr/sbin/nologin -d /srv/sftp/sftpuser -M sftpuser
sudo mkdir -p /srv/sftp/sftpuser/uploads /srv/sftp/sftpuser/.ssh
sudo chown root:root /srv/sftp /srv/sftp/sftpuser
sudo chmod 755 /srv/sftp /srv/sftp/sftpuser
sudo chown sftpuser:sftponly /srv/sftp/sftpuser/uploads /srv/sftp/sftpuser/.ssh
sudo chmod 700 /srv/sftp/sftpuser/.ssh
Legen Sie den öffentlichen Schlüssel des Telefons an Ort und Stelle, aus einer Datei, die Sie auf den Server kopiert haben:
sudo install -m 600 -o sftpuser -g sftponly iphone.pub /srv/sftp/sftpuser/.ssh/authorized_keys
Noch kein Schlüsselpaar? Siehe wie Sie einen Ed25519-SSH-Schlüssel erzeugen.
Erstellen Sie dann /etc/ssh/sshd_config.d/20-sftp.conf:
Match Group sftponly
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
AllowAgentForwarding no
X11Forwarding no
PermitTunnel no
PermitTTY no
Hat Ihr System kein sshd_config.d, setzen Sie den Block ganz ans Ende der sshd_config, denn ein Match-Block dort gilt bis zum Dateiende. Prüfen Sie ihn und laden Sie dann neu:
sudo sshd -t
sudo sshd -T -C user=sftpuser,host=example.com,addr=203.0.113.10 | grep -iE '^(chrootdirectory|forcecommand)'
sudo systemctl reload ssh
Der zweite Befehl muss forcecommand internal-sftp und chrootdirectory %h ausgeben, ab OpenSSH 10.4 mit Großbuchstaben wie ForceCommand. Führen Sie ihn mit einem anderen Benutzernamen noch einmal aus, um zu prüfen, dass andere weiterhin none zeigen. Unter Fedora und RHEL heißt der Dienst sshd.
Die Regel zu den Besitzrechten
Darüber stolpern fast alle. Jeder Ordner im chroot-Pfad, bis einschließlich der chroot selbst, muss root gehören und darf für Gruppe und andere nicht beschreibbar sein. Der Benutzer kann also nicht direkt in seinen eigenen obersten Ordner schreiben, und deshalb gibt es uploads.
Als wir den obersten Ordner dem Benutzer gaben, scheiterte die Anmeldung, und auf dem Client stand nur dies:
Connection to server closed by remote host.
Connection closed
Der wahre Grund steht im Server-Log:
bad ownership or modes for chroot directory "/srv/sftp/sftpuser"
Erst von einem Computer aus testen
$ sftp sftpuser@server
sftp> pwd
Remote working directory: /
sftp> cd uploads
sftp> put photo.jpg
sftp> cd /
sftp> put photo.jpg
dest open "/photo.jpg": Permission denied
sftp> get /etc/passwd
File "/etc/passwd" not found.
Eine Shell-Anmeldung muss scheitern, mit This service allows sftp connections only. Im selben Test funktionierte scp nach /uploads, weil es SFTP nutzt, und rsync scheiterte, weil es ein Programm auf dem Server ausführen muss. Siehe scp, SFTP oder rsync.
Eine Einschränkung: Der Benutzer besitzt .ssh innerhalb der chroot, wer diesen Schlüssel hat, kann also authorized_keys lesen oder ändern. Das gibt keine Shell und keinen Zugriff außerhalb des Ordners, aber ein weiterer Schlüssel für dieses Konto ließe sich hinzufügen. Setzen Sie AuthorizedKeysFile im Match-Block auf einen Pfad außerhalb der chroot, wenn Ihnen das wichtig ist.


Fragen
Kann sich die Dateien-App des iPhone mit einem SFTP-Server verbinden?
Nein. „Mit Server verbinden“ in der Dateien-App ist für Dateiserver wie SMB gedacht, nicht für SFTP. Für einen Server per SSH brauchen Sie eine SFTP-Client-App.
Welchen Port nutzt SFTP?
Den SSH-Port, also 22, sofern der Server nichts anderes vorgibt, denn SFTP läuft innerhalb einer SSH-Verbindung.
Warum bekommt ein reiner SFTP-Benutzer direkt nach der Anmeldung Connection closed?
Meist haben die Chroot-Ordner den falschen Eigentümer. Jeder Ordner bis zum Chroot muss root gehören und darf für andere nicht beschreibbar sein, und im Serverlog steht bad ownership or modes for chroot directory.
Quellen
- sshd_config(5): ChrootDirectory, ForceCommand, Subsystem, OpenBSD manual
- sftp(1), OpenBSD manual
- Connect servers or external devices with Files on iPhone, Apple Support