El mensaje
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:iU7+QOFWSHJeCFBdzU31dTOoJRNhncp+Wzw3UJMzasU.
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in /home/user/.ssh/known_hosts:1
Host key for server has changed and you have requested strict checking.
Host key verification failed.
Un servidor demuestra su identidad con su clave de host. Tu ordenador guardó esa clave la primera vez que te conectaste. Ahora ha recibido otra distinta, y ssh se detuvo antes de enviar nada. Los dos datos que necesitas son la huella nueva (la línea SHA256:) y el lugar de la entrada antigua (known_hosts:1 es la línea 1). En Debian y Ubuntu el mensaje también sugiere un comando ssh-keygen -R: ejecútalo solo después de la comprobación de abajo.
¿Causa legítima o ataque?
Causas inofensivas habituales:
- El servidor se reconstruyó, reinstaló o restauró, lo que suele crear claves de host nuevas.
- La dirección ahora pertenece a otra máquina: una VM nueva en una IP de nube reutilizada, o una Elastic IP que se movió.
- Un balanceador de carga o un par de conmutación por error te lleva a una máquina con claves distintas.
- Un puerto reenviado como
localhost:2222ahora lleva a otro sitio. - Un administrador o un servicio cambió las claves, como hizo GitHub con su clave de host RSA en marzo de 2023.
- El servidor ya no ofrece el tipo de clave que guardaste. En nuestra prueba, un servidor limitado a RSA provocó esta advertencia en un cliente que había guardado su clave ED25519.
Desconfía cuando nadie sabe explicar el cambio, cuando aparece solo en una red como el Wi-Fi público, o cuando se trata de un servidor que nadie tocó. Hasta que lo sepas, no escribas una contraseña ni ejecutes nada en él. Probar desde otra red ayuda: si las huellas difieren entre redes, algo en una de ellas está interfiriendo.
Comprueba la huella nueva por otra vía
Por otra vía (out of band) significa por un canal que un atacante en esta conexión no pueda controlar: la consola web del proveedor, una consola serie, acceso físico o un compañero con acceso verificado. En el servidor, ejecuta:
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
256 SHA256:iU7+QOFWSHJeCFBdzU31dTOoJRNhncp+Wzw3UJMzasU root@server (ED25519)
Usa el archivo del tipo de clave que nombra la advertencia: ssh_host_rsa_key.pub o ssh_host_ecdsa_key.pub para los demás. El valor debe coincidir exactamente con la advertencia. Algunas imágenes en la nube también imprimen las huellas en el registro de la consola en el primer arranque.
El comando de abajo solo muestra lo que envía el servidor que está en el camino de tu red actual. Es útil para leer un valor, pero por sí solo no prueba nada, porque un atacante le enviaría la misma clave falsa:
ssh-keyscan -t ed25519 server | ssh-keygen -lf -
Elimina la clave antigua
ssh-keygen -R server
# Host server found: line 1
/home/user/.ssh/known_hosts updated.
Original contents retained as /home/user/.ssh/known_hosts.old
Esto funciona incluso con nombres cifrados con hash, y no tienes que editar el archivo a mano. Usa el mismo nombre con el que te conectas. Algunas configuraciones necesitan más de una llamada:
ssh-keygen -R 203.0.113.10
ssh-keygen -R '[server]:2222'
La segunda forma es para un servidor en un puerto distinto del 22.
Vuelve a conectar y compara
ssh user@server
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])?
Compara, o mejor aún, pega en este aviso la huella que obtuviste de la consola. ssh las compara por ti, y vuelve a preguntar si no coinciden.
Por qué no StrictHostKeyChecking=no
Es el consejo que encontrarás con más frecuencia, y elimina la protección por completo. Lo probamos contra una clave cambiada. Sigue imprimiendo la advertencia y luego continúa:
Password authentication is disabled to avoid man-in-the-middle attacks.
Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.
Agent forwarding is disabled to avoid man-in-the-middle attacks.
El acceso con clave siguió funcionando, así que estás trabajando en un servidor que no has verificado, y todo lo que escribas o copies allí puede llegar a un atacante. Poner UserKnownHostsFile=/dev/null hace un daño parecido: nunca se recuerda nada, así que nunca se puede comprobar nada.
Para scripts que se encuentran con hosts nuevos, usa StrictHostKeyChecking=accept-new. Guarda las claves de los hosts nuevos y sigue rechazando una clave cambiada, como confirmamos. Mira known_hosts explicado.
Para scripts y CI que se detienen con una sola línea, consulta Host key verification failed en scripts y CI.
Evita ver esta advertencia en cambios planificados
- Cuando reconstruyas un servidor, restaura sus claves de host antiguas desde tu copia de seguridad segura, si tu política lo permite.
- Para un conjunto de máquinas detrás de un nombre, usa certificados de host, para que los clientes confíen en una CA y no en cada clave.
- Para rotar claves, añade primero la clave nueva y deja que los clientes la aprendan con
UpdateHostKeys, y solo entonces elimina la antigua.
Preguntas
¿Basta con ejecutar ssh-keygen -R?
Solo después de confirmar la nueva huella por otro canal. El comando quita el aviso, no su causa, así que por sí solo puede ocultar un ataque.
¿Por qué aparece el aviso después de reinstalar el servidor?
Una reinstalación suele crear claves de host nuevas, así que la clave ya no coincide con la guardada en known_hosts. Compara la nueva huella desde la consola y luego borra la entrada antigua.
¿StrictHostKeyChecking=accept-new evita este aviso?
No. accept-new solo guarda claves de hosts que nunca ha visto. Una clave cambiada se sigue rechazando.
Fuentes
- ssh(1), Verifying host keys
- ssh_config(5), StrictHostKeyChecking
- ssh-keygen(1), manual de OpenBSD
- Solución de problemas al conectar a una instancia Linux de EC2, AWS