La app Archivos u otra app
La app Archivos tiene un comando Conectarse al servidor, pero es para servidores de archivos compartidos como los recursos SMB. No ofrece SFTP, así que para llegar a un servidor por SSH necesitas una app cliente de SFTP.
Las apps se integran de forma distinta con Archivos. Algunas añaden su propia ubicación, y entonces puedes explorar el servidor desde dentro de Archivos. Otras guardan las descargas en una carpeta propia, que aparece en En mi iPhone. Comprueba cuál obtienes, porque de eso depende cómo abres un archivo en otras apps.
Qué buscar en una app
- Acceso con clave, con claves Ed25519 y frase de contraseña.
- Comprobación de la clave de host, con un aviso que detenga la conexión cuando la clave cambia.
- Subidas desde Fotos y Archivos, ya que ahí es donde viven los archivos del móvil.
- Comportamiento en segundo plano. iOS puede suspender una app que sale de la pantalla, así que una transferencia grande puede detenerse. Averigua qué hace la app y prueba con un archivo grande.
- Reanudación, para que una subida fallida con mala cobertura no tenga que empezar de nuevo.
- Dónde guarda los secretos, y si tiene bloqueo de la app.
Qué necesita SFTP en el servidor
SFTP funciona dentro de SSH, así que si SSH funciona solo necesitas una cosa más, el subsistema sftp. Compruébalo:
sudo sshd -T | grep -i '^subsystem'
En Debian esto imprime subsystem sftp /usr/lib/openssh/sftp-server. Si no aparece nada, los clientes SFTP fallan así:
subsystem request failed on channel 0
Connection closed
Para arreglarlo, añade Subsystem sftp internal-sftp a sshd_config y recarga sshd. Para llegar a un servidor privado desde el móvil, consulta SSH desde un iPhone. Es el mismo camino de red.
Un usuario que solo puede usar SFTP en una carpeta
Tu teléfono no necesita un shell en el servidor para subir fotos. Un usuario dedicado limita el daño si se pierde el teléfono o su clave. Crea el grupo, el usuario y las carpetas:
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
Coloca la clave pública del teléfono, desde un archivo que hayas copiado al servidor:
sudo install -m 600 -o sftpuser -g sftponly iphone.pub /srv/sftp/sftpuser/.ssh/authorized_keys
¿Aún no tienes un par de claves? Consulta cómo generar una clave SSH Ed25519.
Luego crea /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 tu sistema no tiene sshd_config.d, pon el bloque al final de todo de sshd_config, porque un bloque Match allí se aplica hasta el final del archivo. Compruébalo y recarga:
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
El segundo comando debe imprimir forcecommand internal-sftp y chrootdirectory %h, con mayúsculas, como ForceCommand, desde OpenSSH 10.4. Vuelve a ejecutarlo con otro nombre de usuario para comprobar que los demás siguen mostrando none. En Fedora y RHEL el servicio se llama sshd.
La regla de propiedad
Esto es lo que hace tropezar a casi todo el mundo. Cada carpeta de la ruta del chroot, hasta el propio chroot incluido, debe pertenecer a root y no ser escribible por el grupo ni por otros. Por eso el usuario no puede escribir directamente en su carpeta superior, y por eso existe uploads.
Cuando dimos la carpeta superior al usuario, el inicio de sesión falló y en el cliente solo salía esto:
Connection to server closed by remote host.
Connection closed
La razón real está en el registro del servidor:
bad ownership or modes for chroot directory "/srv/sftp/sftpuser"
Pruébalo primero desde un ordenador
$ 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.
Un inicio de sesión con shell debe fallar, con This service allows sftp connections only. En la misma prueba, scp hacia /uploads funcionó, porque usa SFTP, y rsync falló, porque necesita ejecutar un programa en el servidor. Consulta scp, SFTP o rsync.
Un límite: el usuario es dueño de .ssh dentro del chroot, así que quien tenga esa clave puede leer o cambiar authorized_keys. Eso no le da un shell ni acceso fuera de la carpeta, pero podría añadir otra clave para esta cuenta. Si te importa, pon AuthorizedKeysFile en el bloque Match con una ruta fuera del chroot.


Preguntas
¿La app Archivos del iPhone se conecta a un servidor SFTP?
No. Conectarse al servidor, en Archivos, es para servidores de archivos compartidos como SMB, no para SFTP. Para llegar a un servidor por SSH necesitas una app cliente de SFTP.
¿Qué puerto usa SFTP?
El puerto de SSH, el 22 salvo que el servidor diga otra cosa, porque SFTP va dentro de una conexión SSH.
¿Por qué un usuario solo SFTP recibe Connection closed justo después de entrar?
Normalmente las carpetas del chroot tienen el dueño equivocado. Cada carpeta hasta el chroot debe ser de root y sin escritura para otros, y el log del servidor dice bad ownership or modes for chroot directory.
Fuentes
- sshd_config(5): ChrootDirectory, ForceCommand, Subsystem, manual de OpenBSD
- sftp(1), manual de OpenBSD
- Conectar con servidores o dispositivos externos en la app Archivos del iPhone, Soporte de Apple