Mover archivos a un servidor con FTP simple significa enviar nombres de usuario, contraseñas y datos por la red en texto claro. SFTP soluciona eso, y si tu servidor Linux ya ejecuta SSH, estás a la mayor parte del camino para tenerlo.

SFTP (SSH File Transfer Protocol) transfiere archivos a través de una conexión SSH cifrada. A pesar del nombre parecido, no es FTP con seguridad añadida: es un protocolo aparte que funciona en un solo puerto (22), lo que lo hace mucho más fácil de proteger con un firewall que FTP.

Esta guía muestra cómo configurar un servidor SFTP en Linux con OpenSSH, crear un usuario restringido que solo pueda acceder a su propia carpeta y, opcionalmente, reforzarlo con llaves SSH. Los comandos usan Ubuntu/Debian, con notas para los sistemas basados en RHEL cuando difieren.

¿Por Qué Usar SFTP en Lugar de FTP?

  • Cifrado por defecto. Las credenciales y el contenido de los archivos están protegidos en tránsito.
  • Un solo puerto. Solo hay que abrir el puerto 22, sin rangos de puertos pasivos que administrar.
  • Construido sobre SSH. Obtienes las mismas opciones de autenticación, incluidas las llaves SSH.
  • Sin software de servidor adicional. OpenSSH ya incluye un subsistema SFTP.

Paso 1: Instala y Habilita OpenSSH

La mayoría de los servidores ya tienen OpenSSH. Si el tuyo no, instálalo:

sudo apt update
sudo apt install openssh-server

En RHEL, Rocky o AlmaLinux:

sudo dnf install openssh-server

Asegúrate de que el servicio esté en ejecución y se inicie al arrancar (el servicio se llama ssh en Ubuntu/Debian y sshd en los sistemas basados en RHEL):

sudo systemctl enable --now ssh
sudo systemctl status ssh

Paso 2: Crea un Grupo y un Usuario para SFTP

En lugar de configurar cada usuario individualmente, crea un grupo y aplica las reglas de SFTP a todos los miembros:

sudo groupadd sftpusers

Crea un usuario sin acceso a shell, para que pueda transferir archivos pero no iniciar sesión en una terminal:

sudo useradd -m -G sftpusers -s /usr/sbin/nologin sftpuser
sudo passwd sftpuser

La opción -s /usr/sbin/nologin bloquea los inicios de sesión interactivos en shell, mientras que SFTP sigue funcionando porque lo maneja el propio demonio de SSH.

Paso 3: Crea la Estructura de Directorios Chroot

Una “jaula” chroot confina al usuario a un directorio específico para que no pueda explorar el resto del sistema de archivos. OpenSSH tiene un requisito estricto aquí: el directorio chroot y todos sus directorios padre deben ser propiedad de root y no ser modificables por nadie más. El usuario no puede escribir en la raíz de la jaula, así que creas una subcarpeta con permiso de escritura dentro de ella.

sudo mkdir -p /srv/sftp/sftpuser/uploads
sudo chown root:root /srv/sftp /srv/sftp/sftpuser
sudo chmod 755 /srv/sftp /srv/sftp/sftpuser
sudo chown sftpuser:sftpusers /srv/sftp/sftpuser/uploads
sudo chmod 755 /srv/sftp/sftpuser/uploads

Cuando sftpuser se conecta, aterriza en su jaula y ve solo una carpeta uploads, que es donde puede leer y escribir archivos.

Paso 4: Configura el Demonio de SSH

Abre la configuración del servidor SSH:

sudo nano /etc/ssh/sshd_config

Busca la línea que comienza con Subsystem sftp y cámbiala para que use el servidor SFTP interno, algo necesario para que chroot funcione sin copiar binarios dentro de la jaula:

Subsystem sftp internal-sftp

Luego agrega este bloque al final del archivo:

Match Group sftpusers
    ChrootDirectory /srv/sftp/%u
    ForceCommand internal-sftp
    X11Forwarding no
    AllowTcpForwarding no

Qué hace cada línea:

  • Match Group sftpusers aplica los siguientes ajustes solo a los miembros de ese grupo.
  • ChrootDirectory /srv/sftp/%u enjaula al usuario en una carpeta con el nombre de su usuario (%u).
  • ForceCommand internal-sftp permite únicamente SFTP y rechaza cualquier otro comando.
  • X11Forwarding no / AllowTcpForwarding no desactivan funciones que un usuario solo de SFTP no necesita.

