Qué es known_hosts y cómo verificar la huella de un host SSH

~/.ssh/known_hosts lista las claves públicas de host de los servidores a los que te has conectado, para que ssh detecte si un servidor presenta después una distinta. Para verificar una huella, ejecuta ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub en el servidor por un canal de confianza, como una consola, y compárala con lo que muestra ssh.

Actualizada el . ssh-keygen -F, -R, -H y -lf, ssh-keyscan, los valores de StrictHostKeyChecking y UpdateHostKeys=yes se ejecutaron con OpenSSH 10.3 en macOS contra OpenSSH 10.0 en Debian 13, con archivos known_hosts temporales.

Para qué sirve

Un cliente SSH necesita saber que habla con el servidor real antes de enviar una contraseña o ejecutar un comando. En la primera conexión muestra la huella del servidor y pregunta. Si aceptas, la clave pública se guarda en known_hosts. En las conexiones siguientes la comprobación es automática, y una clave distinta provoca el error REMOTE HOST IDENTIFICATION HAS CHANGED.

El archivo solo contiene claves públicas. No tiene secretos, pero sí revela qué servidores usas.

El formato

203.0.113.10 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYt...
[server]:2222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMJi...
server,203.0.113.10 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB...

Cada línea tiene los nombres de host, el tipo de clave y la clave. Un puerto distinto de 22 se escribe entre corchetes, como [server]:2222. Los nombres pueden ser una lista separada por comas y admiten comodines. Pueden ir antes dos marcadores opcionales: @cert-authority para la clave de una CA, y @revoked para una clave que no debe aceptarse nunca. Con los certificados de host SSH, una sola línea de la CA puede sustituir una línea por cada servidor.

El cliente también lee un archivo global, /etc/ssh/ssh_known_hosts, que un administrador puede rellenar para todos.

Entradas con hash

|1|eoQ3SZFlQ/5gRWuuw3MoS+AtytA=|BlzFc5MrVrt8iIEm7rloTmKPRBo= ssh-ed25519 AAAAC3Nz...

Una línea que empieza por |1| tiene el nombre de host con hash, de modo que quien robe el archivo no obtiene una lista lista para usar de tus servidores. ssh sigue encontrándola. Lo controla HashKnownHosts. El valor por defecto de OpenSSH es no, pero Debian lo activa en /etc/ssh/ssh_config, así que verás ambas formas.

Para aplicar el hash a un archivo existente:

ssh-keygen -H

Esto conserva el original como known_hosts.old, en texto plano. Borra esa copia si lo hiciste por privacidad.

Comandos del día a día

Funcionan también con archivos con hash. Añade -f file para usar un archivo distinto del predeterminado.

ObjetivoComando
Encontrar la entrada de un hostssh-keygen -F server
Encontrar una en otro puertossh-keygen -F '[server]:2222'
Mostrar la huella de ese hostssh-keygen -lF server
Listar todas las huellasssh-keygen -lf ~/.ssh/known_hosts
Eliminar un hostssh-keygen -R server

Con -F, el código de salida es 1 si el host no se encuentra, lo que resulta útil en scripts. -R sale con 0 en ambos casos.

Cómo verificar una huella

En la primera conexión ves esto:

The authenticity of host 'server (203.0.113.10)' can't be established.
ED25519 key fingerprint is: SHA256:iU7+QOFWSHJeCFBdzU31dTOoJRNhncp+Wzw3UJMzasU
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Escribir yes sin comprobar es confiar en lo que haya respondido. Para comprobarlo bien, obtén el valor desde un lugar que no pase por esta conexión, como la consola de tu proveedor, o de la persona que administra el servidor. En el servidor:

sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

Compara los valores, o pega la huella correcta en el prompt en lugar de yes, y ssh hace la comparación por ti. En nuestra prueba se aceptó el valor correcto, y uno incorrecto dio Please type 'yes', 'no' or the fingerprint:.

ssh-keyscan y su problema de confianza

ssh-keyscan -t ed25519 server >> ~/.ssh/known_hosts

Esto obtiene la clave pública de un servidor y se ve con frecuencia en scripts de instalación y trabajos de CI. El problema es que no comprueba nada. Registra lo que haya respondido, así que un atacante en el camino consigue que se registre su clave, y desde ese momento el ataque es invisible.

Está bien si verificas el resultado después:

ssh-keyscan -t ed25519 server | ssh-keygen -lf -

Para CI, es mejor guardar la línea esperada de known_hosts como un valor en tu pipeline y escribirla en el archivo.

Valores de StrictHostKeyChecking

ValorHost nuevoClave cambiada
ask (por defecto)Te preguntaRechaza
yesRechazaRechaza
accept-newLo añadeRechaza
no u offLo añadeConecta, con restricciones

accept-new es la opción razonable para la automatización: confía en el primer uso y detecta cambios posteriores. yes es la más estricta y encaja en flotas donde distribuyes tú mismo known_hosts. Con ella, un host desconocido da:

No ED25519 host key is known for server and you have requested strict checking.
Host key verification failed.

Evita no. Conecta con un host cuya clave ha cambiado, que es justo el caso que este archivo existe para detectar.

UpdateHostKeys

Un servidor puede informar al cliente de todas sus claves de host tras el inicio de sesión. Con UpdateHostKeys, el cliente las añade a known_hosts, lo que permite a un administrador añadir una clave nueva, esperar a que los clientes la aprendan y luego quitar la antigua sin avisos. Probamos UpdateHostKeys=yes: partiendo solo de la entrada ED25519, un inicio de sesión añadió líneas RSA y ECDSA.

El manual dice que está activado por defecto si no has cambiado UserKnownHostsFile y no has activado VerifyHostKeyDNS. Solo acepta claves de un host en el que ya se confía a través de tu propio archivo, no de un archivo global, y no se aplica cuando el host se autenticó con un certificado.

SSHFP: huellas en DNS

Las huellas de las claves de host también se pueden publicar en DNS como registros SSHFP. Esto imprime los registros que hay que añadir para un servidor, ejecutado en ese servidor:

ssh-keygen -r example.com

Los clientes los usan con VerifyHostKeyDNS yes. Solo se confía en ellos automáticamente cuando la respuesta DNS es segura, lo que en la práctica significa zonas firmadas y un resolvedor que las valide. En otro caso se comporta como ask: te muestra la coincidencia y tú aún tienes que confirmar. El valor por defecto es no.

Preguntas

¿Dónde está el archivo known_hosts?

En ~/.ssh/known_hosts, dentro de tu carpeta personal, en cualquier sistema con OpenSSH. También puede haber un archivo para todo el sistema en /etc/ssh/ssh_known_hosts.

¿Se puede borrar known_hosts?

Solo contiene claves públicas, así que no pierdes nada secreto. Pero ssh volverá a preguntar por cada servidor y pierdes la comprobación que detecta una clave cambiada. Mejor quita un solo host con ssh-keygen -R.

¿Cómo quito un host de known_hosts?

Ejecuta ssh-keygen -R server, escrito como '[server]:2222' si el puerto no es el 22. También funciona con archivos con hash.

Fuentes

Más en Mensajes de error

Todas las guías