是否可以使用一些cli工具来验证known_hosts的内容?也许尝试对其中的所有主机执行ping操作,看看我是否可以连接到每个主机?
可能使用ssh-keygen
或ssh-keyscan
吗?
答案 0 :(得分:3)
如果您有所有可用主机的列表,则可以这样做:
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
答案 1 :(得分:1)
至少由于我的设置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++
仅在首次运行时为假(0),则继续)。最后,我们将主机推入port_list
数组中以逗号分隔的列表字符串,并以类型和端口的元组为键。
在读取了整个known_hosts文件之后,我们迭代type,port
元组对,这些元组对将port_list
数组作为键,将它们拆分为名为a
的数组,然后运行{{1} }。
像ssh-keyscan
一样运行,如果您喜欢它弹出的awk -f 'this_script.awk' ~/.ssh/known_hosts
命令,请从系统命令中删除ssh-keyscan
并重新运行。
请勿将此输出传递到echo
!。您将要手动查看结果(并可能过滤掉注释)。另外,您不能将输出重定向到输入中使用的文件之一。