
Vamos imaginar o seguinte cenário.
Eu tenho uma chave de host ABCDEF1234
para um determinado nome de host, então meu known_hosts
arquivo fica assim (versão sem hash):
example.com ssh-rsa ABCDEF1234
Agora eu me conecto a ele e os nomes de host são resolvidos para 10.11.12.13. Tenho uma mensagem como esta
Warning: Permanently added the ECDSA host key for IP address '10.11.12.13' to the list of known hosts.
E meus conhecidos_hosts ficam assim
example.com ssh-rsa ABCDEF1234
192.0.2.1 ssh-rsa ABCDEF1234
Agora, alguns meses depois, example.com
o administrador me disse que a chave RSA foi removida e alterada em favor da 1234ABCDEF
chave. Então eu removo a chave incorreta usando ssh-keygen -R example.com
, depois me conecto pela primeira vez, aceito a chave e sei que minha known_host
aparência é assim:
192.0.2.1 ssh-rsa ABCDEF1234
example.com ssh-rsa 1234ABCDEF
E toda vez que me conecto recebo esta bela mensagem de aviso:
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
Agora imagine que existem dezenas ou centenas de IPs para esse nome de host específico, o que significa muitas linhas para limpar. Uma solução é usar sed
para remover linhas correspondentes, mas o objetivo não é ssh-keygen -R
evitar mexer com sed
?
sed -i '/ABCDEF1234/d' known_hosts
Existe outra solução que remova todas as entradas de um known_host
arquivo associado a uma determinada chave, em vez de um nome de host ou endereço IP?
Responder1
O objetivo ssh-keygen -R
não é evitar o uso sed
, mas remover hosts com hash que, por exemplo, sed
não foram encontrados. Dessh-keygen(1):
-R hostname
Remove todas as chaves pertencentes
hostname
a umknown_hosts
arquivo. Esta opção é útil para excluir hosts com hash (veja a-H
opção acima).
-H
Hash um
known_hosts
arquivo. Isso substitui todos os nomes de host e endereços por representações com hash no arquivo especificado; o conteúdo original é movido para um arquivo com um.old
sufixo. Esses hashes podem ser usados normalmente porssh
esshd
, mas não revelam informações de identificação caso o conteúdo do arquivo seja divulgado. Esta opção não modificará nomes de host com hash existentes e, portanto, é segura para uso em arquivos que misturam nomes com e sem hash.
Considerações
Evite colisões
Observe que é melhor usar a chave pública completa codificada em Base64 para evitar a remoção de outras chaves. Por exemplo, se você usar apenas partes docabeçalhovocê acabaria removendo todas as chaves do mesmo tipo:
Base64 | ASCII | Ref. |
---|---|---|
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 |
Ajuste seu sed
para Base64
A chave pública codificada em Base64 contém caracteres A-Za-z0-9+/=
. Como pode conter o /
usado no seu sed
exemplo, você gostaria de usar outro caractere como :
.
Exemplos de trabalho
Nos exemplos:
- O
AAAA+OLD/KEY=
é um espaço reservado para ocompletochave pública antiga. - O
AAAA+NEW/KEY=
é um espaço reservado para ocompletonova chave pública.
Remova todos os hosts com a mesma chave
Use a chave antiga completa para remover todas as linhas que a contêm:
sed -i ':AAAA+OLD/KEY=:d' ~/.ssh/known_hosts
Substitua a chave antiga por uma nova
Use as chaves completas (antigas e novas) para substituí-las em todas as linhas que contêm a chave antiga:
sed -i 's:AAAA+OLD/KEY=:AAAA+NEW/KEY=:g' ~/.ssh/known_hosts
Se o tipo de chave também mudar, você deverá incluí-lo, por exemplo,
sed -i 's:ssh-rsa AAAA+OLD/KEY=:ecdsa-sha2-nistp256 AAAA+NEW/KEY=:g' ~/.ssh/known_hosts
Remova as chaves do nome do host ou IP
Este é o único caso de uso em que você usaria ssh-keygen
.
ssh-keygen -R example.com
ssh-keygen -R 192.0.2.1
Responder2
Evitar o problema em primeiro lugar é uma boa solução. Seknown_hosts não fosse preenchido com entrada para cada IP de um determinado nome de host, não haveria necessidade de mexer com sed. ssh_keygen -R hostname
seria suficiente para realizar a rotação da chave.
Então, minha solução para isso é definir CheckHostIP
na no
configuração do ssh.