我正在编写一些需要通过 TLS 连接与远程主机通信的 Python 代码。我设置了这样的 SSL 上下文:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
cxt.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
然后,我连接到域 d
通过端口 p
像这样:s = ctx.wrap_socket(socket.create_connection(d, p))
我在意外的 EOF 上遇到了协议(protocol)违规。解决方法是像这样创建套接字:s = ctx.wrap_socket(socket.create_connection(d, p), server_hostname=d)
正如我对 TLS 几乎一无所知,这非常令人困惑。为什么成功连接需要服务器主机名?如果重要,我测试了与域
d = 'drewdevault.com'
的连接在端口 p = 1965
;我正在写一个 Gemini 客户端。这在所有远程主机上都无法重现。
最佳答案
server_hostname
参数将在 TLS 握手中用于为服务器提供预期的主机名。 TLS 中没有严格要求,但需要一台服务器具有不同域的多个证书但在相同的 IP 地址上。如果没有此信息,服务器将不知道向客户端提供哪个证书。
关于python - 为什么 SSL 包装的套接字需要 `server_hostname`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70478701/