许多服务(如 GitHub)使用广泛的 IP,并且显然使用相同的公钥。
如何将 IP 范围(最好是单个)添加到known_hosts 文件中?
对于 GitHub 示例,它使用以下范围:
- 207.97.227.224/27
- 173.203.140.192/27
- 204.232.175.64/27
- 72.4.117.96/27
- 192.30.252.0/22
关键是:
AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIckr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eF zLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3l GHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
答案1
正如其他答案中指出的,已知主机不支持 IP 地址范围。但是,它确实支持通配符。当然,通配符并不完全相同,因此您需要非常小心在 IP 地址中使用它们,但在 GitHub 的特殊情况下,这可以安全地完成。
自从这个问题问出来之后,情况似乎变得简单了。根据GitHub 的官方文档仅使用一个 IP 地址范围(至少就 IPv4 而言)。这是 192.30.252.0/22 范围。这使得 1020 个可能的 IP 地址可以方便地跨越四个不同 C 块中最后一个八位字节的整个可能范围。
从man 8 sshd
,这就是我们必须处理的已知主机:
Hostnames
是逗号分隔的模式列表(*
并?
充当通配符);每个模式依次与规范主机名(对客户端进行身份验证时)或用户提供的名称(对服务器进行身份验证时)进行匹配。模式前面也可以带有 来!
表示否定:如果主机名与否定模式匹配,则即使它与该行中的另一个模式匹配,也不会(被该行)接受。主机名或地址可以选择括在方括号内,[
然后]
是:
非标准端口号。
使用此信息,我们可以使用*
最后一个八位字节的通配符构造一个条目,该条目与所有可能的 GitHub 端点相匹配(并且仅有的这些端点)就像这样:
github.com,192.30.252.*,192.30.253.*,192.30.254.*,192.30.255.* ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
如果您需要构建的 IP 范围未填充完整的 C 块(因此填充八位字节的所有可能值),则不可能使用通配符进行如此准确的匹配。
答案2
我认为您无法轻松添加范围,但我认为(现在无法测试这一点)可以通过将以下内容添加到 .ssh/ssh_config 来实现相同的效果:
Host *.github.com
HostKeyAlias github-server-pool.github.com
接下来,您可以将密钥添加到名称为 github-server-pool.github.com 下的known_hosts 文件中。
假设:主机 github-server-pool.github.com 不存在或从未通过 SSH 连接到。
其背后的想法是,ssh 将使用密钥 github-server-pool.github.com 作为查找 github.com 域的所有主机的公共主机密钥的密钥。
答案3
文件中不支持 IP 地址集known_hosts
。每个地址必须有一行。
尽管默认情况下条目的主机名部分是经过哈希处理的,但这只是为了隐私,因此掌握您的人.known_hosts
将无法轻松找出您已连接到哪些主机。 (他们仍然可以验证猜测。)您可以使用普通主机名或 IP 地址。
for net in 207.97.227.224/27 173.203.140.192/27 204.232.175.64/27 72.4.117.96/27 192.30.252.0/24 192.30.252.1/24 192.30.252.2/24 192.30.252.3/24; do
base=${net%/*}; d=${base##*.}; abc=${base%.*}
bits=$((32 - ${net#*/}))
e=0
while [ $e -lt $((2 ** bits) ]; do
echo "$abc.$((d + e)) ssh-rsa AAAAB3NzaC1yc…" >>~/.ssh/known_hosts
e=$((e + 1))
done
done
请注意,这可能会添加重复项。
答案4
我编写了一个小型 Ruby 脚本,github_known_hosts
它可以扩展 GitHub 发布的 IP 地址范围元 API 端点(https://api.github.com/meta)。
#!/usr/bin/env ruby
require "ipaddr"
require "json"
pubkey = "AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=="
ips = JSON.parse(STDIN.read)["git"].flat_map { |net| IPAddr.new(net.chomp).to_range.map(&:to_s) }
puts "github.com,gist.github.com,#{ips.join(',')} ssh-rsa #{pubkey}"
像这样使用它,它会生成一个很长的行,您可以将其粘贴到文件中~/.ssh/known_hosts
:
curl --silent https://api.github.com/meta | github_known_hosts >> ~/.ssh/known_hosts