¿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 (consulta nuestra guía de chmod y chown para profundizar en permisos Linux):
# 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. Para más sobre escritura de scripts robustos, revisa nuestra guía de shell scripting.
Técnicas avanzadas
Reenvío de agente SSH (ForwardAgent)
Cuando necesitas hacer SSH desde un servidor bastión a un servidor interno, no deberías almacenar claves privadas en el bastión. El reenvío de agente permite que los servidores internos usen tu clave local a través del túnel.
# ~/.ssh/config
Host bastion
HostName bastion.example.com
User admin
ForwardAgent yes
Host internal-*
User deploy
ProxyJump bastion
ForwardAgent yes
# Conectar a través del bastión al interno, luego git pull funciona
ssh internal-web
git pull # tu clave local se reenvía, así que la autenticación tiene éxito
Nota de seguridad: Solo configura ForwardAgent yes para servidores en los que confíes. Cualquiera con acceso root en el bastión puede acceder a tu socket de agente y usar tus claves. Nunca lo configures globalmente con Host * — especifícalo explícitamente por host.
Reanudación y progreso de rsync (-P)
Al transferir archivos grandes por conexiones inestables, -P te permite reanudar desde donde te quedaste.
# -P es atajo para --partial --progress
rsync -avzP user@server:/data/large-dump.sql.gz ./backups/
--partial mantiene los archivos parcialmente transferidos en lugar de eliminarlos (comportamiento por defecto). La siguiente ejecución de rsync transfiere solo la porción restante. --progress muestra el progreso de la transferencia en tiempo real.
# Sincronizar archivos grandes con parciales almacenados en un directorio oculto
rsync -avzP --partial-dir=.rsync-partial user@server:/data/ ./local-data/
--partial-dir almacena archivos incompletos en un directorio separado, limpiado automáticamente después de completar la transferencia. Mantiene tu directorio de trabajo limpio.
Limitación de ancho de banda en rsync (--bwlimit)
Evita que transferencias grandes saturen la red en servidores de producción.
# Limitar ancho de banda a 5MB/s
rsync -avz --bwlimit=5000 ./release/ user@production:/app/
# Moderado durante horario laboral
rsync -avz --bwlimit=1000 ./data/ user@server:/backup/
--bwlimit está en KBytes/s. 5000 = aproximadamente 5MB/s. Añadirlo a scripts de despliegue previene el problema de "el sitio se puso lento después del deploy".
Montar sistemas de archivos remotos con sshfs
Monta el directorio de un servidor remoto localmente y trabaja con los archivos como si estuvieran en tu máquina. sshfs usa SFTP internamente.
# Montar directorio remoto
mkdir -p ~/mnt/server
sshfs user@server:/var/www ~/mnt/server
# Editar archivos con tu editor local
code ~/mnt/server/index.html
# Desmontar
fusermount -u ~/mnt/server
Tu configuración de ~/.ssh/config se usa automáticamente, así que sshfs myserver:/var/www ~/mnt/server funciona con nombres cortos de host.
Ten en cuenta que sshfs se ve directamente afectado por la latencia de red, así que no es ideal para operaciones masivas de archivos. Es más adecuado para verificar archivos de configuración o ediciones pequeñas.
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 (
mlkem768x25519-sha256) habilitado por defecto, proporcionando protección preventiva contra amenazas de computación cuántica
CVE-2025-26465 (ataque MITM)
Una vulnerabilidad descubierta por Qualys TRU en OpenSSH 6.8p1 hasta 9.9p1 permitía ataques man-in-the-middle cuando VerifyHostKeyDNS estaba habilitado. Corregido en 9.9p2 (febrero 2025). Ten en cuenta que VerifyHostKeyDNS está deshabilitado por defecto, así que solo afecta a usuarios que lo habilitaron explícitamente.
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ó seis CVEs críticos descubiertos por investigadores de Google Cloud, incluyendo CVE-2024-12084 (desbordamiento de búfer heap que permite ejecución remota de código). 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
Preguntas frecuentes
¿La autenticación por clave SSH es más segura que la de contraseña?
Significativamente más segura. La autenticación por contraseña es vulnerable a ataques de fuerza bruta y phishing. La autenticación por clave usa pares de claves criptográficas — sin el archivo de clave privada, el login es matemáticamente imposible. Los servidores de producción siempre deberían deshabilitar la autenticación por contraseña una vez configurada la autenticación por clave.
¿Puedo usar la misma clave SSH para múltiples servidores?
Sí. Copias la misma clave pública (~/.ssh/id_ed25519.pub) al ~/.ssh/authorized_keys de cada servidor. Sin embargo, algunos equipos con alta conciencia de seguridad prefieren claves separadas por entorno (por ejemplo, una para producción, otra para desarrollo) para limitar el radio de impacto si una clave se compromete.
¿Cómo soluciono errores "Permission denied (publickey)"?
Revisa en orden: (1) Asegúrate de que ~/.ssh sea 700 y ~/.ssh/authorized_keys sea 600 en el servidor. (2) Verifica que la clave pública correcta esté en authorized_keys. (3) Confirma que PubkeyAuthentication yes esté en sshd_config. (4) Revisa la salida de ssh -vvv user@server para ver la razón específica del rechazo.
¿Cuál es la diferencia entre scp y rsync?
scp copia archivos completos cada vez, mientras que rsync transfiere solo las partes que cambiaron (transferencia delta). rsync también soporta reanudación tras interrupción (--partial), compresión (-z), patrones de exclusión (--exclude) y espejado (--delete). Para cualquier cosa más allá de una copia rápida puntual, rsync es la mejor opción.
¿La barra final en rsync realmente importa?
Sí, y confundirla es uno de los errores más comunes con rsync. rsync -avz src/ dest/ copia el contenido de src en dest. Pero rsync -avz src dest/ copia src como directorio dentro de dest/src/. Siempre haz dry-run con -n si no estás seguro.
¿Puede rsync funcionar con un puerto SSH no estándar?
Sí. Usa el flag -e: rsync -avz -e 'ssh -p 2222' ./files/ user@server:/data/. Si ya configuraste el puerto en ~/.ssh/config, rsync lo detecta automáticamente cuando usas el alias del hostname.
¿Es seguro usar ForwardAgent?
Solo para servidores en los que confíes plenamente. Cuando ForwardAgent yes está activo, cualquiera con acceso root en ese servidor puede usar tu clave SSH reenviada para autenticarse como tú en otros servidores. Nunca lo configures globalmente con Host * — especifícalo por host, y solo para servidores bastión o servidores CI bajo tu control.
Artículos relacionados
- Guía de seguridad SSH: de la autenticación por clave al acceso solo por VPN — hardening SSH en profundidad, más allá de lo cubierto en este artículo
- Guía completa de curl — a menudo necesitarás hacer peticiones API en servidores remotos con curl
- Guía práctica de tmux — esencial para mantener sesiones durante conexiones SSH
- Guía práctica de chmod y chown — entender los permisos Linux que SSH exige
- Guía de shell scripting — escribe scripts de despliegue que usen rsync
- Dotfiles y variables de entorno — gestiona tu
~/.ssh/configjunto con otros dotfiles - Kit de herramientas CLI — el panorama general de herramientas CLI y cuándo usar cada una
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.