Acceder por SSH con una clave sin depender de la contraseña

Entrar a un servidor por SSH escribiendo su contraseña cada vez funciona, pero no es la única opción. Con una clave tenemos dos piezas: la privada se queda en nuestro ordenador y la pública se copia al servidor. El servidor permite la entrada cuando comprobamos que poseemos la parte privada correspondiente.

Esto no significa dejar la clave privada sin protección ni desactivar contraseñas a la primera. Vamos a crear una clave separada, copiar sólo la pública y probarla en una segunda terminal antes de tocar la configuración del servidor.

Esquema de una clave privada que permanece en el portátil y una clave pública copiada al servidor SSH
La clave privada no se envía al servidor. Allí sólo se instala la parte pública.

Comprobar si ya tenemos claves

Abrimos una terminal en el ordenador desde el que nos conectamos y miramos el contenido de la carpeta de SSH:

ls -la ~/.ssh

Si ya aparecen archivos como id_ed25519 e id_ed25519.pub, no respondemos alegremente que sí cuando ssh-keygen pregunte si queremos sobrescribirlos. Puede que esa clave dé acceso a otros equipos. Para este tutorial utilizaremos un nombre reconocible y separado: id_ed25519_servidor.

Creamos el par con Ed25519:

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_servidor \
  -C "portatil-servidor"

El comentario sólo nos ayuda a identificar la clave. Cuando pregunte la frase de paso, pondría una. Si alguien copia el archivo privado, esa frase añade una barrera antes de poder usarlo. Podemos evitar escribirla en cada conexión utilizando después ssh-agent, sin quitarla del archivo.

Al terminar tendremos:

  • ~/.ssh/id_ed25519_servidor: clave privada; no se comparte.
  • ~/.ssh/id_ed25519_servidor.pub: clave pública; esta sí se instala en el servidor.

Podemos comprobar su huella:

ssh-keygen -lf ~/.ssh/id_ed25519_servidor.pub

Para preparar este artículo generé un par temporal con OpenSSH 9.6 y comprobé que la orden anterior reconocía una clave ED25519 de 256 bits. La prueba fue local: no demuestra que nuestro servidor acepte la clave hasta completar el siguiente paso.

Copiar la clave pública al servidor

Sustituimos usuario y servidor por los datos que ya utilizamos para entrar:

ssh-copy-id -i ~/.ssh/id_ed25519_servidor.pub usuario@servidor

Esta vez nos pedirá la contraseña del usuario remoto. ssh-copy-id inicia sesión y añade la clave pública a ~/.ssh/authorized_keys del servidor. La opción -i es importante si tenemos varias claves: indica exactamente cuál queremos instalar.

Si SSH escucha en otro puerto, lo especificamos así:

ssh-copy-id -i ~/.ssh/id_ed25519_servidor.pub \
  -p 2222 usuario@servidor

No enviamos por correo ni pegamos en un panel el archivo que no termina en .pub. La clave privada debe permanecer en el equipo donde se creó y en una copia de seguridad protegida si decidimos conservarla.

Probarla sin cerrar la sesión actual

Dejamos abierta la terminal con la que todavía podemos administrar el servidor. Abrimos otra y forzamos la clave recién creada:

ssh -i ~/.ssh/id_ed25519_servidor usuario@servidor

Puede pedirnos la frase de paso de la clave; eso es distinto de la contraseña de la cuenta remota. Una vez dentro ejecutamos whoami y hostname para verificar que hemos llegado al usuario y equipo correctos.

Si falla, la sesión anterior sigue abierta para revisar el problema. Ejecutar el cliente con -v muestra qué claves ofrece y en qué punto se rechaza la autenticación:

ssh -v -i ~/.ssh/id_ed25519_servidor usuario@servidor

Entre las causas habituales están haber copiado la clave a otro usuario, permisos incorrectos en ~/.ssh del servidor o estar conectando a un puerto diferente. No desactivaría todavía la entrada por contraseña: primero tiene que funcionar la clave desde cada equipo que necesitemos.

Crear un alias en ~/.ssh/config

Para no escribir la ruta de la clave, el usuario y el puerto en cada conexión, añadimos una entrada a ~/.ssh/config. Si el archivo no existe podemos crearlo; si ya contiene otros servidores, lo editamos sin borrar sus bloques.

Host servidor-casa
    HostName 192.0.2.25
    User usuario
    Port 22
    IdentityFile ~/.ssh/id_ed25519_servidor
    IdentitiesOnly yes

La dirección 192.0.2.25 es sólo un ejemplo y no corresponde a un servidor real. Host es el apodo que escribiremos; HostName debe contener la IP o dominio verdaderos. IdentitiesOnly yes evita que el cliente pruebe todas las claves cargadas en el agente antes de utilizar la indicada.

Ajustamos los permisos del archivo y comprobamos qué configuración interpreta SSH:

chmod 600 ~/.ssh/config
ssh -G servidor-casa | grep -E '^(hostname|user|port|identityfile) '
ssh servidor-casa

La opción -G no conecta: muestra la configuración final después de combinar el bloque del usuario, los valores globales y las opciones de la terminal. Es útil cuando un alias no está usando la identidad que esperábamos.

Usar ssh-agent sin quitar la frase de paso

En muchos escritorios ya existe un agente para conservar la clave desbloqueada durante la sesión. Podemos añadirla manualmente:

ssh-add ~/.ssh/id_ed25519_servidor
ssh-add -l

La primera orden pide la frase de paso una vez; la segunda enumera las huellas cargadas. Si indica que no puede conectar con el agente, antes de pegar comandos para arrancarlo conviene revisar cómo lo integra nuestro escritorio, porque GNOME, KDE y las distintas sesiones lo gestionan de manera diferente.

La documentación de OpenSSH sobre ssh-keygen explica los tipos de clave y sus archivos, y el manual de ssh_config recoge todas las opciones del cliente. Después de comprobar varias conexiones podemos plantearnos endurecer el servidor, pero es otra tarea: mezclar la creación de la clave con desactivar accesos puede dejarnos fuera por un pequeño error.

Si utilizáis varios servidores, contadnos si preferís una clave por equipo o separarlas por cliente y entorno.

Sergio Almela

Senior Software Engineer con más de diez años de experiencia. Escribo sobre Linux, software libre, backend, arquitectura, rendimiento, testing e IA aplicada al desarrollo.

Ver todas las entradas de Sergio Almela →