10 comandos SSH que todo administrador Linux debería conocer
Los 10 comandos SSH que todo administrador Linux debería conocer
SSH es la herramienta más usada por cualquier persona que trabaja con Linux en producción. Esta guía cubre los 10 comandos que realmente necesitas: conexiones, port forwarding, túneles, jump hosts y trucos que te ahorrarán horas.
—
TL;DR — Lo que vas a tener al final
- Tiempo de setup: 1-2 horas para un server nuevo.
- Requisitos: Acceso root, 2 sesiones SSH abiertas durante cambios.
- Resultado: Login por clave ed25519, fail2ban activo, 99% de ataques bloqueados.
- Troubleshooting: Consola del proveedor, journalctl -u sshd, fail2ban-client status.
Antes de empezar: tu primera conexión
Si SSH te suena a chino, abrí una terminal y ejecuta:
Te conecta a un host remoto y abre un shell interactivo en esa máquina. El argumento usuario@host le indica a SSH qué cuenta usar; si lo omitís, intenta con tu usuario local.
ssh [email protected]
Te pedirá la contraseña del usuario en esa máquina. Si ves Permission denied repetido, el problema es de credenciales — no de red. Si ves Connection refused, el puerto 22 está cerrado o el servicio SSH no está corriendo. Si ves Connection timed out, hay un firewall o routing roto entre tu laptop y el host.
Ahora sí, los 10 comandos.
—
1. ssh — Conexión básica con opciones útiles
El comando base, pero con flags que vale la pena memorizar:
Las cinco variantes que siguen cubren el 90% de los casos reales: puerto alternativo, identidad específica, modo debug, desactivación temporal de host key checking, y compresión. Cada flag está pensada para resolver un problema concreto: el -p cuando el server escucha en otro puerto (cada vez más común por seguridad), -i cuando manejas múltiples identidades, -vvv cuando algo no conecta y necesitas ver qué paso falla, -o StrictHostKeyChecking=no solo en escenarios automatizados donde regenerás el host (como clonar una VM), y -C cuando la red está lenta.
# Conectar a un puerto no estándar
ssh -p 2222 usuario@servidor
# Especificar identidad (clave privada)
ssh -i ~/.ssh/mi-clave.pem usuario@servidor
# Modo verbose (debug de conexión)
ssh -vvv usuario@servidor
# Desactivar comprobación de host key (NO recomendado)
ssh -o StrictHostKeyChecking=no usuario@servidor
# Comprimir la conexión (útil en redes lentas)
ssh -C usuario@servidor
El -vvv es tu mejor amigo cuando algo no conecta: te dice exactamente en qué paso falla (DNS, TCP, autenticación, etc.).
Atención con StrictHostKeyChecking=no: nunca lo uses contra hosts que ya tienen clave persistida en ~/.ssh/known_hosts, porque te hace perder protección contra MITM. Reservalo para VMs nuevas que regeneran host key en cada deploy.
—
2. ssh-keygen — Generar pares de claves
La base de la autenticación moderna en SSH. Genera un par clave pública/privada:
El comando crea dos archivos: una clave privada (la que vive en tu máquina, nunca se comparte) y una pública (la que va en el servidor en ~/.ssh/authorized_keys). El parámetro -t elige el algoritmo: rsa con -b 4096 para máxima compatibilidad, ed25519 para criptografía moderna más corta y rápida. La -f define dónde guardar el archivo y -C agrega un comentario (suele usarse el email para identificar la clave cuando la ves listada en el server).
# RSA clásico (compatible con todo)
ssh-keygen -t rsa -b 4096
# Ed25519 (más moderno, más rápido, más seguro)
ssh-keygen -t ed25519 -C "[email protected]"
# Con passphrase para más seguridad
ssh-keygen -t ed25519 -f ~/.ssh/id_servidor -C "servidor producción"
Tip: usa Ed25519 a menos que necesites compatibilidad con sistemas muy viejos. Es más corto, más rápido y más seguro que RSA.
Si te pregunta Enter passphrase y le das Enter sin escribir nada, la clave queda sin protección: cualquiera que robe el archivo entra al server. Si le das passphrase, vas a tener que tipearla cada vez que uses la clave (salvo que uses ssh-agent, que está más adelante en esta guía). Cuando ejecutes el segundo bloque con ssh-copy-id, vas a tener que tipear la contraseña del server la primera vez.
Después de generar la clave, copiá la pública al servidor:
Lo que hace este bloque es tomar la clave pública que generaste y ponerla en el archivo ~/.ssh/authorized_keys del usuario en el server, con los permisos correctos (700 para ~/.ssh y 600 para authorized_keys). SSH rechaza claves en archivos con permisos abiertos porque es un vector clásico de escalada. La versión larga con cat | ssh ... es útil cuando ssh-copy-id no está disponible en tu sistema (por ejemplo en Alpine o en containers minimalistas).
ssh-copy-id usuario@servidor
# o manualmente:
cat ~/.ssh/id_ed25519.pub | ssh usuario@servidor "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Si ves Permission denied (publickey) después de esto, casi siempre es problema de permisos: corré chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys en el server. Si sigue sin funcionar, revisa con ssh -vvv que la clave se está ofreciendo (tiene que aparecer en el debug).
—
3. ssh-copy-id — Copiar tu clave pública al servidor
Olvidate de pegar manualmente:
ssh-copy-id se conecta al server con tu contraseña (por única vez), crea el directorio ~/.ssh si no existe, copia la clave pública en authorized_keys y ajusta los permisos. La flag -i permite especificar qué clave subir cuando tienes varias en ~/.ssh/. La -p es para servers que escuchan en otro puerto.
ssh-copy-id -i ~/.ssh/id_ed25519.pub usuario@servidor
# Si el servidor usa otro puerto
ssh-copy-id -p 2222 -i ~/.ssh/id_ed25519.pub usuario@servidor
Este comando se conecta con contraseña, copia tu clave pública en ~/.ssh/authorized_keys con los permisos correctos. A partir de ahí, la próxima conexión ya no pedirá contraseña.
Si te tira ERROR: No identities found, es que el path que pasaste con -i no existe o el nombre está mal escrito. Listá las claves disponibles con ls ~/.ssh/*.pub. Si te tira Permission denied (password), el server tiene PasswordAuthentication no y no puedes copiar por este medio — vas a tener que pegar la clave manualmente con cat | ssh.
—
4. scp — Copiar archivos entre máquinas
El primo simple de rsync:
scp usa la misma autenticación y cifrado que SSH (porque corre sobre el protocolo SSH). La sintaxis es origen destino y siempre tienes que especificar usuario@host: cuando el archivo está del lado remoto. El flag -r es para copiar directorios enteros recursivamente, y -P (mayúscula) es para puerto alternativo — ojo que es mayúscula, mientras que en ssh es minúscula (-p). Esa diferencia histórica confunde a mucha gente.
# Local a remoto
scp archivo.txt usuario@servidor:/ruta/destino/
# Remoto a local
scp usuario@servidor:/ruta/archivo.log /tmp/
# Copiar un directorio completo (recursivo)
scp -r ./mi-proyecto usuario@servidor:/var/www/
# Con puerto personalizado
scp -P 2222 archivo.txt usuario@servidor:/tmp/
Ojo con -r en directorios grandes: scp no comprime por defecto, usa rsync -avz para transferencias grandes.
Si ves scp: ambiguous target, es que el destino tiene espacios o caracteres especiales y no los escapaste. Envolvelos entre comillas: scp archivo.zip usuario@servidor:"/var/backups/". Para archivos >100 MB o conexiones lentas, scp se cuelga a mitad de camino y no resume: ahí sí o sí rsync -avzP con -P (progress + partial).
—
5. rsync — Sincronización inteligente (la evolución de scp)
rsync solo transfiere las partes de los archivos que cambiaron. Imprescindible para backups y despliegues:
A diferencia de scp, rsync compara origen y destino antes de transferir: si el archivo ya está igual (mismo tamaño + mismo timestamp + mismo checksum), no lo copia. Esto hace que las sincronizaciones incrementales sean muchísimo más rápidas. Las flags -a (archive) preserva permisos, propietarios, symlinks y timestamps; -v muestra qué archivos transfiere; -z comprime en tránsito. Para copiar directorios, la sintaxis exige barra al final del origen (./carpeta/) para que copie el contenido, no la carpeta en sí.
# Sincronizar local → remoto (con compresión y verbose)
rsync -avz ./mi-carpeta/ usuario@servidor:/ruta/destino/
# Mantener permisos, timestamps, symlinks
rsync -avzP ./ usuario@servidor:/backup/
# Excluir archivos
rsync -avz --exclude='.git' --exclude='node_modules' ./ usuario@servidor:/deploy/
# Borrar archivos en destino que no existen en origen
rsync -avz --delete ./ usuario@servidor:/mirror/
El -a es archive: preserva permisos, propietarios, symlinks. -z comprime la transferencia. -P muestra progreso y permite reanudar.
--delete es la opción más peligrosa: si la borra y la fuente está vacía o incompleta, vacía el destino. Úsala solo cuando estés seguro de que la fuente es la fuente de verdad. Si la transferencia se interrumpe, rsync la retoma desde donde quedó (a diferencia de scp) gracias al -P o --partial. verifica el resultado con rsync -avzn --dry-run antes de cualquier deploy importante.
Para backups recurrentes, montá esto en cron:
Este es un cron job clásico: a las 3 AM todos los días, sincroniza /home/usuario/ con el directorio del usuario backup en el NAS, eliminando archivos que ya no existen en origen. El --delete mantiene el backup como espejo exacto. Editá tu crontab con crontab -e y verifica después con crontab -l que quedó bien guardado.
0 3 * * * rsync -avz --delete /home/usuario/ backup@nas:/backups/casa/
Si tu NAS no tiene usuario SSH dedicado, primero generá una clave con ssh-keygen en la máquina que corre el cron y copiala al NAS con ssh-copy-id backup@nas. Sin clave deployada, el cron va a fallar silenciosamente porque no puede pedir passphrase interactivamente. verifica que el cron corrió con grep CRON /var/log/syslog (en Debian/Ubuntu) o mirando los timestamps de los archivos en el NAS.
—
6. ssh -L — Local port forwarding (túneles inversos)
¿quieres acceder al puerto 80 de un server que solo es accesible desde tu server SSH? Túnel local:
-L abre un puerto en tu máquina local y todo lo que llegue ahí se reenvía, cifrado, al server SSH, que a su vez lo manda al destino final. La sintaxis es -L puerto_local:host_destino:puerto_destino. Es el caso de uso más útil para desarrollo: acceder a servicios internos sin exponerlos a internet. El túnel queda abierto mientras la sesión SSH esté activa.
# Acceder a puerto-remoto en destino, exponiéndolo en puerto-local
ssh -L 8080:localhost:80 usuario@servidor
# Ahora en tu navegador: http://localhost:8080 → ve al puerto 80 del servidor
Caso de uso real: tu Nextcloud corre en cloud.example.com:8080 y solo es accesible desde el propio server. Con -L puedes abrirlo temporalmente en tu laptop:
Mapeás el puerto 8080 interno del server en el 9000 de tu laptop. Mientras la sesión SSH esté abierta, http://localhost:9000 en tu navegador va a responder como si fueras el propio server. Cuando cierres la sesión (Ctrl+D o exit), el túnel desaparece.
ssh -L 9000:localhost:8080 [email protected]
# Abres http://localhost:9000 en tu navegador
Otro caso común: acceder a un servidor de bases de datos que solo escucha en localhost:
Patrón clásico para desarrollo: el Postgres de producción está en db-server y solo escucha en 127.0.0.1:5432 (no se expone a la red por seguridad). Con este túnel, tu app en tu laptop puede usar localhost:5432 como si el Postgres estuviera corriendo ahí. Sirve también para psql local, PgAdmin, DBeaver o cualquier cliente que use el puerto.
ssh -L 5432:localhost:5432 usuario@db-server
# Ahora tu app local puede usar localhost:5432 → llega al Postgres remoto
Si tu app ya usa el 5432 local para otro Postgres, cambiá el primer número a otro libre (ej: 55432:localhost:5432). Para mantener el túnel activo aunque la red parpadee, agregale -o ServerAliveInterval=60 -o ServerAliveCountMax=3 al comando SSH.
—
7. ssh -R — Remote port forwarding (exponer tu local al mundo)
Lo contrario: hacer que algo en tu máquina sea accesible desde el server remoto:
-R hace lo inverso a -L: abre un puerto en el server remoto y reenvía el tráfico a tu máquina local. Sirve para mostrarle a alguien algo que está corriendo en tu laptop sin que tengas que abrir puertos en tu router ni exponer tu IP pública. A diferencia de -L, este requiere configuración del lado del server: GatewayPorts yes en sshd_config (explicado más abajo).
ssh -R 8080:localhost:3000 usuario@servidor
# Ahora desde el servidor: curl http://localhost:8080 → ve tu puerto 3000 local
Caso de uso: estás desarrollando una web app en localhost:3000 y quieres mostrársela a un cliente. haz un túnel inverso a un server público y pasale la URL.
Si el cliente te dice “no carga”, lo más probable es que GatewayPorts esté en no (el default por seguridad): en ese caso SSH solo escucha en 127.0.0.1 del server, no en su IP pública. La solución es editar /etc/ssh/sshd_config en el server, agregar GatewayPorts yes y reiniciar sshd. Para evitar abrirle el server a todo internet, especificá un cliente: ssh -R 8080:localhost:3000 -o "PermitRemoteOpen=client.example.com:*" usuario@servidor.
Cuidado: para que -R funcione, el server SSH necesita tener GatewayPorts yes en /etc/ssh/sshd_config.
—
8. ssh -D — SOCKS proxy dinámico (tu VPN personal)
Crea un proxy SOCKS5 dinámico. Todo el tráfico de las aplicaciones que apunten a ese proxy pasa por el server SSH:
La flag -D abre un puerto SOCKS en tu máquina local. Cualquier aplicación que sepa usar SOCKS5 (navegador, Telegram, curl, SSH mismo) puede enrutar su tráfico a través del server SSH remoto. La diferencia con -L es que -D es dinámico: no mapeás un puerto específico, el cliente le dice al proxy a qué host conectar en cada request. Las flags combinadas -C -q -N son las típicas para un proxy “invisible”: -C comprime, -q silencia el banner, -N no abre shell remoto (solo mantiene el túnel).
ssh -D 1080 -C -q -N usuario@servidor
# -D puerto del proxy SOCKS
# -C comprimir
# -q quiet
# -N no ejecutar comando remoto
Luego configuras tu navegador o aplicación para usar SOCKS5 localhost:1080 como proxy. Todo el tráfico sale por el server remoto.
Si tu navegador es Firefox, andá a Settings → Network Settings → Manual proxy → SOCKS Host localhost, port 1080, marcar “Proxy DNS when using SOCKS v5” (clave: si no lo marcás, las DNS queries van por tu ISP y filtran qué visitás aunque el tráfico vaya cifrado). Para Chrome, lanzalo con --proxy-server="socks5://localhost:1080". Si el túnel se cae, todo el tráfico vuelve a salir directo — verifica con https://ifconfig.me que la IP que muestra sea la del server SSH, no la de tu ISP.
Caso de uso: estás en una WiFi pública (cafetería, aeropuerto) y quieres cifrar todo tu tráfico. Conectá al proxy SOCKS y ya nadie ve qué hacés.
—
9. ssh -J — Jump hosts (conectar a través de un bastion)
Si tu infra tiene un bastion host (el “puerta de entrada” a la red interna), SSH puede saltar automáticamente:
-J (JumpHost) le indica a SSH que primero se conecte al bastion, y desde ahí abra una segunda conexión al server final. Todo el tráfico va cifrado entre los tres puntos, y solo necesitas autenticarte en el bastion y en el destino. Si el bastion escucha en otro puerto o usa otra clave, puedes encadenar flags con -J.
# Conectar a servidor-interno pasando por bastion
ssh -J usuario@bastion usuario@servidor-interno
# Con clave específica para el jump
ssh -J usuario@bastion -i ~/.ssh/clave-interna.pem usuario@servidor-interno
Para hacerlo permanente, editá ~/.ssh/config (no requiere reiniciar nada, se lee en cada conexión):
Host bastion
HostName bastion.example.com
User admin
Host servidor-interno
HostName 10.0.0.5
User app
ProxyJump bastion
Host servidor-db
HostName 10.0.0.10
User postgres
ProxyJump bastion
Ahora puedes hacer ssh servidor-db directamente y SSH se encarga de los saltos.
—
10. ssh-agent y ssh-add — Gestión de claves con passphrase
Si usas passphrase (recomendado), no quieres escribirla cada vez. ssh-agent la recuerda por tú durante la sesión:
ssh-agent es un proceso de fondo que mantiene las claves descifradas en memoria. ssh-add las carga pidiéndote la passphrase una sola vez. Después, cualquier conexión SSH que use una clave cargada en el agente no te vuelve a pedir la passphrase. eval "$(ssh-agent -s)" arranca el agente y exporta las variables de entorno (SSH_AUTH_SOCK, SSH_AGENT_PID) en tu shell actual; si abres otra terminal, esas variables no están y tienes que re-evaluar o usar un mecanismo persistente (Keychain en macOS, systemd user service en Linux moderno).
# Iniciar el agente y guardar las variables de entorno
eval "$(ssh-agent -s)"
# Agregar tu clave (te pide la passphrase UNA vez)
ssh-add ~/.ssh/id_ed25519
ssh-add ~/.ssh/id_servidor_produccion
# Ver qué claves están cargadas
ssh-add -l
Para que se haga automáticamente al iniciar sesión, en macOS agregá a ~/.ssh/config:
AddKeysToAgent yes
UseKeychain yes
Nota: UseKeychain es una directiva exclusiva de macOS (no existe en OpenSSH estándar de Linux/BSD). En Linux moderno lo más cercano es configurar ssh-agent como systemd user service o usar keychain para persistir entre sesiones.
En Linux con bash, agregá a ~/.bashrc:
Este snippet detecta si ya hay un agente SSH corriendo en la sesión actual (chequeando $SSH_AUTH_SOCK). Si no hay, arranca uno nuevo con ssh-agent -s y carga la clave por defecto. Pegalo al final de tu .bashrc y la próxima vez que abras una terminal, el agente estará listo. Si tienes varias claves, agregá más líneas ssh-add ~/.ssh/....
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
fi
—
Bonus: El ~/.ssh/config que todo sysadmin debería tener
Este archivo te ahorra teclear lo mismo mil veces. Ejemplo completo:
# Defaults que aplican a todas las conexiones
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
Compression yes
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
# Servidor de desarrollo
Host dev
HostName dev.example.com
User developer
Port 2222
# Producción con jump host
Host prod
HostName 10.0.1.50
User deploy
ProxyJump [email protected]
# Servidor de bases de datos
Host db
HostName db-internal.example.com
User postgres
IdentityFile ~/.ssh/id_postgres
LocalForward 5432 localhost:5432
Con esto, ssh prod te lleva al servidor de producción pasando por el bastion, con keepalive automático, compresión, y la clave cargada en el agente.
—
Seguridad: 5 reglas innegociables
1. Desactiva el login con contraseña en servidores. Solo claves SSH.
# En /etc/ssh/sshd_config:
PasswordAuthentication no
2. Cambia el puerto por defecto (22) para reducir escaneos automáticos:
Port 2222
3. Desactiva el login de root:
PermitRootLogin no
4. Usa AllowUsers para limitar quién puede conectarse:
AllowUsers admin deploy app
5. Instala fail2ban para bloquear IPs que fallen muchos logins:
fail2ban lee logs de autenticación de SSH (y otros servicios) y aplica reglas de iptables/nftables para banear IPs que superen un umbral de intentos fallidos. La instalación por defecto en Debian/Ubuntu ya viene con un perfil razonable para SSH. El enable es clave: sin él, fail2ban no levanta en el próximo reboot.
sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
verifica que esté activo con sudo fail2ban-client status sshd (debería mostrar 0 jail y 0 banned IPs hasta que haya intentos fallidos). Si quieres ver los logs: sudo tail -f /var/log/fail2ban.log. Si te baneaste a tú mismo (pasó), desbloqueate con sudo fail2ban-client set sshd unbanip TU.IP.AQUI.
—
Resumen rápido (cheatsheet)
| Comando | Para qué sirve |
|---|---|
ssh user@host |
Conectar |
ssh -p 2222 user@host |
Puerto personalizado |
ssh -i clave.pem user@host |
Clave específica |
ssh-keygen -t ed25519 |
Generar par de claves |
ssh-copy-id user@host |
Copiar clave pública |
scp archivo user@host:/ruta/ |
Copiar archivo |
rsync -avz ./ user@host:/dest/ |
Sincronizar |
ssh -L 8080:localhost:80 user@host |
Túnel local |
ssh -R 8080:localhost:3000 user@host |
Túnel remoto |
ssh -D 1080 user@host |
Proxy SOCKS |
ssh -J bastion user@final |
Jump host |
ssh-agent && ssh-add |
Recordar passphrases |
—
Próximos pasos
Si quieres profundizar:
- Mosh: shell que sobrevive a cambios de red (ideal para conexiones WiFi inestables).
- Teleport: SSH con auditoría centralizada, muy útil para equipos.
- Tailscale: VPN basada en WireGuard que reemplaza jump hosts.
- Eternal Terminal: similar a mosh pero con más features.
¿Sobre cuál quieres que escriba el próximo post? Déjamelo en comentarios.
Si te sirvió, suscríbete al blog para no perderte los siguientes tutoriales.
Preguntas frecuentes
¿Por qué 10 comandos SSH que todo administrador Linux debería conocer es relevante para sysadmins Linux?
Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.
¿Qué necesito para empezar con 10 comandos SSH que todo?
Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.
¿Cuáles son los errores más comunes con 10 comandos SSH que todo?
Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.
¿Cuándo usar 10 comandos SSH que todo y cuándo una alternativa?
Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.
¿Cómo migro desde una configuración previa a 10 comandos SSH que todo?
Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.
Lee también
- Guía Fedora 44: Novedades, Instalación y Upgrade para Sysadmins Linux
- Configura VLANs en Linux con nmcli: Guía paso a paso para sysadmins
- Protege tu SSH: Guía esencial para configurar Fail2ban en Linux
- Guía Definitiva: Configura Kubernetes con kubeadm en Ubuntu para Sysadmins Linux
- Configura Prometheus y Grafana: Guía DevOps para SysAdmins Linux

Pingback: Certificaciones Linux: cuáles valen la pena en 2026
Pingback: Cómo ver el ancho de banda en CentOS con iftop
Pingback: Comando SCP en Linux: guía avanzada con ejemplos
Pingback: Pi-hole vs AdGuard Home: comparativa honesta 2026
Pingback: GLAD: la metodología de 4 pasos que arregla el 99% de errores Linux
Pingback: 10 comandos básicos de Linux que todo usuario debe saber
Pingback: Comandos Linux más útiles para empezar en 2026: la guía definitiva - Soy Linux