Como un bloque Match se aplica hasta el siguiente Match o hasta el final del archivo, mantenlo siempre al final.

Paso 5: Prueba la Configuración y Reinicia SSH

Revisa el archivo en busca de errores de sintaxis antes de reiniciar. Un error de escritura aquí podría dejarte fuera del servidor:

sudo sshd -t

Que no haya salida significa que la configuración es válida. Luego reinicia el servicio:

sudo systemctl restart ssh

Mantén abierta tu sesión SSH actual mientras pruebas desde una segunda terminal, para poder corregir cualquier error.

Paso 6: Abre el Firewall

Si usas UFW y SSH ya está permitido, no se necesita nada más. De lo contrario:

sudo ufw allow 22/tcp

En sistemas basados en RHEL con firewalld:

sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

Paso 7: Conéctate y Prueba

Desde otra máquina, conéctate con el cliente de línea de comandos:

sftp sftpuser@your-server-ip

Una vez conectado, prueba algunos comandos:

sftp> pwd
Remote working directory: /
sftp> cd uploads
sftp> put report.pdf
sftp> ls
sftp> get report.pdf
sftp> exit

El usuario enjaulado ve / como su raíz, que en realidad es /srv/sftp/sftpuser en el servidor. Si prefieres un cliente gráfico, FileZilla, WinSCP y Cyberduck admiten SFTP. Elige el protocolo SFTP y el puerto 22.

Opcional: Usa Llaves SSH en Lugar de Contraseñas

La autenticación con llaves es más segura que las contraseñas y evita los intentos de inicio de sesión por fuerza bruta. En tu máquina cliente, genera un par de llaves:

ssh-keygen -t ed25519 -C "sftpuser"

Copia la llave pública al servidor:

ssh-copy-id sftpuser@your-server-ip

ssh-copy-id necesita el inicio de sesión con contraseña para funcionar la primera vez, y escribe en el directorio personal real del usuario (/home/sftpuser/.ssh/authorized_keys), no en la jaula. Eso funciona bien, porque sshd lee el archivo de llaves antes de aplicar el chroot.

Una vez que el inicio de sesión con llave funcione, puedes deshabilitar las contraseñas para el grupo SFTP agregando esta línea dentro del bloque Match Group sftpusers:

PasswordAuthentication no

Ejecuta sudo sshd -t y reinicia SSH otra vez.

Solución de Problemas Comunes de SFTP

  • “Broken pipe” o la conexión se cierra justo después de iniciar sesión. Casi siempre es un problema de permisos del chroot. Verifica que /srv/sftp y /srv/sftp/sftpuser sean propiedad de root:root y no tengan permiso de escritura para el grupo ni para todos.
  • “Permission denied” al subir archivos. El usuario no puede escribir en la raíz de la jaula. Sube los archivos a la subcarpeta uploads y confirma que pertenezca al usuario.
  • El inicio de sesión funciona pero el usuario obtiene un prompt de shell. El bloque Match Group no se está aplicando. Revisa que el usuario esté en el grupo (groups sftpuser) y que el bloque esté al final de sshd_config.
  • Los cambios no tienen efecto. Confirma que reiniciaste el servicio y que sshd -t pase. Revisa los registros con sudo journalctl -u ssh -e (o /var/log/auth.log en sistemas basados en Debian).
  • “Connection refused”. Revisa que el servicio esté en ejecución y que el firewall permita el puerto 22.

Consejos de Seguridad

  • Deshabilita el inicio de sesión de root por SSH con PermitRootLogin no.
  • Prefiere las llaves SSH a las contraseñas y considera fail2ban para bloquear los inicios de sesión fallidos repetidos.
  • Dale a cada usuario su propio directorio de jaula para que no puedan ver los archivos de los demás.
  • Mantén OpenSSH actualizado con ejecuciones periódicas de apt upgrade o dnf update.

Conclusión

Configurar un servidor SFTP en Linux toma solo unos minutos porque OpenSSH ya hace el trabajo pesado. Crea un grupo y un usuario dedicados, construye un directorio chroot propiedad de root con una subcarpeta con permiso de escritura, agrega un bloque Match Group a sshd_config y reinicia el servicio. El resultado es un servicio de transferencia de archivos cifrado que mantiene a cada usuario confinado a su propia carpeta.

A partir de ahí, agrega llaves SSH, endurece las reglas de tu firewall y monitorea tus registros, y tendrás una configuración de transferencia de archivos mucho más segura que el FTP tradicional, sin software adicional que mantener.