注意事项

注意事项

我们想象一下以下场景。

ABCDEF1234我有一个给定主机名的主机密钥,因此我的known_hosts文件如下所示(未散列版本):

example.com ssh-rsa ABCDEF1234

现在我连接到它,主机名解析为 10.11.12.13,我收到如下消息

Warning: Permanently added the ECDSA host key for IP address '10.11.12.13' to the list of known hosts.

我的 known_hosts 看起来像这样

example.com ssh-rsa ABCDEF1234
192.0.2.1 ssh-rsa ABCDEF1234 

现在几个月后,example.com管理员告诉我 RSA 密钥已被删除并改为1234ABCDEF密钥。因此,我使用 删除了有问题的密钥ssh-keygen -R example.com,然后我第一次连接,接受密钥,并知道我的known_host样子如下:

192.0.2.1 ssh-rsa ABCDEF1234 
example.com  ssh-rsa 1234ABCDEF

每次我连接时都会收到以下警告信息:

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

现在想象一下,该特定主机名有数十或数百个 IP,需要清理的行数相当多。一种解决方案是使用sed删除匹配的行,但目标难道不是ssh-keygen -R避免弄乱sed吗?

sed -i '/ABCDEF1234/d' known_hosts

是否有其他解决方案,可以从known_host文件中删除与给定键(而不是主机名或 IP 地址)相关联的所有条目?

答案1

的目的ssh-keygen -R不是为了避免使用sed,而是为了删除散列主机,例如,sed无法找到的散列主机。从ssh-keygen(1)

-R hostname

hostname从文件中删除属于的所有密钥known_hosts。此选项对于删除散列主机很有用(请参阅-H上面的选项)。

-H

对文件进行哈希处理known_hosts。这会将指定文件内的所有主机名和地址替换为哈希表示;原始内容将移动到带有后缀的文件中。这些哈希值可由和.old正常使用,但如果文件内容被泄露,它们不会泄露身份信息。此选项不会修改现有的哈希主机名,因此可安全地用于混合哈希和非哈希名称的文件。sshsshd

注意事项

避免碰撞

请注意,最好使用以 Base64 编码的完整公钥,以避免删除其他密钥。例如,如果您只使用标题你最终会删除所有相同类型的键:

 Base64 ASCII 参考。
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

调整你的sedBase64

Base64 编码的公钥包含字符A-Za-z0-9+/=。由于它可以包含/您示例中使用的sed,因此您可能希望使用另一个字符,例如:

工作示例

在示例中:

  • AAAA+OLD/KEY=的占位符满的旧公钥。
  • AAAA+NEW/KEY=的占位符满的新的公钥。

删除所有具有相同密钥的主机

使用完整的旧密钥删除所有包含它的行:

sed -i ':AAAA+OLD/KEY=:d' ~/.ssh/known_hosts

用新密钥替换旧密钥

使用完整密钥(旧密钥和新密钥)在所有包含旧密钥的行上进行替换:

sed -i 's:AAAA+OLD/KEY=:AAAA+NEW/KEY=:g' ~/.ssh/known_hosts

如果密钥类型也发生变化,则必须将其包括在内,例如,

sed -i 's:ssh-rsa AAAA+OLD/KEY=:ecdsa-sha2-nistp256 AAAA+NEW/KEY=:g' ~/.ssh/known_hosts

删除主机名或 IP 的密钥

这是唯一会使用 的用例ssh-keygen

ssh-keygen -R example.com

ssh-keygen -R 192.0.2.1

答案2

首先避免这个问题是一个很好的解决方案。如果known_hosts没有为给定主机名的每个IP填写条目,那么就没有必要使用sed。ssh_keygen -R hostname足以执行密钥轮换。

所以我的解决方案是在 ssh 配置中CheckHostIP设置。no

SSH 选项 CheckHostIP=yes 到底对我有什么帮助?

相关内容