我有两台运行 OpenBSD v6.9 的机器。让我们原创一下,将它们称为客户端和服务器。
我使用以下命令在服务器上生成了 SSHFP 记录:
ssh-keygen -r host.domain.tld
Run Code Online (Sandbox Code Playgroud)
在 DNS 区域中,我使用以下行添加了 SSHFP 记录:
host IN SSHFP 1 2 02323a6fb8a12eba9288930ce2513fc94970e5575996ebede1ee352bd039c531
host IN SSHFP 4 2 3eef5929fe85038b2e2a7de70897175e7b0d68328b41ef6466a2fa06f9a8bb49
Run Code Online (Sandbox Code Playgroud)
sshd 配置为仅使用 Ed25519 主机密钥,但我也保留 RSA 主机密钥以备将来需要。
DNS 区域使用 DNSSEC 进行签名,所有内容均通过“https://dnsviz.net/”和“https://dnssec-debugger.verisignlabs.com/”进行验证。
在客户端,有一个带有 DNSSEC 验证器的 Unbound 解析器:
dig host.domain.tld -t SSHFP
; <<>> dig 9.10.8-P1 <<>> host.domain.tld -t SSHFP
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9525
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;host.domain.tld. IN SSHFP
;; ANSWER SECTION:
host.domain.tld. 3600 IN SSHFP 4 2 3eef5929fe85038b2e2a7de70897175e7b0d68328b41ef6466a2fa06 f9a8bb49
host.domain.tld. 3600 IN SSHFP 1 2 02323a6fb8a12eba9288930ce2513fc94970e5575996ebede1ee352b d039c531
;; Query time: 182 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon May 17 17:15:46 CEST 2021
;; MSG SIZE rcvd: 137
Run Code Online (Sandbox Code Playgroud)
上面没有提到,但如果我在查询中添加 +dnssec,则会显示 RRSIG SSHFP。
以及 SSH 客户端配置文件:
Host host.domain.tld
AddressFamily inet
HostName host.domain.tld
Port 22
Protocol 2
User username
CheckHostIP yes
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
VerifyHostKeyDNS yes
IdentityFile ~/.ssh/id_ed25519_host.domain.tld
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试从客户端连接到服务器时,SSHFP 似乎不起作用:
ssh host.domain.tld
The authenticity of host 'host.domain.tld (server_ip_address)' can't be established.
ED25519 key fingerprint is SHA256:Pu9ZKf6FA4suKn3nCJcXXnsNaDKLQe9kZqL6Bvmou0k.
Matching host key fingerprint found in DNS.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Run Code Online (Sandbox Code Playgroud)
根据互联网指南,我不应该被要求接受密钥。
所以,总结一下:
这是连接的详细信息:
ssh -v host.domain.tld
OpenSSH_8.6, LibreSSL 3.3.2
debug1: Reading configuration data /home/username/.ssh/config
debug1: /home/username/.ssh/config line 2: Applying options for host.domain.tld
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Connecting to host.domain.tld [server_ip_address] port 22.
debug1: Connection established.
debug1: identity file /home/username/.ssh/id_ed25519_host.domain.tld type 3
debug1: identity file /home/username/.ssh/id_ed25519_host.domain.tld-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.6
debug1: Remote protocol version 2.0, remote software version OpenSSH_8.6
debug1: compat_banner: match: OpenSSH_8.6 pat OpenSSH* compat 0x04000000
debug1: Authenticating to host.domain.tld:22 as 'username'
debug1: load_hostkeys: fopen /home/username/.ssh/known_hosts2: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts2: No such file or directory
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: curve25519-sha256@libssh.org
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: SSH2_MSG_KEX_ECDH_REPLY received
debug1: Server host key: ssh-ed25519 SHA256:Pu9ZKf6FA4suKn3nCJcXXnsNaDKLQe9kZqL6Bvmou0k
debug1: found 2 insecure fingerprints in DNS
debug1: matching host key fingerprint found in DNS
debug1: load_hostkeys: fopen /home/username/.ssh/known_hosts2: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts2: No such file or directory
debug1: load_hostkeys: fopen /home/username/.ssh/known_hosts2: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts2: No such file or directory
debug1: hostkeys_find_by_key_hostfile: hostkeys file /home/username/.ssh/known_hosts2 does not exist
debug1: hostkeys_find_by_key_hostfile: hostkeys file /etc/ssh/ssh_known_hosts does not exist
debug1: hostkeys_find_by_key_hostfile: hostkeys file /etc/ssh/ssh_known_hosts2 does not exist
The authenticity of host 'host.domain.tld (server_ip_address)' can't be established.
ED25519 key fingerprint is SHA256:Pu9ZKf6FA4suKn3nCJcXXnsNaDKLQe9kZqL6Bvmou0k.
Matching host key fingerprint found in DNS.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Run Code Online (Sandbox Code Playgroud)
你知道这个问题吗?
提前致谢。
OpenSSH v6.9 非常非常非常老了。最新的是 OpenSSH v9.0。我查看了dns.c
OpenSSH 存储库的 V_6_9 分支。调试输出中要注意的关键是:
found 2 insecure fingerprints in DNS\n
Run Code Online (Sandbox Code Playgroud)\n意味着 DNSSEC 查找host.domain.tld
不是有效的 DNS 记录(完全不安全),尽管通常已找到两 (2) 个不同的SSHFP
资源记录(安全或不安全)。
这也意味着delv host.domain.tld.
不会在第一行中输出预期的消息:
$ delv host.domain.tld.\n; fully validated\n...\n
Run Code Online (Sandbox Code Playgroud)\n虽然 DNSSEC 故障排除的范围非常广泛,但在本文中并不容易找到解决方案。
\n我建议您将其插入domain.tld
两个出色的在线 DNSSEC 疑难解答程序之一,然后从那里开始:
当然,作为最后的手段,[dnssec]
ServerFault(另一个 StackExchange 组)和您最喜欢的标签上有标签。搜索引擎,但聘请内部 DNSSEC 专家来满足您的需求会更快。
当然,您确实已启动并运行 DNSSEC 吗?
\nSSHFP 的保护只能通过 DNSSEC 正确签名的资源记录来保证,但是……但是大多数人(以及许多 ISP)不会指示他们的 DNS 解析器仅返回由 DNSSEC 确定的有效 DNS 记录;话虽如此,SSHFP 被劫持的可能性仍然存在。
\n这里的问题不是公钥的机密性(它不是\xe2\x80\x99t机密)。
\n我们遇到的问题是保存该公钥的 DNS 记录的完整性。虽然您的问题陈述中的 SSHFP 密钥数据是正确的,但该错误更多的是 \xe2\x80\x9clack of clarity\xe2\x80\x9d 但逻辑在防御上仍然正确。
\n这就是这个原始问题帖子的结束。但我将概述一些更多的安全警告。
\n如果不安全地分发(通过 DNSSEC),此类 SSHFP DNS 记录很容易被篡改或替换为其他密钥。因此,在信任和使用SSHFP
.
如果伪造的 SSH CA 服务器配置了错误的公钥(其私钥在其他人手中),则客户端最终会信任其他人。
\n注意:SSHFP 记录使用不当可能会造成严重的安全后果;请遵循以下规则以避免造成安全漏洞:
\nVerifyHostKeysDNS yes
除非当前解析器正确验证 DNSSEC 批准的查询或使用我使用简单命令创建的有效的支持 DNSSEC 的解析器delv domain.tld.
列表作为其 DNSSEC 功能的测试,否则切勿配置要使用的 SSH 客户端。; fully validated
检查。delv ssh.domain.tld.
并检查第一行的; fully validated
输出或通过强制执行 DNSSEC /etc/resolv.conf
(稍后会详细介绍)。如果不遵守这些规则,攻击者可能会为其 SSH 服务器创建欺骗性 SSHFP 记录来冒充您的服务器,从而使与服务器的 SSH 连接不安全且容易受到攻击。
\n您可以通过让主机的库在解析时执行此操作(通过解析器(3)而不是 gethostbyname(3) 函数调用)来避免“始终执行delv ssh.domain.tld
for )。如果您必须要求绝对 DNSSEC 验证的 DNS 查询您的所有 DNS 需求,您可以将以下内容插入到您的文件中(仅当您有 glibc v2.38 或更高版本时):; fully validated
glibc
/etc/resolv.conf
文件:/etc/resolv.conf
.\n.\n.\noptions edns0\noptions trust-ad\noptions ndots:2\n.\n.\n.\nsearch domain.tld\nnameserver 192.168.1.1\n
Run Code Online (Sandbox Code Playgroud)\n一旦获得 DNSSEC 保护,就需要执行几个步骤来排除SSHFP
DNS 记录和 SSH 客户端机制的故障。
列出七 (7) 个步骤是为了尝试(在前面的步骤通过之前不要执行下一步)。
\nPing host.domain.tld
,获得 ICMP 响应。
执行delv host.domain.tld.
并确保第一行输出显示; fully validated
;.
请注意主机名末尾添加的句点 ( )。
EDNS(0)
使用此EDNS(0) 在线测试仪针对您的相关服务器进行正确的练习。
从有问题的 SSH 服务器获取 SSH 指纹以开始比较;执行ssh-keyscan -D host.domain.tld.
(注意-D
选项)。
found 2 insecure fingerprints in DNS\n
Run Code Online (Sandbox Code Playgroud)\n其输出:
\nhost.domain.tld IN SSHFP 4 1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nhost.domain.tld IN SSHFP 4 2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
Run Code Online (Sandbox Code Playgroud)\nSSHFP
记录delv host.domain.tld. SSHFP
。$ delv host.domain.tld.\n; fully validated\n...\n
Run Code Online (Sandbox Code Playgroud)\n生成以下输出:
\n; fully validated\nhost.domain.tld. 86400 IN SSHFP 1 1 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nhost.domain.tld. 86400 IN SSHFP 1 2 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXX\nhost.domain.tld. 86400 IN SSHFP 3 1 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nhost.domain.tld. 86400 IN SSHFP 3 2 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXX\nhost.domain.tld. 86400 IN SSHFP 4 1 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nhost.domain.tld. 86400 IN SSHFP 4 2 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXX\n
Run Code Online (Sandbox Code Playgroud)\nSSHFP
将实际 SSH 指纹与DNS 记录的内容进行比较。算法 (1-6) 和哈希 ID(1 或 2)也必须匹配。必须匹配的命名算法 ID 为:1=RSA、2=DSA、3=ECDSA、4=Ed25519、6=Ed448。
\n必须匹配的名称的哈希 ID 为:1=SHA1、2=SHA256。
\nssh -oVerifyHostKeyDNS=yes -oStrictHostKeyChecking=yes host.domain.tld.
如果此步骤有效,请将这两个选项集成到您的 SSH 客户端配置文件中。如果指纹不匹配,则始终是需要更新的 DNS 记录。
\n使用较新的 OpenSSH,您甚至可能在初始 SSH 登录期间收到以下讨厌的提示:
\nssh host.domain.tld\n
Run Code Online (Sandbox Code Playgroud)\n可能会输出以下内容:
\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\nIT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!\nIt is also possible that a host key has just been changed.\nThe fingerprint for the ED25519 key sent by the remote host is\nSHA256:XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx.\nPlease contact your system administrator.\nUpdate the SSHFP RR in DNS with the new host key to get rid of this message.\nWarning: Permanently added \'[host.domain.tld.]:22,[999.999.999.999]:22\' (ED25519) to the list of known hosts.\n</etc/motd content goes here>\nuser@host.domain.tld.\'s password: \n
Run Code Online (Sandbox Code Playgroud)\n上面的输出中需要注意的关键是以下行:
\nUpdate the SSHFP RR in DNS with the new host key to get rid of this message.\n
Run Code Online (Sandbox Code Playgroud)\n这正是它的意思。
\n本地 SSH 客户端配置VerifyHostKeyDNS yes
中的\n控制该输出;配置位于$USER/.ssh/config
或 中/etc/ssh/ssh_config
。
上述决定基于以下之间的简单比较:
\nSSHFP
该区域数据的权威名称服务器host.domain.tld
host.domain.tld
提供公钥的SSH服务器此消息涵盖了以下 99.999% 的潜在场景。
\nsshd
没有使用相同的公钥,可能是由于:\nssh-keygen
通过(最常见)生成了不同的公钥sshd -c <config_file>
)AuthorizedKeyFile
已经改变FingerprintHash
) 设置已更改PubkeyAcceptedKeyTypes
已被改变CASignatureAlgorithms
已被改变TrustedCAUserKeys
已被改变另外 0.001% 的时间在许多不太常见的场景之一中发生故障:
\nssh_config
/$HOME/.ssh/config
使用了不同的端口号,则可能会发生这种情况(罕见但有人恶意发生)sshd
守护进程通过 SysV init 启动(service XXXX start
或systemd start XXXX.service
或system start XXXX.timer
或通过 crond/atd 作业甚至偷偷地启动rc.local
),并使用自己的 SSH 服务器公钥。sshd
可执行文件。这需要通过包工具(您的发行版的包工具)进行文件验证,以确定它\xe2\x80\x99s 的校验和值、修改时间、文件路径、安全上下文以及sshd
可执行文件及其引用库的属性(请参阅 参考资料ldd/usr/sbin/sshd
)都是计算并正确设置。无论如何,一旦你消除了剩下的 0.001%,事情就很简单了:
\nSSHFP
DNS 记录 ( ssh-keyscan -r host.domain.tld
); 将输出保存到编辑器缓冲区domain.tld
(dig domain.tld. soa
并记下MNAME
SOA 记录数据的部分)。MNAME
权威名称服务器host.domain.tld
/etc/named.conf
;较新的 Bind v9.11+ 通过显示默认配置named -V
)domain.tld
。(ISC Bind9 是file /var/lib/bind/db.domain.tld
)db.domain.tld
文件。SSHFP
粘贴您在第一步中保存的编辑器缓冲区中的新DNS 记录。可能希望将该句点 ( .
) 符号直接放在每个数据记录的主机名末尾SSHFP
(该数据记录是在关闭该区域数据库文件之前生成的ssh-keyscan
;这样:
; note the extra ending period \'.\' after hostnames\nhost.domain.tld. IN SSHFP 4 1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nhost.domain.tld. IN SSHFP 4 2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
Run Code Online (Sandbox Code Playgroud)\n享受!
\n来源:
\n\n 归档时间: |
|
查看次数: |
1786 次 |
最近记录: |