Lo que ves
$ sftp user@server
subsystem request failed on channel 0
Connection closed
scp usa el mismo servicio desde OpenSSH 9.0, así que también falla:
subsystem request failed on channel 0
scp: Connection closed
Un ssh user@server normal sigue funcionando, porque solo falta la parte de SFTP.
Comprueba el servidor
sudo sshd -T | grep -i '^subsystem'
Si no sale nada, no hay ningún subsistema definido, que es el comportamiento por defecto de OpenSSH cuando falta la línea. Suele pasar después de que alguien sustituye sshd_config por una versión corta y endurecida, o cuando la línea estaba comentada. sshd -t no te avisa de esto.
La solución
Añade una de estas líneas a /etc/ssh/sshd_config, fuera de cualquier bloque Match. La primera ejecuta SFTP dentro de sshd y no necesita un programa aparte:
Subsystem sftp internal-sftp
O la forma clásica, con la ruta de tu sistema:
Subsystem sftp /usr/lib/openssh/sftp-server
Rutas habituales:
| Sistema | Ruta de sftp-server |
|---|---|
| Debian, Ubuntu | /usr/lib/openssh/sftp-server |
| RHEL, Fedora, Rocky, Alma | /usr/libexec/openssh/sftp-server |
| Alpine | /usr/lib/ssh/sftp-server, del paquete openssh-sftp-server |
Después valida y recarga. El servicio es ssh en Debian y Ubuntu y sshd en los sistemas del estilo Red Hat:
sudo sshd -t && sudo systemctl reload ssh
Mantén abierta tu sesión actual hasta que un acceso nuevo funcione.
Con la línea en su sitio, sftp funciona como siempre. Para el uso diario, consulta los comandos de sftp con ejemplos.
En un NAS o un router
Estos equipos activan SFTP en sus propios ajustes, no en sshd_config. En un NAS Synology, activa el servicio SFTP en Panel de control, Servicios de archivos, FTP. En OpenWrt, SFTP necesita el paquete openssh-sftp-server.
Una alternativa cuando no puedes cambiar el servidor
Para copiar archivos, dile a scp que use el protocolo antiguo, que no necesita subsistema:
scp -O file.txt user@server:/tmp/
También puedes enviar los datos por una tubería sobre SSH normal, ya que el acceso en sí funciona:
tar -cf - folder | ssh user@server 'tar -xf - -C /tmp'
Mensajes parecidos con otras causas
La ruta es incorrecta
Cuando la línea existe pero el programa no está ahí, la petición del subsistema tiene éxito y después el programa no arranca. No ves el mensaje del subsistema, solo esto:
Connection closed.
Connection closed
sshd -t no comprueba la ruta, así que prueba el archivo en el servidor:
sudo sshd -T | grep -i '^subsystem'
ls -l /usr/lib/openssh/sftp-server
Corrige la ruta, instala el paquete que falta o cambia a internal-sftp.
El shell imprime algo
Received message too long 1466264675
Ensure the remote shell produces no output for non-interactive sessions.
SFTP lee los primeros bytes de la salida como una longitud binaria, así que cualquier texto del shell lo rompe. En este mensaje, esos números tan grandes son las letras del texto leídas como un número. Comprueba si hay salida:
ssh user@server /bin/true | wc -c
Cualquier valor distinto de 0 significa que un archivo de arranque como ~/.bashrc está imprimiendo. Pon esto al principio de ese archivo para que el resto solo se ejecute en shells interactivos:
case $- in
*i*) ;;
*) return ;;
esac
La cuenta tiene un shell nologin o un comando forzado
Aquí aparece el mismo error Received message too long, porque nologin o un ForceCommand imprimen texto. Para un usuario nologin, internal-sftp funcionó en nuestra prueba, ya que no inicia el shell del usuario. Con un ForceCommand, cambia el ajuste para que no se aplique a los usuarios de SFTP, o ponlo en internal-sftp para ellos.
Preguntas
¿Qué significa subsystem request failed on channel 0?
El acceso funcionó, pero el servidor no tiene un servicio SFTP configurado. Añade Subsystem sftp internal-sftp a sshd_config y recarga SSH.
¿Por qué funciona ssh y no sftp?
ssh solo necesita una shell, mientras que sftp también pide al servidor que arranque su subsistema SFTP. Si falta la línea Subsystem o apunta a una ruta errónea, solo fallan las transferencias de archivos.
¿scp necesita el subsistema SFTP?
Desde OpenSSH 9.0, sí, así que falla igual. scp -O usa el protocolo antiguo, que funciona sin él.