
Imaginemos el siguiente escenario.
Tengo una clave de host ABCDEF1234
para un nombre de host determinado, por lo que mi known_hosts
archivo se ve así (versión sin hash):
example.com ssh-rsa ABCDEF1234
Ahora me conecto y los nombres de host se resuelven en 10.11.12.13. Tengo un mensaje como este.
Warning: Permanently added the ECDSA host key for IP address '10.11.12.13' to the list of known hosts.
Y mis hosts_conocidos se ven así
example.com ssh-rsa ABCDEF1234
192.0.2.1 ssh-rsa ABCDEF1234
Ahora, unos meses después, example.com
el administrador me dice que la clave RSA se eliminó y se cambió a favor de 1234ABCDEF
la clave. Entonces elimino la clave ofensiva usando ssh-keygen -R example.com
, luego me conecto por primera vez, acepto la clave y sé que mi known_host
aspecto es el siguiente:
192.0.2.1 ssh-rsa ABCDEF1234
example.com ssh-rsa 1234ABCDEF
Y cada vez que me conecto tengo este bonito mensaje de advertencia:
Warning: the ECDSA host key for 'example.com' differs from the key for the IP address '192.0.2.1'
Offending key for IP in /home/jenkins/.ssh/known_hosts:162
Matching host key in /home/jenkins/.ssh/known_hosts:182
Ahora imagine que hay decenas o cientos de IP para ese nombre de host en particular, que son muchas líneas que limpiar. Una solución es usar sed
para eliminar líneas coincidentes, pero ¿no es el objetivo ssh-keygen -R
evitar jugar con ellas sed
?
sed -i '/ABCDEF1234/d' known_hosts
¿Existe otra solución que elimine todas las entradas de un known_host
archivo asociadas con una clave determinada, en lugar de un nombre de host o dirección IP?
Respuesta1
El propósito de ssh-keygen -R
no es evitar el uso de sed
, sino eliminar hosts con hash que, por ejemplo, sed
no se pudieron encontrar. Dessh-keygen(1):
-R hostname
Elimina todas las claves que pertenecen
hostname
a unknown_hosts
archivo. Esta opción es útil para eliminar hosts con hash (consulte la-H
opción anterior).
-H
Hash un
known_hosts
archivo. Esto reemplaza todos los nombres de host y direcciones con representaciones hash dentro del archivo especificado; el contenido original se mueve a un archivo con un.old
sufijo. Estos hashes pueden ser utilizados normalmente porssh
ysshd
, pero no revelan información de identificación en caso de que se divulgue el contenido del archivo. Esta opción no modificará los nombres de host con hash existentes y, por lo tanto, es segura de usar en archivos que combinan nombres con y sin hash.
Consideraciones
Evitar colisiones
Tenga en cuenta que es mejor utilizar la clave pública completa codificada en Base64 para evitar eliminar otras claves. Por ejemplo, si utiliza sólo partes delencabezamientoterminarías eliminando todas las claves del mismo tipo:
Base64 | ASCII | Árbitro. |
---|---|---|
AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY AAAAIbmlzdHAyNTYAAABBB |
....ecdsa-sha2-nistp256 ....nistp256...A |
RFC 5656, 3.1 |
AAAAC3NzaC1lZDI1NTE5AAAAIFKy |
....ssh-ed25519... R² |
RFC 8709, 4 |
AAAAB3NzaC1yc2EAAAADAQABAAABAQ |
...ssh-rsa........... |
RFC 4253, 6.6 |
Ajusta tu sed
para Base64
La clave pública codificada en Base64 contiene caracteres A-Za-z0-9+/=
. Como puede contener el /
carácter usado en su sed
ejemplo, le gustaría usar otro carácter como :
.
Ejemplos de trabajo
En los ejemplos:
- El
AAAA+OLD/KEY=
es un marcador de posición para elllenoantigua clave pública. - El
AAAA+NEW/KEY=
es un marcador de posición para elllenonueva clave pública.
Eliminar todos los hosts que tengan la misma clave
Utilice la clave antigua completa para eliminar todas las líneas que la contienen:
sed -i ':AAAA+OLD/KEY=:d' ~/.ssh/known_hosts
Reemplace la llave vieja por una nueva.
Utilice las claves completas (antiguas y nuevas) para reemplazarlas en todas las líneas que contengan la clave anterior:
sed -i 's:AAAA+OLD/KEY=:AAAA+NEW/KEY=:g' ~/.ssh/known_hosts
Si el tipo de clave también cambia, deberá incluirlo, por ejemplo,
sed -i 's:ssh-rsa AAAA+OLD/KEY=:ecdsa-sha2-nistp256 AAAA+NEW/KEY=:g' ~/.ssh/known_hosts
Eliminar claves para el nombre de host o IP
Este es el único caso de uso en el que usarías ssh-keygen
.
ssh-keygen -R example.com
ssh-keygen -R 192.0.2.1
Respuesta2
Evitar el problema en primer lugar es una buena solución. Siknown_hosts no estuviera lleno de entradas para todas y cada una de las IP de un nombre de host determinado, no habría necesidad de meterse con sed. ssh_keygen -R hostname
sería suficiente para realizar la rotación de claves.
Entonces mi solución a esto es configurar CheckHostIP
en no
la configuración ssh.