【发布时间】:2016-08-17 09:50:08
【问题描述】:
我的代码示例:
import OpenSSL
import socket
ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
s = socket.socket(AF_INET, SOCK_STREAM)
connection = OpenSSL.SSL.Connection(ctx, s)
connection.connect((str(ip), port))
connection.setblocking(1)
connection.do_handshake()
chain = connection.get_peer_cert_chain()
如果主机有 SNI 扩展,我会得到一个错误:
[('SSL 例程', 'SSL3_READ_BYTES', 'sslv3 警报握手失败')]
我相信我可以使用OpenSSL.SSL.Connection.set_tlsext_host_name(name) 克服这个问题,但是对于用户主机名未知,我想连接到每个可用的主机名。
所以我的问题是:有没有办法通过 ip 连接到主机并检索所有提供证书的可用主机名?或者有没有办法从 SNI 主机检索所有证书?
【问题讨论】:
-
使用
s_client获取IP地址的证书并打印证书中的DNS名称:openssl s_client -connect <hostname>:<port> -tls1 -servername <hostname> | openssl x509 -text -noout。使用 IP 地址作为 SNI 服务器名称。然后,连接 DNS 名称。在具有虚拟服务器的托管环境中,这可能无法按预期工作。您可能必须执行 DNS 反向查找才能获取名称。反向查找假定 DNS 已按预期配置,但实际情况可能并非如此。
标签: python sockets openssl pyopenssl