¿Cansado de escribir contraseñas cada vez que te conectas por SSH a un servidor? ¿Necesitas enviar archivos a producción pero scp se siente dolorosamente lento? ¿Quieres acceder a un servidor de desarrollo remoto desde tu máquina local?
La respuesta es ssh y rsync. ssh proporciona conexiones remotas cifradas, y rsync maneja la sincronización eficiente de archivos transfiriendo solo lo que ha cambiado. Juntos, forman la base de la administración de servidores y los flujos de trabajo de despliegue.
Esta guía te lleva a través de la configuración de autenticación por clave, ajuste de archivos de configuración, reenvío de puertos y patrones de respaldo con rsync — todo con comandos listos para ejecutar.
¿Qué es SSH?
ssh (Secure Shell) es un protocolo y comando para operar máquinas remotas de forma segura a través de una red. Toda la comunicación está cifrada, así que las contraseñas y comandos nunca viajan en texto plano.
Su predecesor, telnet, enviaba todo sin cifrar. ssh lo reemplazó en 1995 y se ha convertido en el estándar de facto para la administración de servidores.
ssh hace mucho más que solo login remoto:
- Ejecución remota de comandos: ejecuta one-liners como
ssh user@server "ls -la /var/log" - Transferencia de archivos: transferencias cifradas vía scp y sftp
- Reenvío de puertos: crea túneles entre puertos locales y remotos
- Tunneling: úsalo como proxy SOCKS para funcionalidad similar a una VPN
La conexión básica es directa:
ssh user@192.168.1.100
Para especificar un puerto, usa -p:
ssh -p 2222 user@192.168.1.100
Configurar la autenticación por clave
ssh soporta dos métodos principales de autenticación: basada en contraseña y basada en clave.
Autenticación por contraseña requiere ingresar una contraseña en cada conexión. Es simple pero débil — vulnerable a ataques de fuerza bruta, y si la contraseña se filtra, todo está perdido.
Autenticación por clave usa un par de claves pública-privada. Sin la clave privada, el login es imposible, haciendo ineficaces los ataques de fuerza bruta. Para servidores de producción, la autenticación por clave es esencialmente obligatoria.
Generar claves
El estándar en 2026 es Ed25519. Proporciona seguridad igual o mejor que RSA con longitudes de clave más cortas, y firma y verificación más rápidas.
ssh-keygen -t ed25519 -C "your_email@example.com"
Se te pedirá una ubicación para guardar y una frase de paso. Establecer una frase de paso es altamente recomendable — es la última línea de defensa si tu clave privada se ve comprometida.
Si necesitas RSA por compatibilidad con servidores antiguos, usa al menos 4096 bits:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Copiar tu clave pública al servidor
El método más fácil es ssh-copy-id:
ssh-copy-id user@server
Esto añade tu clave pública local (~/.ssh/id_ed25519.pub) al ~/.ssh/authorized_keys del servidor.
Si ssh-copy-id no está disponible, hazlo manualmente:
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Establecer permisos
ssh es estricto con los permisos. La autenticación por clave puede ser rechazada si estos no están configurados correctamente:
# Lado del servidor
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# Lado del cliente
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
Gestionar claves con ssh-agent
Si estableciste una frase de paso en tu clave, ingresarla en cada conexión se vuelve tedioso. Registra tu clave con ssh-agent para omitir las peticiones de frase de paso durante la sesión:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
El archivo ssh config
~/.ssh/config almacena parámetros de conexión para que no tengas que escribirlos cada vez.
Sintaxis básica
Host myserver
HostName 192.168.1.100
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
Ahora ssh myserver es equivalente a ssh -p 2222 -i ~/.ssh/id_ed25519 deploy@192.168.1.100.
Comodines
Aplica configuraciones comunes a múltiples servidores:
Host *.example.com
User admin
IdentityFile ~/.ssh/id_ed25519_work
Keep-alive
Evita que las conexiones SSH inactivas se corten:
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
Esto envía una señal de keep-alive cada 60 segundos. Si el servidor no responde 3 veces, la conexión se termina.
SSH multi-salto (ProxyJump)
Conectarse a través de un host bastión para llegar a servidores internos es un patrón común. ProxyJump lo maneja en un solo comando:
Host bastion
HostName bastion.example.com
User admin
Host internal
HostName 10.0.0.5
User deploy
ProxyJump bastion
ssh internal se enruta automáticamente a través del bastión para llegar al servidor interno.
Multiplexación de conexiones (ControlMaster)
Acelera las conexiones posteriores al mismo servidor. La primera conexión crea un socket, y las conexiones siguientes lo reusan:
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
Crea primero el directorio de sockets:
mkdir -p ~/.ssh/sockets
ControlPersist 600 mantiene el socket vivo durante 600 segundos después de cerrar la última conexión. Esto marca una diferencia notable en scripts de despliegue que se conectan al mismo servidor repetidamente.
Reenvío de puertos
El reenvío de puertos SSH crea túneles cifrados para retransmitir tráfico entre puertos. Es invaluable para acceder a servicios detrás de firewalls o exponer servicios locales externamente.
Reenvío local (-L)
Reenvía un puerto remoto a tu máquina local. Este es el patrón más común:
ssh -L 8080:localhost:3000 user@server
Accede a localhost:8080 en tu máquina, y el tráfico se reenvía a localhost:3000 en el servidor remoto. Úsalo cuando necesites alcanzar un servidor de desarrollo remoto o panel de administración desde tu navegador local.
Ejemplo práctico: conectar a una instancia PostgreSQL remota
ssh -L 5433:localhost:5432 user@db-server
En otra terminal:
psql -h localhost -p 5433 -U myuser mydb
Puedes conectarte al PostgreSQL remoto como si estuviera corriendo localmente. Combina con tmux para gestionar múltiples terminales.
Reenvío remoto (-R)
Expón un puerto local a través del servidor remoto:
ssh -R 8080:localhost:3000 user@server
Accede a localhost:8080 en el servidor remoto, y el tráfico se reenvía a localhost:3000 en tu máquina. Útil para mostrar una aplicación de desarrollo local a tu equipo.
Reenvío dinámico (-D)
Crea un proxy SOCKS:
ssh -D 1080 user@server
Configura localhost:1080 como proxy SOCKS de tu navegador, y todo el tráfico se enruta a través del túnel SSH. Útil para cifrar tráfico en WiFi público o acceder a servicios con restricción geográfica.
Ejecutar túneles en segundo plano
Si solo necesitas el reenvío y no necesitas un shell, usa -fN:
ssh -fNL 8080:localhost:3000 user@server
-f ejecuta ssh en segundo plano, -N le dice que no ejecute comandos remotos.
¿Qué es rsync?
rsync es una herramienta de sincronización de archivos especializada en transferencias delta. Detecta qué partes de los archivos han cambiado y transfiere solo esas partes, haciendo que las sincronizaciones posteriores sean dramáticamente más rápidas.
Así se compara con scp:
| Característica | scp | rsync |
|---|---|---|
| Modo de transferencia | Copia completa cada vez | Solo delta |
| Reanudación tras interrupción | No | Sí, con --partial |
| Compresión | No | Sí, con -z |
| Patrones de exclusión | No | --exclude flexible |
| Espejado | No | Sí, con --delete |
Para cualquier transferencia de archivos no trivial, rsync es el claro ganador.
Sintaxis básica:
rsync [opciones] origen destino
Opciones más usadas:
-a(archive): copia recursiva preservando permisos, marcas de tiempo y propiedad-v(verbose): mostrar nombres de archivos durante la transferencia-z(compress): comprimir datos de transferencia-n(dry-run): mostrar qué pasaría sin transferir realmente--progress: mostrar progreso de la transferencia
rsync en la práctica
Sincronización básica de archivos
Local a remoto:
rsync -avz ./dist/ user@server:/var/www/
Remoto a local:
rsync -avz user@server:/var/log/ ./logs/
Siempre haz un dry run primero. Solo añade -n:
rsync -avzn ./dist/ user@server:/var/www/
Patrones de exclusión
Excluir archivos o directorios específicos de la transferencia:
rsync -avz --exclude='node_modules' --exclude='.git' --exclude='.env' ./project/ user@server:/app/
Cuando tienes muchas exclusiones, ponlas en un archivo. Crea .rsyncignore:
node_modules
.git
.env
*.log
.DS_Store
Luego referéncialo con --exclude-from:
rsync -avz --exclude-from='.rsyncignore' ./project/ user@server:/app/
Respaldos
Respaldo espejo mantiene el destino como una copia exacta del origen. --delete elimina archivos del respaldo que ya no existen en el origen:
rsync -avz --delete /data/ /backup/data/
Respaldo generacional guarda archivos eliminados o modificados en un directorio con fecha:
rsync -avz --backup --backup-dir="/backup/$(date +%Y%m%d)" --delete /data/ /backup/current/
/backup/current/ siempre contiene el estado más reciente, mientras que los archivos eliminados y actualizados se preservan en directorios como /backup/20260308/.
Script de despliegue
Un ejemplo práctico de automatización del despliegue de una aplicación web con rsync:
#!/bin/bash
set -euo pipefail
REMOTE_USER="deploy"
REMOTE_HOST="server.example.com"
REMOTE_PATH="/var/www/myapp"
LOCAL_PATH="./dist/"
echo "Iniciando despliegue a ${REMOTE_HOST}..."
rsync -avz --delete \
--exclude='.git' \
--exclude='node_modules' \
--exclude='.env' \
--exclude='*.log' \
"${LOCAL_PATH}" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/"
echo "Despliegue completado."
set -euo pipefail es esencial para el manejo de errores en scripts — detiene la ejecución tan pronto como cualquier comando falla.
Consideraciones de seguridad
La seguridad SSH y la seguridad del servidor van de la mano. Aquí está lo mínimo que deberías estar haciendo.
Cambios clave en OpenSSH 10.0
OpenSSH 10.0 (abril 2025) introdujo cambios de seguridad significativos:
- DSA eliminado completamente: las claves DSA ya no pueden generarse ni usarse. Migra a Ed25519
- Soporte ML-KEM: algoritmo de intercambio de claves post-cuántico (ML-KEM) habilitado por defecto, proporcionando protección preventiva contra amenazas de computación cuántica
CVE-2025-26465 (ataque MITM)
Una vulnerabilidad en OpenSSH 9.9p1 y anteriores permitía ataques man-in-the-middle cuando VerifyHostKeyDNS estaba habilitado. Corregido en 9.9p2 y posteriores. Si usas VerifyHostKeyDNS, verifica tu versión.
Configuración recomendada de sshd_config
Configura /etc/ssh/sshd_config en el lado del servidor:
Solo establece PasswordAuthentication no después de que la autenticación por clave esté completamente funcionando. Hacerlo antes te deja fuera del servidor.
Seguridad de rsync
rsync 3.4.0 (enero 2025) corrigió múltiples CVEs críticos. Si estás ejecutando 3.3.x o anterior, actualiza inmediatamente. La versión 3.4.1 es un release de corrección de regresiones, así que 3.4.1 es el objetivo recomendado.
Verifica tu versión:
rsync --version
Firewall y fail2ban
Restringe el acceso al puerto SSH (por defecto: 22) por IP:
# Usando ufw
sudo ufw allow from 203.0.113.0/24 to any port 22
sudo ufw deny 22
fail2ban detecta intentos de login fallidos y bloquea automáticamente las IPs ofensoras. Es la defensa estándar contra ataques de fuerza bruta SSH:
sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Conclusión
ssh y rsync son la base del trabajo con servidores remotos. Autentícate de forma segura con claves, agiliza las conexiones con archivos de configuración y sincroniza archivos eficientemente con rsync.
Puntos clave:
- Usa claves Ed25519. DSA fue eliminado en OpenSSH 10.0
- Centraliza los parámetros de conexión en
~/.ssh/config. UsaProxyJumppara conexiones multi-salto - El reenvío de puertos te permite acceder a servicios remotos desde localhost
- Lo básico de rsync:
-avzpara la mayoría de operaciones. Siempre haz dry-run con-nprimero - La barra final cambia completamente el comportamiento de rsync — verifícala hasta que sea memoria muscular
- En el lado del servidor, establece
PasswordAuthentication noyPermitRootLogin no
Combina ssh con tmux para hacer el trabajo en terminal remoto significativamente más cómodo. Para la visión general completa del kit de herramientas CLI, consulta el Kit de herramientas CLI.