有没有一些可以用来验证 known_hosts 内容的命令行工具?也许可以尝试对其中的所有主机进行 ping 测试并查看是否能够连接到每个主机吗?
可能会使用 ssh-keygen
或 ssh-keyscan
?
有没有一些可以用来验证 known_hosts 内容的命令行工具?也许可以尝试对其中的所有主机进行 ping 测试并查看是否能够连接到每个主机吗?
可能会使用 ssh-keygen
或 ssh-keyscan
?
ssh-keyscan -t rsa,dsa -f hosts_list > ~/.ssh/known_hosts_revised
known_hosts_revised
文件,您可以将其与当前的know_hosts
文件进行对比以查看差异。... > ~/.ssh/known_hosts
即可覆盖它(警告:原始known_hosts
将会丢失!)hosts_list
是期望接受的内容:1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4
对于我的设置来说,使用ssh-keyscan
是不可能的,因为我有一个庞大的~/.ssh/config
文件。我使用了很多代理命令、跳板主机和替代的Hostname
声明。
例如:
# Connect to Tor nodes
Host *.onion
ProxyCommand socat - SOCKS4A:localhost:%h:%p,socksport=9050
# Work jump box
Host bastion
Hostname bastion.work.com
# Office system, e.g. bob.office -> bastion -> bob.work.com
Host *.office
ProxyCommand ssh bastion nc -w600s $(echo "%h" |sed 's/\.office$/work.com/') %p
# Home system, e.g. adam -> home.com -> adam-laptop.local
Host adam
Hostname adam-laptop.local
ProxyJump home.com
以上方法均不可行。
以下是一个应该适用于其余情况的脚本:
#!/usr/bin/awk -f
!/^#/ && NF > 2 {
split($1, hosts, ",")
key_type = $2
gsub(/^ssh-/, "", key_type)
gsub(/-.*/, "", key_type)
for (h in hosts) {
p = index(hosts[h], "]:") # [host]:port (supports raw IPv6 hosts)
if (!p && hosts[h] ~ /^[^:]+:[0-9]+$/) p = index(hosts[h], ":") # host:port
if (p > 0) {
port = substr(hosts[h], p + 2)
gsub("\[|\]?:" port, "", hosts[h])
} else {
port = 22
}
if (seen[key_type,port,hosts[h]]++) next # prevent duplicate lookups
if (port_list[key_type,port]) { comma = "," } else { comma = "" }
port_list[key_type,port] = port_list[key_type,port] comma hosts[h]
}
}
END {
for (tp in port_list) {
split(tp, a, SUBSEP)
system("echo ssh-keyscan -t " a[1] " -p " a[2] " " port_list[tp])
}
}
去掉 echo
部分,一旦您确信这将执行您想要的操作。
这个程序解析没有注释的行并且至少有3个字段(因为格式是 host_list key_type key_hash
)。它会将主机列表拆分,因为它可以逗号分隔,并且需要进一步解析,因为它可能包含端口,但 ssh-keyscan
不能接受以 known_hosts
使用的主机格式。
有两种指定端口的方式:
host:port
。[host]:port
。如果存在 ]:
字符串(新风格),则设置 p
为该位置。如果该字符串不存在,则检查旧风格并重置 p
。
如果 p
为正数,则有一个端口规范。提取端口并从主机名中删除它和方括号。否则,端口为22。
为了防止重复条目,我们检查它们并继续进行,如果我们已经看到了类型、端口和主机组合(只有第一次运行时x++
为false(0))。最后,我们将主机推送到以类型和端口为键的port_list
数组中的逗号分隔列表字符串。
在读取整个known_hosts文件后,我们迭代键控port_list
数组的type,port
元组对,将它们拆分成名为a
的数组,并在其上运行ssh-keyscan
。
像这样运行:awk -f 'this_script.awk' ~/.ssh/known_hosts
,如果你喜欢它输出的ssh-keyscan
命令,请从系统命令中删除echo
并重新运行。
不要将此输出管道传输到~/.ssh/known_hosts
!您需要手动审查结果(并可能过滤注释)。另外,您不能将输出重定向到输入中使用的文件之一。