"¿Añadir la clave de host correcta en conocido_hosts" / múltiples claves de host ssh por nombre de host?

147

Tratando de ingresar a una computadora que controlo, recibo el mensaje familiar:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    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 RSA key sent by the remote host is
[...].
Please contact your system administrator.
Add correct host key in /home/sward/.ssh/known_hosts to get rid of this message.
Offending RSA key in /home/sward/.ssh/known_hosts:86
RSA host key for [...] has changed and you have requested strict checking.
Host key verification failed.

De hecho, cambié la clave. Y leí unas pocas docenas de publicaciones que decían que la forma de resolver este problema es eliminar la clave anterior del known_hostsarchivo.

Pero lo que me gustaría es que ssh acepte tanto la clave antigua como la nueva clave. El idioma en el mensaje de error (" Add correct host key") sugiere que debería haber alguna forma de agregar la clave de host correcta sin eliminar la anterior.

No he podido descubrir cómo agregar la nueva clave de host sin eliminar la anterior.

¿Es esto posible o el mensaje de error es extremadamente engañoso?

Samuel Edwin Ward
fuente
99
Esta es la clave de host que genera el error. Un host debe tener una y solo una clave. Esto no tiene nada que ver con las claves de cliente o usuario. ¿Tiene una dirección IP que flota entre hosts distintos o algo así?
David Schwartz
44
En mi caso, sé que voy a cambiar mucho entre las dos teclas en el futuro cercano mientras jugueteo con algunas cosas. Parece que esto también sería útil en la única IP con la situación de múltiples hosts que sugiere. Principalmente solo quiero saber si esto es posible para mi propia educación, aparte de cualquier aplicación práctica en particular.
Samuel Edwin Ward,

Respuestas:

148
  1. obtenga la clave rsa de su servidor, donde server_ipestá la dirección IP de su servidor, como 192.168.2.1:

    $ ssh-keyscan -t rsa server_ip
    

    Respuesta de muestra:

    # server_ip SSH-2.0-OpenSSH_4.3
    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG...
    
  2. y en el cliente, copie la línea de respuesta completa server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG...y agregue esta clave al final de su ~/.ssh/known_hostsarchivo:

    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAqx9m529...(the offending key, and/or the very bottom of the `known_hosts` file)
    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG... (line you're adding, copied and pasted from above)
    
quanta
fuente
12
Esto funcionó! Sin embargo, estoy usando "HashKnownHosts", por lo que la entrada parecía un poco fuera de lugar. Afortunadamente, ssh_config (5) me señaló a ssh-keygen (1), lo que explicaba que puedo usar "ssh-keygen -H" para hacer hash en las entradas no compartidas. ¡Gracias!
Samuel Edwin Ward,
2
Esto "funciona" pero no está verificando la clave, por lo que es vulnerable a los ataques mitm ...
JasperWallace
3
@JasperWallace, siempre y cuando primer paso se realiza en conexión segura (por ejemplo, usando localhost) que debe ser bastante segura, creo
ony
3
¿Hay alguna forma de reunir todos los tipos de clave del servidor? A veces no sabes si son RSA, DSA, ECDSA, RSA1 ... etc.
Sopalajo de Arrierez
3
@SopalajodeArrierez la misma página de manual también se dice que se puede separar por comas tipos, también lo hacen ssh-keyscan -t rsa1,dsa,rsa,ecdsa,ed25519 server_ip- pero la única razón para encontrar rsa1y dsaclaves es identificar los servidores que necesitan ser actualizados / reconfigurado
kbolino
94

Elimina esa entrada de known_hosts usando:

ssh-keygen -R *ip_address_or_hostname*

Esto eliminará la IP problemática o el nombre de host del archivo known_hosts e intentará conectarse nuevamente.

De las páginas del manual:

-R hostname
Elimina todas las claves que pertenecen al nombre de host de un archivo conocido_hosts. Esta opción es útil para eliminar hosts hash (consulte la opción -H más arriba).

Luis Abarca
fuente
11
"cómo agregar la nueva clave de host sin eliminar la anterior".
Samuel Edwin Ward
44
Esta es la mejor solución !
Thomas Decaux
8
¿Cómo tiene esto 19 votos? No se acerca a responder la pregunta que se hizo ..
Molomby
2
Su pregunta aparece en segundo lugar cuando busco en Google "clave de host de actualización git ssh automáticamente". Esta respuesta es lo que estaba buscando. Abrir una nueva pregunta con exactamente lo que quiero podría cerrarlo como un duplicado.
Jason Goemaat
El nombre de host también funciona
damluar el
18

Una forma muy simple es:

cp ~/.ssh/known_hosts ~/.ssh/known_hosts.bak

Luego edite known_hosts para borrar la clave original, luego ssh al host usando:

ssh name@computer

Agregará la nueva clave automáticamente; luego compare los dos archivos. Un programa como meld es una buena manera de comparar los dos archivos. Luego, combine los archivos para hacer conocido_hosts que contengan ambas claves

Mi 'razón' para mantener dos claves es que el sistema de destino es de arranque múltiple, aunque me atrevo a decir que hay una forma de sincronizar las claves en las instalaciones, parece más sencillo permitir múltiples claves.

EDITAR 2015/06

Debo agregar, revisándolo ahora, que noto una forma aún más simple [siempre que la entrada sea identificable, normalmente desde el nombre de host / dirección IP, aparte del mensaje de error que hace referencia a su ubicación específica];

  1. Edite conocido_hosts para agregar # al comienzo de la entrada 'antigua' en conocido_hosts temporalmente
  2. Conéctese [ssh al host], acepte la solicitud para agregar la nueva clave 'automáticamente'
  3. Luego vuelva a editar known_hosts para eliminar el #

Incluso hay la opción HostKeyAlias ​​como en

ssh -o HostKeyAlias=mynewaliasforthemachine name@computer

luego, después de que el cliente ssh agregue la nueva clave bajo el alias, puede editar conocido_hosts para sustituir el nombre de host / dirección 'real' por el alias o conectarse a esa encarnación de ese host con la opción de alias.

marca
fuente
Esta 'fusión'? meldmerge.org
Samuel Edwin Ward
esa es la fusión :) nombre de instalación apt-get / yum es simplemente fusión
Mark
Hice una variante de su sugerencia que funcionó bien: en lugar de cp, mv, luego ssh, luego cat ~ / .ssh / known_hosts.bak ~ / .ssh / known_hosts> tmp; mv tmp ~ / .ssh / known_hosts
Peter N Lewis
6

