SSH a fondo: claves, servidor y túneles
Intermedio
Los pasos marcados en azul cambian según tu sistema.
SSH es la llave de tu infraestructura. Con él entras en el VPS que tienes alquilado, en la Raspberry Pi del armario o en el servidor que comparte tu colectivo; ejecutas comandos, mueves archivos y llegas a servicios que no quieres dejar a la vista de internet. Todo cifrado, y sin pasar por el panel web de ninguna empresa.
Aquí tienes una guía de referencia para dominarlo: las claves, la conexión, una configuración segura para el servidor, trucos para el cliente, túneles y una lista de averías con su arreglo. No hace falta leerla de un tirón: usa el índice y ve a lo que necesites.
Los nombres que verás en los comandos (usuario, servidor, ejemplo.org…) son de ejemplo: cámbialos por los tuyos. Cuando un paso depende de la distribución del servidor, elige la tuya en el desplegable de arriba.
Lo básico en dos minutos
En una conexión SSH hay dos partes. En el servidor corre sshd, un servicio que espera conexiones (normalmente en el puerto 22). En tu ordenador usas ssh, el cliente. Linux y macOS lo traen instalado, y Windows 10 y 11 también: todo lo que verás aquí funciona igual desde PowerShell.
Para demostrar quién eres puedes usar una contraseña o un par de claves. Las contraseñas son la puerta por la que entran los problemas: desde el primer día, tu servidor recibirá intentos automáticos de adivinarlas. Las claves son otra cosa:
- La clave privada vive en tu ordenador y no sale de ahí. Es tu identidad.
- La clave pública la copias a los servidores donde quieras entrar. Puedes enseñarla a quien quieras: con ella no se puede entrar en ningún sitio.
El servidor guarda las claves públicas autorizadas en ~/.ssh/authorized_keys, una por línea. Cuando te conectas, te pide que firmes un reto con tu clave privada y comprueba la firma con la pública. Tu clave privada nunca viaja por la red, y si alguien asalta el servidor no encontrará en él nada que le sirva para suplantarte en otro sitio. Para quitarle el acceso a una clave, borras su línea y listo.
Hay una segunda comprobación que va en sentido contrario: tu cliente también verifica que el servidor es quien dice ser. La primera vez que te conectas, guarda la huella de la clave del servidor en ~/.ssh/known_hosts; si un día esa huella cambia, te avisará antes de conectar. Tus claves te identifican a ti; la huella identifica al servidor.
Tus claves
Crear un par de claves
Ed25519 es hoy el algoritmo recomendado para claves SSH: seguro, rápido y con claves muy cortas. Crea tu par en tu ordenador:
ssh-keygen -t ed25519 -C "tu_correo@ejemplo.org"
Lo que pongas tras -C es solo una etiqueta para reconocer la clave. El programa te hará dos preguntas:
Enter file in which to save the key (/home/usuario/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Para la ruta, deja la que propone pulsando Intro: así tu cliente encontrará la clave sin que tengas que indicarla. Para la frase de paso, escribe una: cifra la clave privada en el disco, de modo que si alguien copia el archivo no podrá usarlo. No verás nada mientras la escribes; es lo normal.
Al terminar tendrás dos archivos en ~/.ssh: id_ed25519 (la privada, que no debe salir de tu ordenador) e id_ed25519.pub (la pública, la que repartirás).
¿Algún equipo antiguo no acepta Ed25519? Para ellos, crea una clave RSA de 4096 bits con
ssh-keygen -t rsa -b 4096. Si ya tienes unid_rsa, te preguntará si quieres sobrescribirlo: si dices que sí, perderás el acceso a los servidores que solo conocían la antigua.
Cambiar o quitar la frase de paso
La frase de paso se puede cambiar cuando quieras, siempre que te acuerdes de la actual (si la olvidas, no hay forma de recuperarla: toca crear claves nuevas):
ssh-keygen -p -f ~/.ssh/id_ed25519
Te pedirá la frase antigua y la nueva. Si dejas la nueva vacía, la clave quedará sin protección.
Identificar una clave
Para saber qué clave es cuál sin mostrarla entera, mira su huella:
ssh-keygen -l -f ~/.ssh/id_ed25519.pub
256 SHA256:5w5o0ZKcH7MXUd4b2rC8bVzE8n7H3uU9b1M2y3Q4x5w tu_correo@ejemplo.org (ED25519)
Llevar tu clave pública al servidor
Elige el método según lo que tengas a mano.
Si puedes entrar con contraseña y tienes ssh-copy-id (viene con OpenSSH en Linux y macOS), es un solo comando:
ssh-copy-id usuario@servidor
Te pedirá la contraseña de la cuenta remota y añadirá tu clave a su authorized_keys. A la siguiente, ssh usuario@servidor ya no te pedirá contraseña.
Si puedes entrar con contraseña pero no tienes ssh-copy-id (por ejemplo, en Windows), envía la clave por la propia conexión. Este comando crea la carpeta si hace falta, añade la clave y deja los permisos correctos:
cat ~/.ssh/id_ed25519.pub | ssh usuario@servidor "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
En PowerShell, cambia el principio por type $env:USERPROFILE\.ssh\id_ed25519.pub | y deja el resto igual.
Si no tienes ningún acceso por SSH, toca hacerlo a mano. Muestra tu clave pública y cópiala entera:
cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJkqgjQ2s3k5x7d0v8yE0nVd4R1pTq0y9uYb3fH6aWcK tu_correo@ejemplo.org
Entra en el servidor por otra vía (la consola web de tu proveedor, o un teclado y una pantalla) y, con el usuario que quieres habilitar:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "pega_aquí_tu_clave_pública" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Conectarte
Entrar en el servidor
ssh usuario@servidor
servidor puede ser una IP o un nombre de dominio. Si tu usuario local se llama igual que el remoto, basta con ssh servidor.
La primera conexión a un servidor siempre empieza con esta pregunta:
The authenticity of host '203.0.113.10 (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:Xn1p0Lw3Gm8qY0sV6sRk4cB2t9eHq5yJ7aZ1uW3oP2c.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Tu cliente no conoce todavía ese servidor y te muestra la huella de su clave. Si quieres hacerlo bien, compárala con la que te muestre la consola de tu proveedor o con la que obtengas en el propio servidor (ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub). Si coincide, responde yes.
Lanzar un comando y volver
No siempre necesitas una sesión. Si pones un comando al final, SSH lo ejecuta en el servidor, te enseña el resultado y se desconecta:
ssh usuario@servidor "df -h"
Otro puerto
Si el servidor no escucha en el 22, indica el puerto con -p:
ssh -p 4444 usuario@servidor
Más abajo verás cómo guardarlo en tu configuración para no tener que escribirlo cada vez.
No volver a escribir la frase de paso
El agente SSH guarda tu clave desbloqueada mientras dure tu sesión en el ordenador, así que la frase de paso solo te la pide una vez. En macOS y en la mayoría de escritorios Linux ya está funcionando; añade tu clave con:
ssh-add ~/.ssh/id_ed25519
Si te dice que no encuentra el agente, arráncalo primero con eval "$(ssh-agent -s)". En Windows, el agente es un servicio que hay que activar una vez desde PowerShell como administrador:
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
Llegar a un servidor a través de otro
Si una máquina solo es accesible pasando por otra (un bastión o la máquina de entrada de tu red), usa -J:
ssh -J usuario@bastion usuario@servidor_interno
Tu cliente atraviesa la primera máquina y se autentica en la segunda con tus claves, que nunca pisan el bastión.
¿Y
ssh -A? Reenviar el agente también permite saltar de un servidor a otro, pero mientras estás conectado, quien administre esa máquina puede usar tu agente para entrar en otros sitios en tu nombre. Resérvalo para servidores que controles al cien por cien; en general,-Jes mejor opción.
Blindar el servidor
La configuración de serie de SSH prioriza que todo funcione a la primera. Para un servidor expuesto a internet conviene cerrar varias puertas desde el primer día: solo claves, nada de root, pocos intentos y una lista explícita de quién puede entrar.
Requisito imprescindible: que ya puedas entrar con tu clave. Si desactivas las contraseñas antes, te quedarás fuera.
El archivo que de verdad manda
La configuración del servicio está en /etc/ssh/sshd_config, pero las versiones actuales de Debian, Ubuntu, AlmaLinux y Fedora cargan antes los archivos de /etc/ssh/sshd_config.d/. Y en sshd, para cada opción, gana el primer valor que se lee. Es una trampa clásica en los VPS: la imagen del proveedor trae un 50-cloud-init.conf con PasswordAuthentication yes, y por mucho que cambies sshd_config, las contraseñas siguen funcionando.
La solución es dejar tus ajustes en un archivo propio que se lea antes que ninguno:
sudo nano /etc/ssh/sshd_config.d/00-cableando.conf
La configuración base
Copia esto y cambia usuario por las cuentas que deban poder entrar (separadas por espacios):
/etc/ssh/sshd_config.d/00-cableando.conf
# Solo claves: nada de contraseñas
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
# root no entra directamente: se usa sudo
PermitRootLogin no
# Tres intentos por conexión y treinta segundos para identificarse
MaxAuthTries 3
LoginGraceTime 30
# Lista cerrada de cuentas con acceso
AllowUsers usuario
Con esto, los bots no tienen contraseñas que probar, la cuenta que todos intentan (root) queda fuera de su alcance, cada conexión tiene pocas oportunidades y cualquier usuario que se cree en el sistema sin estar en la lista no podrá entrar por SSH. Además, como cada persona entra con su cuenta y usa sudo, queda constancia de quién hizo qué.
Aplicar los cambios sin quedarte fuera
Primero, valida la sintaxis. Si no muestra nada, está todo bien:
sudo sshd -t
Después reinicia el servicio:
Ubuntu
sudo systemctl restart ssh
Debian
sudo systemctl restart ssh
AlmaLinux / Rocky
sudo systemctl restart sshd
Fedora
sudo systemctl restart sshd
Y comprueba los valores que el servicio está aplicando de verdad:
sudo sshd -T | grep -Ei 'passwordauthentication|permitrootlogin|maxauthtries'
maxauthtries 3
permitrootlogin no
passwordauthentication no
Mantén abierta la sesión con la que has hecho los cambios y prueba a entrar desde otra terminal. Si algo ha ido mal, aún puedes corregirlo.
Más ajustes del servidor
Todos estos cambios se hacen en tu 00-cableando.conf y se aplican igual: sshd -t, reinicio y prueba desde otra terminal.
Mover SSH a otro puerto
Sacar SSH del puerto 22 no lo hace más seguro (las claves y el cortafuegos sí), pero reduce muchísimo el ruido de los bots en los registros. Elige un puerto libre, por ejemplo el 4444, y añádelo:
/etc/ssh/sshd_config.d/00-cableando.conf
Port 4444
Antes de reiniciar, abre ese puerto en el cortafuegos, o te dejarás fuera:
Ubuntu
sudo ufw allow 4444/tcp
En Ubuntu 22.10 y posteriores, quien escucha en el puerto es un socket de systemd, no el propio servicio. Para que se entere del cambio:
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
Debian
sudo ufw allow 4444/tcp
sudo systemctl restart ssh
AlmaLinux / Rocky
SELinux solo permite a SSH los puertos que tiene registrados para él, así que hay que añadirlo (si te falta semanage, instala policycoreutils-python-utils). Después ábrelo en firewalld y reinicia:
sudo semanage port -a -t ssh_port_t -p tcp 4444
sudo firewall-cmd --permanent --add-port=4444/tcp
sudo firewall-cmd --reload
sudo systemctl restart sshd
Fedora
SELinux solo permite a SSH los puertos que tiene registrados para él, así que hay que añadirlo. Después ábrelo en firewalld y reinicia:
sudo semanage port -a -t ssh_port_t -p tcp 4444
sudo firewall-cmd --permanent --add-port=4444/tcp
sudo firewall-cmd --reload
sudo systemctl restart sshd
A partir de ahí, conéctate con ssh -p 4444 usuario@servidor. Cuando compruebes que funciona, cierra el 22 en el cortafuegos.
Dar acceso por grupos
Si la lista de AllowUsers crece, es más cómodo gestionar el acceso con un grupo. Cambia la línea por:
/etc/ssh/sshd_config.d/00-cableando.conf
AllowGroups accesossh
Crea el grupo y añade a quien corresponda:
sudo groupadd -r accesossh
sudo usermod -aG accesossh ana
sudo usermod -aG accesossh luis
Dar o quitar acceso pasa a ser meter o sacar a alguien del grupo.
Un comando concreto como root
Hay tareas automáticas, como una copia de seguridad nocturna, que necesitan hacer algo como root a través de SSH. En vez de reabrir la cuenta de root, puedes autorizar una clave para un único comando.
Úsalo con cabeza. Si puedes, es mejor un usuario sin privilegios con permiso de
sudosolo para ese comando.
Crea una clave dedicada a esa tarea e instala su parte pública en /root/.ssh/authorized_keys. Después, edita esa línea y antepón el comando permitido y unas cuantas restricciones:
/root/.ssh/authorized_keys
command="/usr/local/bin/copia-de-seguridad.sh",no-port-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAA...
En la configuración de sshd, cambia PermitRootLogin no por:
/etc/ssh/sshd_config.d/00-cableando.conf
PermitRootLogin forced-commands-only
Esa clave solo podrá lanzar ese comando; cualquier otra cosa será rechazada.
Ventanas del servidor en tu escritorio
Si de vez en cuando necesitas un programa gráfico que está en el servidor, SSH puede traer sus ventanas a tu pantalla (reenvío X11). En el servidor hace falta el paquete xauth y esta opción:
/etc/ssh/sshd_config.d/00-cableando.conf
X11Forwarding yes
En tu ordenador necesitas un servidor gráfico X (en Linux suele estar; en macOS, instala XQuartz). Conéctate con -X y los programas gráficos que abras aparecerán en tu escritorio:
ssh -X usuario@servidor
Tu cliente, a tu medida
Todo lo que repites al conectarte puede quedarse guardado en ~/.ssh/config, en tu ordenador.
Un nombre corto para cada servidor
nano ~/.ssh/config
~/.ssh/config
Host vps
HostName ejemplo.org
Port 4444
User usuario
IdentityFile ~/.ssh/id_ed25519
Host casa
HostName 192.168.1.20
User usuario
Ahora ssh vps y ssh casa hacen todo el trabajo. Puedes añadir cualquier opción de man ssh_config.
Para aplicar algo a todos los servidores, usa Host *. Ojo con el orden: el cliente se queda con el primer valor que encuentra para cada opción, así que los bloques concretos van arriba y el general, al final.
Que no se corte la sesión
Si tus sesiones mueren cuando las dejas un rato quietas, algún equipo de red intermedio está cerrando la conexión por inactividad. Pide a tu cliente que dé señales de vida cada dos minutos:
~/.ssh/config
Host *
ServerAliveInterval 120
Abrir sesiones al instante
Si te conectas muchas veces al mismo servidor, puedes hacer que todas las sesiones compartan una sola conexión. La primera tarda lo normal; las siguientes se abren al momento:
~/.ssh/config
Host *
ControlMaster auto
ControlPath ~/.ssh/multiplex/%r@%h:%p
ControlPersist 1
Crea la carpeta que usará para coordinarse:
mkdir -p ~/.ssh/multiplex
Si alguna vez quieres una conexión aparte, ssh -S none usuario@servidor.
Máquinas de usar y tirar
En un laboratorio en tu red local donde creas y destruyes máquinas virtuales continuamente, el aviso de huella cambiada se vuelve un incordio. Para ese rango concreto puedes desactivar la comprobación:
Nunca lo hagas para servidores en internet ni para
Host *: es la protección que te avisa si alguien se hace pasar por tu servidor.
~/.ssh/config
Host 192.168.56.*
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Túneles
Por una conexión SSH puede viajar cualquier otro tráfico, cifrado. Es la forma más simple de llegar a un servicio que no quieres exponer, de cifrar un protocolo que no lo está o de navegar a través de tu servidor cuando no te fías de la red en la que estás.
Los ejemplos usan -N (no abrir sesión, solo el túnel). Si añades -f, el túnel se queda funcionando en segundo plano.
Traer un servicio remoto a tu ordenador
El caso típico: un panel de administración que en el servidor solo escucha en localhost. Con -L lo llevas a un puerto de tu ordenador:
ssh -N -L 8888:localhost:80 usuario@servidor
Mientras el túnel esté abierto, http://127.0.0.1:8888 en tu navegador te mostrará lo que sirve el puerto 80 del servidor. La parte localhost:80 se interpreta desde el servidor, así que también puedes apuntar a otra máquina de su red.
Publicar un servicio de tu red a través del servidor
-R hace el camino inverso: abre un puerto en el servidor que lleva a algo que tu ordenador alcanza. Útil para enseñar desde tu VPS algo que tienes en casa sin abrir puertos en el router:
ssh -N -R 8888:localhost:3000 usuario@servidor
Ahora el puerto 8888 del servidor lleva al 3000 de tu ordenador. Por defecto solo escucha en el localhost del servidor; para abrirlo hacia fuera necesitas GatewayPorts yes en su configuración (y pensártelo bien).
Tu propio proxy, sin intermediarios
Con -D, un puerto de tu ordenador se convierte en un proxy SOCKS que sale a internet desde tu servidor. Para una wifi pública o una red que filtra contenidos, es como una VPN de bolsillo, con la diferencia de que el servidor es tuyo:
ssh -N -D 7777 usuario@servidor
En Firefox, ve a Ajustes → General → Configuración de red, elige la configuración manual del proxy y pon 127.0.0.1 y 7777 como servidor SOCKS v5. Activa también la opción de hacer las consultas DNS a través del proxy, para que tampoco se filtren por la red local.
Cerrar un túnel
Si lo abriste sin -f, Ctrl+C en su terminal lo cierra. Si está en segundo plano, busca su proceso y termínalo:
pgrep -af "ssh -N"
5965 ssh -f -N -D 7777 usuario@servidor
kill 5965
Órdenes dentro de una sesión
Tu cliente SSH escucha unas órdenes especiales que empiezan por ~ y solo funcionan como primer carácter de una línea: pulsa Intro antes de escribirlas.
~.cierra la conexión al instante. Es la salida de emergencia cuando la sesión se queda congelada (has cambiado de wifi, el servidor no responde…): escríbelo aunque no veas nada en pantalla.~seguido deCtrl+Zmanda la sesión a segundo plano y te devuelve a tu terminal. Conjobsves las que tienes y confg(ofg %2) vuelves a una.~Cabre una pequeña línea de órdenes para gestionar túneles sin reconectar. Por ejemplo,-L 8888:127.0.0.1:80abre uno y-KL 8888lo cierra. Con-hves todas las opciones.~?muestra la lista completa de secuencias.
Cuando algo falla
Permission denied (publickey)
El servidor no ha aceptado ninguna de tus claves. Repasa, en este orden:
- ¿Te conectas con el usuario correcto? La clave está autorizada para una cuenta concreta.
- ¿Está tu clave pública en el
~/.ssh/authorized_keysde esa cuenta? - ¿Son correctos los permisos? sshd ignora
authorized_keyssi la carpeta o el archivo los tienen demasiado abiertos. Desde la consola del servidor:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Connection refused
Llegas al servidor, pero nadie atiende en ese puerto: el servicio está parado, escucha en otro puerto o un cortafuegos lo impide. Desde la consola del servidor, comprueba el servicio:
Ubuntu
sudo systemctl status ssh
Debian
sudo systemctl status ssh
AlmaLinux / Rocky
sudo systemctl status sshd
Fedora
sudo systemctl status sshd
Y en qué puerto escucha:
sudo ss -tlnp | grep ssh
Host key verification failed
La huella del servidor no coincide con la que tu cliente guardó. Si sabes por qué (lo has reinstalado, o esa IP ahora es de otra máquina), olvida la antigua:
ssh-keygen -R servidor
Si no sabes por qué ha cambiado, no sigas: es exactamente el aviso que te protege de una suplantación.
Too many authentication failures
Tu agente ofrece tantas claves que el servidor corta antes de llegar a la buena. Indica cuál usar con ssh -i ~/.ssh/id_ed25519 usuario@servidor, o fíjalo para ese servidor:
~/.ssh/config
Host vps
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Ver la conversación completa
Si nada de lo anterior encaja, añade -v (o -vvv para aún más detalle) y verás paso a paso qué intenta el cliente y dónde se rompe:
ssh -v usuario@servidor
En el servidor, el registro del servicio cuenta su versión de los hechos: sudo journalctl -u ssh -n 50 en Debian y Ubuntu, o sudo journalctl -u sshd -n 50 en AlmaLinux, Rocky y Fedora.
Siguiente parada
Con tus claves, una configuración base sólida y los túneles en la recámara, ya tienes lo necesario para gestionar tus máquinas sin depender de nadie. Si estás montando un servidor desde cero, sigue con los primeros pasos de un servidor Linux, el cortafuegos con UFW y Fail2Ban.
