是否有一些 cli 工具可以用来验证 known_hosts 的内容?也许尝试 ping 那里的所有主机,看看我是否可以连接到每个主机?
可能使用ssh-keygen
或者ssh-keyscan
?
是否有一些 cli 工具可以用来验证 known_hosts 的内容?也许尝试 ping 那里的所有主机,看看我是否可以连接到每个主机?
可能使用ssh-keygen
或者ssh-keyscan
?
如果你有所有可用主机的列表,你可以这样做:
ssh-keyscan -t rsa,dsa -f hosts_list > ~/.ssh/known_hosts_revised
这将生成一个新的known_hosts_revised
,您可以diff
使用当前创建一个know_hosts
以查看差异。
如果您不需要比较它,您可以简单... > ~/.ssh/known_hosts
地覆盖它(警告:原件known_hosts
将丢失!)
信息来源是ssh-keyscan(1)的 OpenBSD 手册页。
编辑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
设置为]:
if present(新样式)的位置。如果该字符串不存在,我们检查旧样式并重置p
。
如果p
是肯定的,我们有一个端口规范。提取端口并从主机名中删除(它和方括号)。否则,端口为 22。
以防有重复条目,如果我们已经看到类型、端口、主机组合(x++
仅在第一次运行时为 false (0)),我们会检查它们并继续。最后,我们将主机推送到数组中以逗号分隔的列表字符串,该字符串port_list
由类型和端口的元组作为键。
读入整个 known_hosts 文件后,我们迭代作为数组type,port
键的元组对port_list
,将它们拆分为一个名为 的数组a
,然后ssh-keyscan
在它们上运行。
像这样运行awk -f 'this_script.awk' ~/.ssh/known_hosts
,如果您喜欢ssh-keyscan
它吐出的命令,请echo
从系统命令中删除并重新运行。
不要将此输出通过管道传输到~/.ssh/known_hosts
! 您将需要手动查看结果(并可能过滤掉评论)。此外,您不能将输出重定向到输入中使用的文件之一。