为什么 SSL 包装的套接字需要“server_hostname”?

Why is `server_hostname` required for an SSL-wrapped socket?

我正在编写一些需要通过 TLS 连接与远程主机通信的 Python 代码。我设置了这样的 SSL 上下文:

ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
cxt.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

然后,我通过端口 p 连接到域 d,如下所示:

s = ctx.wrap_socket(socket.create_connection(d, p))

我在意外的 EOF 上遇到了协议冲突。修复方法是像这样创建套接字:

s = ctx.wrap_socket(socket.create_connection(d, p), server_hostname=d)

因为我对 TLS 几乎一无所知,所以这很令人困惑。为什么需要服务器主机名才能成功连接?

如果重要的话,我在端口 p = 1965 上测试了到域 d = 'drewdevault.com' 的连接;我正在写一个 Gemini 客户端。这不是所有远程主机都能重现的。

server_hostname 参数将用于 TLS 握手中,为服务器提供预期的主机名。它在 TLS 中不是严格要求的,但是需要一台服务器,该服务器具有针对不同域但在同一 IP 地址上的多个证书。如果没有此信息,服务器将不知道向客户端提供哪个证书。