这件事让我抓狂。我正在测试 SSL 证书,并使用不同的 SNI 来确定哪些是可接受的。我不拥有/管理该证书,因此依靠 s_client 提供信息。我知道有几种 SNI 可以工作。我还测试了一个不起作用的 SNI,因为我看到返回了“主机名不匹配”。
我可以使用 -verify_hostname 标志来查看哪些有效,哪些无效,使用以下命令:
echo -n | openssl s_client -connect {IP_ADDR}:443 -servername {SERVER_NAME} -verify_hostname {HOSTNAME - same as the servername} | openssl x509 -noout -text | grep 'Subject Alternative Name' -A2
证书中只有一个 SAN。并且有一个不是通配符的 CN。换句话说,我在 X509v3 主题备用名称:输出中看到 jack.whatever.com,并且在 CN = jack.whatever.com 中看到相同的内容
但是,在 -servername 标志字段中发送时,还有一些其他主机名是可以接受的。如果不使用 -verify_hostname 值,并且我发送了一个不可接受的 SNI,则不会收到主机名不匹配错误,并且我会在 X509v3 主题备用名称:字段中返回默认的 jack.whatever.com。如果我发送了一个可接受的 SNI 值,我会在 X509v3 主题备用名称:字段中返回该值(以及其他值!)。
总而言之,有多个可接受的 SNI,但只有一个 CN 和 SAN 值。我如何确定所有可接受的 SNI 主机名?除了尝试一些我知道有效的 SNI 之外,我看不到任何信息。我想知道哪些未知的 SNI 有效。请注意,删除上述命令的 grep 部分以获取所有信息仍然不会显示“可接受的”SNI - 完整输出不包含此信息。
答案1
证书不接受 SNI。相反,服务器将接受 SNI,然后使用配置的证书继续进行 TLS 握手。
这意味着,即使域名与证书匹配,服务器也可能不会接受该域名作为 SNI。此外,服务器也可能接受该域名作为 SNI,但提供与该域名不匹配的证书,在这种情况下,客户端可能会抱怨验证错误。
没有办法查询哪些域被服务器接受为 SNI,只能尝试。