Tengo el mismo problema con un raspberry pi que arranco con varios sistemas diferentes (sistema de desarrollo para compilar binarios de brazo, proyecto, xbmc, etc.) y me he encontrado con el mismo problema. Utilizan DHCP en una red local y mi enrutador siempre reutilizaba la misma IP ya que la dirección MAC era la misma. Lo resolví usando diferentes nombres de dominio en mi archivo de hosts:

10.10.10.110 pi-dev
10.10.10.110 pi-xbmc
10.10.10.110 pi-etc

El archivo known_hosts guarda las huellas digitales por nombre de host, por lo que, aunque es la misma dirección IP, cada nombre de host único obtiene una entrada diferente.

Me cansé de agregar los nombres a los archivos de host cada vez que usaba un nuevo sistema, así que se me ocurrió una forma aún más perezosa al usar ceros a la izquierda en direcciones IP como:

$ ssh [email protected]
$ ssh [email protected]
$ ssh [email protected]

Cada variación de la dirección IP (no canonizada) obtiene su propia entrada en conocido_hosts.

Miguel
fuente
1
La gente de OpenSSH me entendió, esta escapatoria ya no funciona en versiones más recientes.
Mike
Se puede utilizar CheckHostIP noen ~/.ssh/configpoder seguir utilizando la escapatoria. Incluso puede definir sus alias allí para que no tenga que jugar /etc/hostsy definir CheckHostIP nosolo para estos 3 nombres de host.
GnP
3

Si tanto su cliente como su servidor tienen OpenSSH 6.8 o posterior, puede usar la UpdateHostKeys yesopción en su ssh_configo ~/.ssh/config. Por ejemplo:

Host *
    UpdateHostKeys yes

Esto hace que SSH almacene todas las claves de host que tiene que tener el servidor known_hosts, y cuando un servidor cambia o elimina una clave de host, la clave también se cambia o elimina en su known_hosts.

Mikaela
fuente
¡Esta es, con mucho, la respuesta más útil! Aunque no ofrece explícitamente una forma de resolver la pregunta original si ya se cambió una clave de host, todas las otras respuestas son inseguras ya que no verifican la nueva clave de host. Esta opción le permite hacer una transferencia segura a nuevas claves de host.
Jaap Eldering
1

No veo por qué quiere trabajar con dos claves, pero ciertamente puede agregar más de una clave válida al ~/.ssh/known_hostsarchivo, pero tendrá que hacerlo manualmente.

Otra solución podría ser utilizar la StrictHostKeyChecking=noopción para este host específico:

ssh -o StrictHostKeyChecking=no user@host

que podrías poner en un alias en tu ~/.profileo algo similar.

