如何移除known_hosts文件中所有包含指定公钥的条目?
如何移除known_hosts文件中所有包含指定公钥的条目?
兄弟我太懂你这种头疼的场景了——当一个域名对应几十上百个IP,换了主机密钥后,光用ssh-keygen -R example.com删除域名对应的条目根本没用,那些关联旧密钥的IP条目还躺在known_hosts里,每次连接都弹出烦人的警告,手动删或者逐个处理完全不现实。
下面给你几个可行的解决方案,按需选择:
一、先明确:ssh-keygen没有直接按公钥删除的原生选项
OpenSSH自带的ssh-keygen工具,它的-R选项只能针对主机名、IP地址,或者哈希后的主机标识来删除条目,并没有直接通过公钥内容批量删除所有匹配行的内置功能——这点确实有点遗憾。
二、用ssh-keygen结合文本工具间接批量删除(更“原生”的思路)
如果你不想直接用sed,可以先找出所有关联旧密钥的主机/IP,再批量用ssh-keygen -R删除。假设你的旧密钥是ABCDEF1234,可以用下面的命令:
for host in $(ssh-keygen -l -f ~/.ssh/known_hosts | grep "ABCDEF1234" | awk '{print $3}'); do ssh-keygen -R "$host" done
命令解释:
ssh-keygen -l -f ~/.ssh/known_hosts:列出known_hosts中每个条目的密钥指纹、类型和对应的主机/IP;grep "ABCDEF1234":过滤出包含旧密钥的行;awk '{print $3}':提取行中的主机/IP部分;- 循环用
ssh-keygen -R删除每个对应的条目。
注意:这个方法只适合未哈希的known_hosts文件(就像你例子里的那样),如果你的
known_hosts是哈希加密的(默认可能开启了HashKnownHosts),主机/IP会显示为乱码,这个方法就不适用了。
三、最直接高效:用sed一键删除所有匹配条目
虽然你一开始想避免sed,但不得不说,它是处理这种批量删除场景最快捷的方式——只要你确认旧密钥是唯一的(不会和其他条目重复),这个命令绝对安全高效:
sed -i '/ABCDEF1234/d' ~/.ssh/known_hosts
这个命令会直接删除known_hosts中所有包含ABCDEF1234的行,一步到位,几百条IP也能瞬间处理完。
四、预防未来踩坑的小建议
如果经常遇到这种多IP对应单域名的场景,可以试试这些方法减少麻烦:
- 开启
HashKnownHosts yes(在/etc/ssh/ssh_config或~/.ssh/config中配置):虽然会哈希主机名/IP,不好手动查找,但更安全,也能避免一些无关的IP关联问题; - 在SSH配置中指定
HostKeyAlgorithms,强制只使用特定类型的密钥(比如只允许rsa-ssh),减少不同密钥类型的冲突; - 对于大量管理的主机,使用单独的
UserKnownHostsFile配置,把不同集群的主机密钥分开存储,方便批量管理。
备注:内容来源于stack exchange,提问作者shodanex
相关产品推荐
相关产品推荐

