L'app Fichiers ou une app séparée
L'app Fichiers a une commande Se connecter au serveur, mais elle est prévue pour les serveurs de partage de fichiers comme les partages SMB. Elle n'offre pas SFTP : pour atteindre un serveur via SSH, il vous faut donc une app cliente SFTP.
Les apps diffèrent dans leur façon de s'intégrer à l'app Fichiers. Certaines ajoutent leur propre emplacement, et vous pouvez alors parcourir le serveur depuis Fichiers. D'autres gardent les téléchargements dans un dossier à elles, qui apparaît sous Sur mon iPhone. Vérifiez laquelle vous avez, car cela décide de la façon d'ouvrir un fichier dans d'autres apps.
Quoi chercher dans une app
- Connexion par clé, avec des clés Ed25519 et une phrase secrète.
- Vérification des clés d'hôte, avec un arrêt quand la clé change.
- Envois depuis Photos et Fichiers, car c'est là que se trouvent les fichiers d'un téléphone.
- Comportement en arrière-plan. iOS peut suspendre une app qui quitte l'écran : un gros transfert peut donc s'arrêter. Renseignez-vous sur ce que fait l'app, et testez avec un gros fichier.
- Reprise, pour qu'un envoi raté sur une connexion faible n'ait pas à repartir de zéro.
- Où elle stocke les secrets, et si elle a un verrouillage de l'app.
Ce que SFTP exige côté serveur
SFTP fonctionne à l'intérieur de SSH : si SSH marche, il ne manque qu'une chose, le sous-système sftp. Vérifiez-le :
sudo sshd -T | grep -i '^subsystem'
Sur Debian, cela affiche subsystem sftp /usr/lib/openssh/sftp-server. Si rien n'apparaît, les clients SFTP échouent ainsi :
subsystem request failed on channel 0
Connection closed
Pour corriger, ajoutez Subsystem sftp internal-sftp à sshd_config et rechargez sshd. Pour joindre un serveur privé depuis un téléphone, voir SSH depuis un iPhone. C'est le même chemin réseau.
Un utilisateur qui ne peut utiliser SFTP que dans un dossier
Votre téléphone n'a pas besoin d'un shell sur le serveur pour envoyer des photos. Un utilisateur dédié limite les dégâts si le téléphone ou sa clé est perdu. Créez le groupe, l'utilisateur et les dossiers :
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
Placez la clé publique du téléphone, à partir d'un fichier que vous avez copié sur le serveur :
sudo install -m 600 -o sftpuser -g sftponly iphone.pub /srv/sftp/sftpuser/.ssh/authorized_keys
Pas encore de paire de clés ? Voir comment générer une clé SSH Ed25519.
Créez ensuite /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
Si votre système n'a pas de sshd_config.d, placez le bloc tout à la fin de sshd_config, car un bloc Match s'applique jusqu'à la fin du fichier. Vérifiez, puis rechargez :
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
La deuxième commande doit afficher forcecommand internal-sftp et chrootdirectory %h, avec des majuscules, comme ForceCommand, à partir d'OpenSSH 10.4. Relancez-la avec un autre nom d'utilisateur pour vérifier que les autres affichent toujours none. Sous Fedora et RHEL, le service s'appelle sshd.
La règle de propriété
C'est ce qui piège presque tout le monde. Chaque dossier du chemin du chroot, jusqu'au chroot inclus, doit appartenir à root et ne pas être modifiable par le groupe ni par les autres. L'utilisateur ne peut donc pas écrire directement dans son propre dossier de premier niveau, et c'est pourquoi uploads existe.
Quand nous avons donné le dossier de premier niveau à l'utilisateur, la connexion a échoué avec seulement ceci côté client :
Connection to server closed by remote host.
Connection closed
La vraie raison est dans le journal du serveur :
bad ownership or modes for chroot directory "/srv/sftp/sftpuser"
Testez d'abord depuis un ordinateur
$ 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.
Une connexion avec shell doit échouer, avec This service allows sftp connections only. Dans le même essai, scp vers /uploads a fonctionné, car il utilise SFTP, et rsync a échoué, car il doit exécuter un programme sur le serveur. Voir scp, SFTP ou rsync.
Une limite : l'utilisateur possède .ssh dans le chroot, donc quiconque détient cette clé peut lire ou modifier authorized_keys. Cela ne lui donne ni shell ni accès hors du dossier, mais il pourrait ajouter une autre clé pour ce compte. Si cela vous importe, réglez AuthorizedKeysFile dans le bloc Match sur un chemin hors du chroot.


Questions
L'app Fichiers de l'iPhone peut-elle se connecter à un serveur SFTP ?
Non. Se connecter au serveur, dans Fichiers, sert aux serveurs de partage comme SMB, pas à SFTP. Pour joindre un serveur en SSH, il faut une app cliente SFTP.
Quel port utilise SFTP ?
Le port SSH, 22 sauf réglage contraire du serveur, car SFTP passe dans une connexion SSH.
Pourquoi un utilisateur SFTP seul reçoit-il Connection closed juste après la connexion ?
En général, les dossiers du chroot ont le mauvais propriétaire. Chaque dossier jusqu'au chroot doit appartenir à root et ne pas être modifiable par les autres, et le journal du serveur indique bad ownership or modes for chroot directory.
Sources
- sshd_config(5) : ChrootDirectory, ForceCommand, Subsystem, manuel OpenBSD
- sftp(1), manuel OpenBSD
- Se connecter à des serveurs ou des appareils externes avec Fichiers sur l'iPhone, Assistance Apple