验证.ssh / known_hosts文件的内容

时间:2019-05-14 00:26:00

标签: ssh unknown-host ssh-keygen ssh-config ssh-keyscan

是否可以使用一些cli工具来验证known_hosts的内容?也许尝试对其中的所有主机执行ping操作,看看我是否可以连接到每个主机?

可能使用ssh-keygenssh-keyscan吗?

2 个答案:

答案 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使用的格式的主机。

可以通过两种方式指定端口:

  1. 不适用于裸IPv6地址的旧样式为host:port
  2. 裸机IPv6地址所需的新样式为[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。您将要手动查看结果(并可能过滤掉注释)。另外,您不能将输出重定向到输入中使用的文件之一。