我们想象一下以下场景。
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
正常使用,但如果文件内容被泄露,它们不会泄露身份信息。此选项不会修改现有的哈希主机名,因此可安全地用于混合哈希和非哈希名称的文件。ssh
sshd
注意事项
避免碰撞
请注意,最好使用以 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 |
调整你的sed
Base64
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