Frequentemente crio e destruo máquinas virtuais e me conecto a elas via SSH.
O sistema operacional é RedHat Enterprise Linux versões 7 ou 8 (acontece com ambos) no lado do cliente e do servidor e, claro, openssh como servidor SSH.
A primeira conexão SSH sempre relatará a falta de chaves de host, a menos que eu use ssh-keyscan para pré-preencher meu arquivo known_hosts. É claro que isso é esperado.
Em seguida, configuro o sistema (geralmente usando o Ansible, mas também observei o problema antes mesmo do Ansible ser executado) e, inevitavelmente, toda vez, ao reconectar, o SSH relata que uma das chaves do host foi alterada.
Warning: the ED25519 host key for 'redacted' differs
from the key for the IP address 'redacted' Offending key for IP
in /redacted/.ssh/known_hosts:424 Matching host key in
/redacted/.ssh/known_hosts:362
Também verifiquei o /etc/ssh do lado do servidor e descobri que todas as chaves do host têm o mesmo carimbo de hora, portanto, a chave do host ED25519 não foi alterada.
-rw-r-----. 1 root ssh_keys 480 Aug 6 17:26 ssh_host_ecdsa_key
-rw-r--r--. 1 root root 162 Aug 6 17:26 ssh_host_ecdsa_key.pub
-rw-r-----. 1 root ssh_keys 387 Aug 6 17:26 ssh_host_ed25519_key
-rw-r--r--. 1 root root 82 Aug 6 17:26 ssh_host_ed25519_key.pub
-rw-r-----. 1 root ssh_keys 2.6K Aug 6 17:26 ssh_host_rsa_key
-rw-r--r--. 1 root root 554 Aug 6 17:26 ssh_host_rsa_key.pub
Estou procurando entender por que known_hosts primeiro é preenchido com uma chave ED25519 diferente daquela usada em conexões subsequentes.
Não estou procurando correções da natureza "editar seu arquivo known_hosts". Eu sei como fazer isso (consulte também Como corrigir o aviso sobre a chave do host ECDSA se quiser saber mais). Na grande escala que às vezes estou trabalhando (às vezes centenas de sistemas) é muito tedioso. Além disso, simplesmente manipular o arquivo known_hosts sem entender o motivo pelo qual uma chave foi alterada pode ser uma preocupação de segurança.
O que estou procurando é uma compreensão mais profunda do que está acontecendo e como evitar que isso aconteça, ou pelo menos como resolvê-lo automaticamente (sem comprometer a segurança!)
Atualização inspirada em Frank Thomas:
O problema acontece independentemente de eu ter reutilizado um endereço IP usado anteriormente ou um novo (a maioria é nova na minha situação).
Outra observação possivelmente relevante: no meu arquivo known_hosts, as chaves de host rsa e edcsa estão associadas ao FQDN. Existem duas entradas para as chaves do host ed25519. Um está associado ao FQDN, enquanto o outro está associado ao endereço IP.
O problema parece sempre se referir à versão da chave associada ao endereço IP.
Mais detalhes sobre como meu arquivo known_hosts é preenchido:
Primeiro, exclua todas as entradas de known_host existentes. O nome de host dos hosts getent obviamente retornará o endereço IP e o nome do host.
for host in $h $(getent hosts $h)
do
/usr/bin/ssh-keygen -R $host 2>&1 >/dev/null
done
Em seguida, recupere as novas chaves:
/usr/bin/ssh-keyscan $h 2>/dev/null >> ~/.ssh/known_hosts
Isso apenas preenche o rsa e a chave do host ED25519 pelo nome do host.
A chave do host ECDSA e a chave ED25519 por endereço IP são preenchidas pela primeira conexão SSH. Isso parece funcionar bem para a chave do host ECDSA, mas aparentemente não para a chave ED25519.
Parece que isso pode ser um bug no openssh.
As linhas 447 a 450 do meu arquivo known_hosts são:
As chaves nas duas últimas linhas correspondem e todas as quatro linhas se referem ao mesmo FQDN ou ao endereço IP correspondente.
O que me leva a concluir que isso é um bug no openssh é que a "chave incorreta" não é realmente uma chave ed25519. O openssh deve detectar isso e combiná-lo com o ecdsa-sha2-nistp256.
Depois de excluir a "chave incorreta" e conectar-se com o ssh novamente, a chave é preenchida corretamente com a chave ssh-ed25519 correta.
Ainda não sei por que essa chave é inicialmente preenchida com o tipo de chave errado.
Atualização: descobri que a população inicial parece estar relacionada à especificação de minhas próprias cifras no arquivo sshd_config, o que provavelmente é uma má ideia de qualquer maneira. Remover isso e remover a entrada CRYPTO_POLICY= em /etc/sysconfig/sshd parece ter resolvido o problema. Isso está no RedHat 8 (o RedHat 7 não possui uma política global de criptografia).