alias hc=ssh -o StrictHostKeyChecking=no user@host
Sven
fuente
StrictHostKeyChecking no parece ayudar en este caso; aparentemente solo especifica el comportamiento cuando el host no está en el archivo known_hosts. Mencionado aquí: gossamer-threads.com/lists/openssh/dev/45349#45349
Samuel Edwin Ward
Funciona aqui. Recibirá la advertencia, pero el inicio de sesión continúa.
Sven
Eso es extraño. ¿Estás utilizando la autenticación de contraseña? ¿Estás usando OpenSSH?
Samuel Edwin Ward,
1

Si solo ssh en una red local, entonces ...

Una solución simple es borrar el archivo de clave anterior y reemplazarlo por uno en blanco. Esto le permitirá volver a autorizar todas sus conexiones con nuevas claves. Si tiene claves ssh almacenadas para sitios fuera de su red local, debe asegurarse de que su conexión inicial sea segura como lo hizo la primera vez que se conectó a ese servidor.

p.ej

cp known_hosts known_hosts.old
rm known_hosts
nano known_hosts

Luego presione la barra espaciadora, retroceda cntl + x e 'y' para guardar el nuevo búfer (archivo). Es una mala práctica, pero está bien, siempre y cuando no esté regularmente fuera de su red local (por ejemplo, un servidor uni o de trabajo)

En una red local segura, esto es seguro porque simplemente no puedes encontrar a un hombre en el medio del ataque.

¡Siempre es mejor usar el código que entiendes!

Aaron
fuente
44
Limpiar todo el known_hostsarchivo cada vez va a negar la mayor parte de la seguridad proporcionada por ssh.
kasperd
De hecho, diría que en una red interna segura, es más seguro comprender su código y evadir la seguridad que copiarlo sin pensar. En una red externa, la situación sería diferente.
Aaron
-1

Tantas respuestas, pero tantas que renuncian a la protección desactivando totalmente la comprobación estricta del host, o destruyendo información del host no relacionada o simplemente obligando al usuario a aceptar claves interactivamente, posiblemente en un momento posterior, cuando es inesperado.

Aquí hay una técnica simple que le permite dejar un host estricto comprobando, pero actualizar la clave de forma controlada, cuando espera que cambie:

  • Elimine la clave anterior y actualice en un comando

    ssh-keygen -R server.example.com && \
        ssh -o StrictHostKeyChecking=no server.example.com echo SSH host key updated.
    
  • Repita con las direcciones IP u otros nombres de host si los usa.

La ventaja de este enfoque es que modifica el servidor exactamente una vez. La mayoría de las versiones de ssh-keygen parecen no devolver un error si el servidor que intenta eliminar no existe en el archivo de hosts conocidos, si esto es un problema para usted, use los dos comandos en secuencia.

Este enfoque también verifica la conectividad y emite un buen mensaje para los registros en el comando ssh (que inicia sesión, actualiza la clave del host y genera la clave del host SSH actualizada y luego sale inmediatamente).

Si su versión de ssh-keygen devuelve un código de salida distinto de cero, y prefiere manejar esto sin error, independientemente de la conexión previa, simplemente use los dos comandos en secuencia, ignorando cualquier error en el comando ssh-keygen.

Si utiliza esta técnica, nunca necesitará modificar su comando ssh, ni desactivar la comprobación del host, excepto durante ese comando ssh. Puede estar seguro de que las futuras sesiones ssh funcionarán sin conflictos o la necesidad de aceptar explícitamente una nueva clave, siempre que el comando ssh anterior se ejecute sin error.

markgo2k
fuente
-3

Yo tuve el mismo problema.

Todo lo que hice fue sudo nano /home/user/.ssh/ host_allowborrar la llave.

Cuando vuelvo al servidor, agrega una nueva clave.

david
fuente
2
Un poco más de información sobre por qué sucede esto sería útil para la respuesta.
Drew Khoury
-4

Use el comando sed para eliminar la línea ofensiva

OUTPUT: as show in above example
Offending key in /home/user/.ssh/known_hosts:86

Elimine la línea 86 como se menciona en los hosts conocidos.

CODE: 
sed -i '86d' /home/user/.ssh/known_hosts

La próxima vez que acceda mediante ssh, el sistema agregará automáticamente una nueva clave.

nuevas versiones de ssh

utilizar:

ssh-keygen -R <hostname|ip address>

Eliminará la entrada del nombre de host y tomará una copia de seguridad de la antigua .known_hostcomoknown_hosts.old

Viikram Simha
fuente
44
"Pero lo que me gustaría es que ssh acepte la clave antigua y la clave nueva". Tu respuesta no hace esto.
Samuel Edwin Ward