Las claves SSH sustituyen la contraseña por un par de claves criptográficas: la clave privada se queda en tu equipo y la pública se copia al servidor. Son mucho más resistentes a ataques de fuerza bruta y permiten desactivar por completo el acceso por contraseña. En este tutorial generarás una clave Ed25519, la instalarás en un servidor Ubuntu 24.04, configurarás el cliente y el agente SSH, endurecerás sshd para aceptar solo claves y aprenderás a restringir, rotar y revocar claves.
Requisitos previos
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, al que ahora accedes con usuario y contraseña.
- Un usuario no root con privilegios
sudoen el servidor. En los ejemplos se llamayour_usery la IP del servidor esyour_server_ip. - Un equipo local con OpenSSH: cualquier Linux, macOS o Windows 10/11 (PowerShell incluye
sshyssh-keygen).
Los pasos 1 a 4 se ejecutan en tu equipo local; el paso 5 en el servidor.
Paso 1: Generar un par de claves Ed25519
Ed25519 es el tipo de clave recomendado: claves cortas, rápidas y seguras, compatibles con cualquier OpenSSH de los últimos años. Genera la clave en tu equipo local:
ssh-keygen -t ed25519 -C "your_user@portatil-2026"
El comentario de -C sirve para identificar la clave más tarde en authorized_keys; usa algo que indique quién y desde dónde. Acepta la ruta por defecto (~/.ssh/id_ed25519) e introduce una frase de contraseña:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/tu_usuario/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/tu_usuario/.ssh/id_ed25519
Your public key has been saved in /home/tu_usuario/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:mQ3b7l1xT0H9... your_user@portatil-2026
Importanteusa siempre una frase de contraseña en claves personales. Si alguien copia tu clave privada, no podrá usarla sin la frase. Gracias a
ssh-agent(paso 4) solo tendrás que escribirla una vez por sesión.
Si algún sistema antiguo no admite Ed25519, genera una clave RSA de 4096 bits con ssh-keygen -t rsa -b 4096.
Comprueba los permisos: la clave privada debe ser legible solo por ti.
ls -l ~/.ssh/id_ed25519*
-rw------- 1 tu_usuario tu_usuario 464 Sep 25 10:20 /home/tu_usuario/.ssh/id_ed25519
-rw-r--r-- 1 tu_usuario tu_usuario 105 Sep 25 10:20 /home/tu_usuario/.ssh/id_ed25519.pub
Si los permisos no coinciden, corrígelos con chmod 700 ~/.ssh y chmod 600 ~/.ssh/id_ed25519.
Para cambiar o añadir la frase de contraseña a una clave existente sin regenerarla:
ssh-keygen -p -f ~/.ssh/id_ed25519
Paso 2: Copiar la clave pública al servidor
ssh-copy-id añade tu clave pública al archivo ~/.ssh/authorized_keys del usuario remoto y le pone los permisos correctos. Te pedirá la contraseña del servidor por última vez:
ssh-copy-id -i ~/.ssh/id_ed25519.pub your_user@your_server_ip
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'your_user@your_server_ip'"
and check to make sure that only the key(s) you wanted were added.
En Windows, donde ssh-copy-id no existe, puedes hacer lo mismo desde PowerShell:
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh your_user@your_server_ip "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Paso 3: Probar el acceso con clave
Conéctate de nuevo. Ahora SSH debe pedirte la frase de la clave, no la contraseña del servidor:
ssh your_user@your_server_ip
Para confirmar qué método de autenticación se usó, conecta en modo detallado:
ssh -v your_user@your_server_ip exit 2>&1 | grep -E 'Authenticated|Offering public key'
debug1: Offering public key: /home/tu_usuario/.ssh/id_ed25519 ED25519 SHA256:mQ3b7l1xT0H9... explicit
Authenticated to your_server_ip ([your_server_ip]:22) using "publickey".
No continúes con el paso 5 hasta que este acceso funcione.
Paso 4: Configurar el cliente SSH y el agente
Alias en ~/.ssh/config
El archivo ~/.ssh/config evita repetir usuario, IP, puerto y clave en cada conexión. Créalo o edítalo en tu equipo local:
nano ~/.ssh/config
Host web01
HostName your_server_ip
User your_user
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Host *
ServerAliveInterval 60
AddKeysToAgent yes
IdentitiesOnly yes hace que SSH ofrezca solo la clave indicada, lo que evita el error Too many authentication failures cuando tienes muchas claves cargadas. Protege el archivo y prueba el alias:
chmod 600 ~/.ssh/config
ssh web01
Cargar la clave en ssh-agent
ssh-agent guarda en memoria las claves desbloqueadas para que no tengas que escribir la frase en cada conexión. En la mayoría de escritorios Linux y en macOS ya se ejecuta uno. Si no es tu caso, inícialo en la sesión actual:
eval "$(ssh-agent -s)"
Añade tu clave. La opción -t limita el tiempo que permanece cargada, en este caso 8 horas:
ssh-add -t 8h ~/.ssh/id_ed25519
ssh-add -l
256 SHA256:mQ3b7l1xT0H9... your_user@portatil-2026 (ED25519)
En macOS puedes guardar la frase en el llavero con ssh-add --apple-use-keychain ~/.ssh/id_ed25519.
Saltar a servidores internos a través de un bastión
Si tienes servidores sin IP pública accesibles solo desde un servidor bastión, usa ProxyJump en lugar de copiar tu clave privada al bastión o activar el reenvío del agente:
Host interno01
HostName 10.0.0.15
User your_user
ProxyJump web01
Con ssh interno01, la conexión atraviesa web01 y la autenticación sigue ocurriendo con la clave de tu equipo local.
Paso 5: Desactivar el acceso por contraseña en el servidor
Con el acceso por clave comprobado, configura sshd para rechazar contraseñas. En Ubuntu 24.04 el archivo principal incluye los de /etc/ssh/sshd_config.d/*.conf al principio, y para cada opción gana el primer valor leído. Algunas imágenes cloud crean 50-cloud-init.conf con PasswordAuthentication yes, así que tu archivo debe tener un nombre que se ordene antes. Comprueba qué hay en el directorio:
ls /etc/ssh/sshd_config.d/
Crea el archivo de endurecimiento en el servidor:
sudo nano /etc/ssh/sshd_config.d/10-hardening.conf
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
MaxAuthTries 3
AllowUsers your_user
AllowUsers limita el acceso a los usuarios indicados, separados por espacios. Omite esa línea si varios usuarios deben entrar y prefieres gestionarlo por grupos con AllowGroups.
Valida la sintaxis y comprueba la configuración efectiva:
sudo sshd -t
sudo sshd -T | grep -Ei '^(passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|permitrootlogin|maxauthtries) '
permitrootlogin no
pubkeyauthentication yes
passwordauthentication no
kbdinteractiveauthentication no
maxauthtries 3
Aplica los cambios sin cerrar tu sesión actual:
sudo systemctl reload ssh
Advertenciamantén abierta la sesión actual y prueba desde una nueva terminal con
ssh web01. Si algo falla, corrige la configuración desde la sesión abierta. Si te quedas fuera, necesitarás la consola web del proveedor para entrar.
Desde tu equipo local, confirma que el servidor ya no acepta contraseñas:
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password your_user@your_server_ip
your_user@your_server_ip: Permission denied (publickey).
Paso 6: Restringir lo que puede hacer una clave
Las claves de automatización (copias de seguridad, despliegues) no necesitan una shell completa. En authorized_keys puedes añadir opciones delante de la clave. La opción restrict desactiva reenvío de puertos, del agente, X11 y la asignación de terminal; from limita las IP de origen y command fuerza un único comando:
restrict,from="203.0.113.10",command="/usr/local/bin/backup-export" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... backup@servidor-copias
Genera una clave distinta para cada uso o sistema, en lugar de reutilizar tu clave personal:
ssh-keygen -t ed25519 -f ~/.ssh/deploy_web01 -C "deploy@ci-2026"
Las claves de sistemas automáticos que no pueden introducir frase se generan sin ella (-N ""), por eso es tan importante limitarlas con restrict, from y command.
Paso 7: Auditar, rotar y revocar claves
Revisar qué claves tienen acceso
ssh-keygen -l muestra la huella y el comentario de cada línea de authorized_keys. Revísalo en el servidor para cada usuario:
ssh-keygen -lf ~/.ssh/authorized_keys
sudo ssh-keygen -lf /root/.ssh/authorized_keys
256 SHA256:mQ3b7l1xT0H9... your_user@portatil-2026 (ED25519)
256 SHA256:Zp41kQ8vW2c... deploy@ci-2026 (ED25519)
El registro de SSH indica qué clave se usó en cada inicio de sesión, con la misma huella:
sudo journalctl -u ssh --since "7 days ago" --no-pager | grep 'Accepted publickey'
Si una huella de authorized_keys no aparece en meses, probablemente sobra.
Rotar una clave
Rota las claves personales periódicamente (por ejemplo, cada año) y de inmediato si pierdes el equipo. El orden correcto evita quedarse fuera:
- Genera la clave nueva:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_2027 -C "your_user@portatil-2027". - Instálala junto a la antigua:
ssh-copy-id -i ~/.ssh/id_ed25519_2027.pub web01. - Actualiza
IdentityFileen~/.ssh/configy comprueba el acceso conssh web01. - En el servidor, borra la línea de la clave antigua de
~/.ssh/authorized_keys.
Revocar una clave comprometida
Elimina su línea de authorized_keys en todos los servidores. Para localizarla, busca por el comentario o por la huella:
grep -n 'your_user@portatil-2026' ~/.ssh/authorized_keys
Borra la línea indicada con tu editor y verifica de nuevo con ssh-keygen -lf ~/.ssh/authorized_keys.
Solución de problemas
Permission denied (publickey). Conecta con ssh -v para ver qué claves se ofrecen. En el servidor, revisa sudo journalctl -u ssh -n 20: un mensaje Authentication refused: bad ownership or modes indica permisos incorrectos. Corrígelos:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod go-w ~
Too many authentication failures. El agente ofrece demasiadas claves antes de la correcta. Añade IdentitiesOnly yes e IdentityFile en el bloque Host de ~/.ssh/config.
REMOTE HOST IDENTIFICATION HAS CHANGED. La clave del servidor cambió, por ejemplo tras reinstalarlo. Si sabes que es legítimo, elimina la entrada antigua con ssh-keygen -R your_server_ip y acepta la nueva huella al conectar. Si no hubo ningún cambio, no continúes: podría ser un ataque de intermediario.
Sigue aceptando contraseñas tras el paso 5. Otro archivo de /etc/ssh/sshd_config.d/ define PasswordAuthentication yes antes que el tuyo. Comprueba el valor efectivo con sudo sshd -T | grep passwordauthentication y renombra tu archivo para que se ordene primero.
Conclusión
Has generado una clave Ed25519 protegida con frase, la has instalado en el servidor, has configurado alias y agente en el cliente, has desactivado el acceso por contraseña y has visto cómo restringir, auditar, rotar y revocar claves. Con esto eliminas los ataques de fuerza bruta contra contraseñas en SSH.
Como siguientes pasos puedes:
- Añadir un segundo factor con Google Authenticator para el acceso SSH.
- Instalar Fail2ban para bloquear las IP que insisten en intentar conectarse.
- Usar llaves de seguridad FIDO2 con claves
ed25519-skpara que la clave privada nunca salga de un dispositivo físico.
