SSH es simple una vez que dejas de tratarlo como una caja mágica de login. Un cliente contacta un servidor, verifica la identidad del servidor y luego demuestra la identidad del usuario. La mayoría de los fallos te dicen exactamente cuál de esas etapas se rompió.
🎙️ Publicado y grabado: ·
Tu clave privada se queda en tu máquina. La clave pública puede copiarse libremente a servidores. Durante el login, el servidor te pide que demuestres posesión de la clave privada; la clave privada no se sube. En el servidor, una línea en ~/.ssh/authorized_keys otorga acceso a una clave pública para esa cuenta.
# Make a modern key pair; use a passphrase.
ssh-keygen -t ed25519 -a 100 -C "laptop-2026"
~/.ssh/id_ed25519 PRIVATE — never send this
~/.ssh/id_ed25519.pub PUBLIC — install this on servers
# Show the public key safely:
cat ~/.ssh/id_ed25519.pubUn destino SSH tiene cuatro datos: usuario, host, puerto e identidad. Los valores por defecto ocultan tres de ellos, lo cual es agradable hasta que el default equivocado gana. Cuando una conexión falla, ejecuta el mismo comando con un -v. Léelo por etapa: conexión de red, verificación de host-key y luego ofertas de autenticación.
ssh [email protected]
ssh -p 2222 [email protected]
# Diagnostic view; -vvv is usually noise until -v is insufficient.
ssh -v -p 2222 [email protected]
# Useful lines:
debug1: Connecting to server.example.com [203.0.113.10] port 2222.
debug1: Server host key: ssh-ed25519 SHA256:...
debug1: Offering public key: /home/alice/.ssh/id_ed25519Sé preciso con el usuario remoto. Tu nombre de usuario en el portátil no es evidencia de que la cuenta del servidor tenga el mismo nombre. Las imágenes cloud suelen esperar ubuntu, ec2-user u otra cuenta provisionada.
Este mensaje exacto significa que la ruta de red y el servicio SSH funcionaron. La autenticación no. No depures firewalls ahora. Confirma el usuario remoto, mira qué clave ofrece el cliente, fuerza la clave prevista, y luego verifica que su clave pública correspondiente está instalada para esa cuenta exacta del servidor.
[email protected]: Permission denied (publickey).
# 1. Does verbose output say "Offering public key"?
ssh -v [email protected]
# 2. Force the intended identity and ignore surprise keys:
ssh -o IdentitiesOnly=yes -i ~/.ssh/work_ed25519 [email protected]
# 3. Compare fingerprints, not filenames:
ssh-keygen -lf ~/.ssh/work_ed25519.pub
# On server console:
ssh-keygen -lf /home/alice/.ssh/authorized_keysauthorized_keys tercero, permisos cuarto, política del servidor último. Regenerar claves al azar destruye evidencia y a menudo te deja con dos claves incorrectas en vez de una.OpenSSH rechaza una clave privada legible por otros usuarios. El servidor también puede ignorar authorized_keys si su directorio o archivo es escribible por las personas equivocadas. Corrige la propiedad antes que los modos; chmod no puede reparar un archivo propiedad de root.
WARNING: UNPROTECTED PRIVATE KEY FILE!
Permissions 0644 for 'id_ed25519' are too open.
# Client:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
# Server, run for the target account:
chown -R alice:alice /home/alice/.ssh
chmod 700 /home/alice/.ssh
chmod 600 /home/alice/.ssh/authorized_keysEn Windows, usa la configuración de Seguridad del archivo o icacls para eliminar el acceso heredado de usuarios no relacionados. Copiar números de modo Unix en PowerShell no es una solución multiplataforma; la regla es que solo el propietario debe poder leer la clave privada.
La host key identifica al servidor. Una clave cambiada puede ser una reconstrucción esperada, una IP reciclada o un atacante interceptando la conexión. La advertencia no puede distinguirlas, así que tu trabajo es verificar. Nunca elimines reflexivamente la advertencia y te reconectes.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
Offending ED25519 key in /home/alice/.ssh/known_hosts:12
Host key verification failed.
# 1. Verify the new fingerprint through a trusted channel:
# cloud console, provider metadata, or an administrator.
# 2. Remove only that host's stale entry:
ssh-keygen -R server.example.com
ssh-keygen -R "[server.example.com]:2222"
# 3. Reconnect and compare the displayed fingerprint.StrictHostKeyChecking=no no es una solución. Cambia una advertencia incómoda por suplantación silenciosa. La verificación toma un minuto; saltarla anula la parte de SSH que te dice qué máquina recibió tus credenciales.Estos fallos ocurren antes de la autenticación. "Refused" es una respuesta rápida del destino: el host es alcanzable, pero nada acepta ese puerto, o un firewall lo rechaza activamente. Un timeout significa que las respuestas se pierden o la ruta está rota. Tratar ambos como "SSH está caído" desperdicia la distinción.
ssh: connect to host server.example.com port 22: Connection refused
→ Check port; check sshd is listening; check service state.
ss -ltn | grep ':22'
systemctl status sshd # some systems name it ssh
ssh: connect to host server.example.com port 22: Connection timed out
→ Check DNS/IP, VPN, routing, security group, firewall allowlist.
ssh -v -o ConnectTimeout=8 [email protected]Prueba el hostname y puerto reales desde la red real del cliente. Una prueba exitosa desde el propio servidor no demuestra casi nada sobre un firewall de entrada. Una vez que la conexión TCP funciona, entonces vuelve a claves y nombres de usuario.
La línea de comandos es para experimentos. Los hosts estables pertenecen a ~/.ssh/config. Da a las máquinas alias memorables, fija el usuario, puerto e identidad, y usa ssh -G alias para inspeccionar la configuración completamente resuelta cuando la herencia te sorprenda.
Host reports
HostName reports.internal.example.com
User alice
Port 2222
IdentityFile ~/.ssh/work_ed25519
IdentitiesOnly yes
Host *.internal.example.com
ServerAliveInterval 30
ServerAliveCountMax 3
# Now:
ssh reports
scp results.csv reports:/srv/import/
ssh -G reports | lessUn agent mantiene las operaciones de clave desbloqueadas para que no teclees la passphrase en cada conexión. No copia la clave privada. Revisa qué tiene cargado cuando el cliente ofrece las identidades equivocadas. Para redes privadas, usa un jump host en vez de loguearte en un bastión y almacenar tu clave ahí.
# Inspect and load local agent identities:
ssh-add -l
ssh-add ~/.ssh/work_ed25519
The agent has no identities. # load one, or specify -i
# Reach an internal host through bastion:
ssh -J [email protected] [email protected]
# Config equivalent:
Host private-app
HostName 10.0.4.12
User app
ProxyJump [email protected]Evita el agent forwarding por defecto. Un host remoto comprometido puede pedirle a tu agent reenviado que firme mientras tu sesión está abierta. ProxyJump enruta la conexión sin exponer el acceso al agent en el bastión y es el mejor valor por defecto.
Local forwarding abre un puerto en tu máquina y lo lleva a través de SSH a un destino visible desde el servidor. Lee -L 8080:db.internal:5432 como: escucha localmente en 8080, luego desde el lado remoto alcanza db.internal puerto 5432. Usa -N cuando necesitas el túnel, no un shell.
# Local 15432 → database reachable from gateway
ssh -N -L 15432:db.internal:5432 gateway
psql -h 127.0.0.1 -p 15432 appdb
# Local 8080 → remote service bound to its localhost:3000
ssh -N -L 8080:127.0.0.1:3000 app-server
# Browse http://127.0.0.1:8080
# Fail immediately if forwarding cannot be established:
ssh -N -o ExitOnForwardFailure=yes -L 8080:127.0.0.1:3000 app-server0.0.0.0. Lo segundo puede exponer una base de datos interna o panel de admin a toda tu red local. Un túnel es transporte privado, no control de acceso automático.Clasifica la etapa antes de cambiar nada. Una ejecución verbose más este orden suele ganarle a veinte intentos a ciegas.
□ Did DNS resolve to the expected IP?
□ Is the port correct, reachable, and actually listening?
□ Refused (reachable, closed) or timeout (dropped/unroutable)?
□ Did I verify the server host-key fingerprint?
□ Is the remote username exactly right?
□ Which key does `ssh -v` say it is offering?
□ Does that public key exist in that user's authorized_keys?
□ Are ownership and permissions strict on both sides?
□ What does `ssh -G alias` say after config expansion?
□ Does the agent hold the intended identity?
□ For a tunnel, which machine resolves the destination host?
□ Did I bind only to loopback and use ExitOnForwardFailure?Mantén las etapas separadas: alcanza el puerto, identifica el servidor, autentica al usuario, luego abre un canal o túnel. Los mensajes de SSH se vuelven útiles en cuanto dejas de tratarlos como un fallo genérico de login.