Mensaje de error
ssh: handshake failed: knownhosts: key is unknown
También se muestra como
- ssh: handshake failed: knownhosts: key mismatch
- ssh: must specify HostKeyCallback
`*knownhosts.KeyError` tiene un campo `Want`: vacío para «key is unknown» y no vacío para «key mismatch». «ssh: must specify HostKeyCallback» significa que el `ClientConfig` no tiene ninguna comprobación de la clave del host.
golang.org/x/crypto/ssh/knownhosts (Go) — *knownhosts.KeyError from the HostKeyCallback
Qué significa
La función de callback de `knownhosts` no encontró ninguna entrada para este host (y puerto) en tu archivo known_hosts, así que se negó a confiar en la clave que presentó el servidor. Así funciona la autenticación del host: sin una clave conocida, el cliente no puede distinguir el servidor real de un impostor. «key mismatch» es el caso hermano más grave: el host figura en la lista, pero con otra clave.
Por qué ocurre
El host nunca se añadió
frecuenteOpenSSH en modo interactivo pregunta «Are you sure you want to continue connecting?» y guarda la clave. Los programas de Go no preguntan, así que un host que nunca se añadió —o un contenedor recién creado con un known_hosts vacío— falla aquí.
Formato incorrecto del nombre de host o del puerto
frecuentePara los puertos distintos del 22, las entradas se escriben como `[host]:port`. Una entrada `host` sin más no coincide con una conexión al puerto 2222, y una dirección IP no coincide con una entrada registrada con el nombre DNS.
La clave del servidor cambió (key mismatch)
ocasionalLos servidores reinstalados, las IP de nube reutilizadas y los balanceadores de carga situados delante de varios hosts presentan claves nuevas. Una discrepancia también puede indicar una interceptación, así que debe resolverse comprobando la nueva huella digital, no eliminando la comprobación.
Cómo solucionarlo
- 1.
Añadir la clave del host después de verificarla
`ssh-keyscan` solo obtiene lo que te da la red. Compara la huella digital con una fuente de confianza antes de añadirla; incorpora las entradas verificadas a las imágenes o al aprovisionamiento.
bash # Fetch the host key, then compare its fingerprint with one obtained out of band # (cloud console, provisioning output, the server's /etc/ssh/*.pub). ssh-keyscan -t ed25519 -p 22 server.example.com > /tmp/hostkey ssh-keygen -lf /tmp/hostkey cat /tmp/hostkey >> ~/.ssh/known_hosts # only after the fingerprints match - 2.
Usar la forma entre corchetes para puertos personalizados
knownhosts compara el host y el puerto exactamente como lo hace OpenSSH. `knownhosts.Normalize` y `knownhosts.Line` generan desde Go entradas con el formato correcto.
text # known_hosts entry for a non-default port: brackets and the port are part of the name [server.example.com]:2222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...