我用的是 http.client.HTTPSConnection 来生成一个HTTPS连接到我的服务器。我不能使用原来的主机名来连接服务器,因为这是一个测试设置,但我需要用正确的主机名作为SNI来进行正确的TLS握手。如何设置HTTPS连接的客户端hello的SNI?
根据 ssl.SSLSocket.server_hostname。如果我可以访问底层的socket,我应该可以将server_hostname设置为我想要的值。HTTPSConnection
确实有一个 sock
成员,但它是 None
构建后。
如果更多的源码背景对你有帮助,我在测试代理中的 代理验证人. 见 代理服务器_http1.py#L94
解决方案:
在问题的评论部分,Steffen Ullrich引导我找到了答案。没有直接的支持我试图做什么通过 http.client.HTTPSConnection
. 然而, http.client.HTTPSConnection
称为 ssl.SSLContext.wrap_socket。 函数的SSLContext。因此,我能够通过为该类创建一个包装器来获得我想要的东西。如果对其他人有帮助,我的代码现在看起来像这样。
if scheme == 'https':
if socket.client_sni:
class WrapSSSLContext(ssl.SSLContext):
'''
HTTPSConnection provides no way to specify the
server_hostname in the underlying socket. We
accomplish this by wrapping the context to
overrride the wrap_socket behavior (called later
by HTTPSConnection) to specify the
server_hostname that we want.
'''
def __new__(cls, server_hostname, *args, **kwargs):
return super().__new__(cls, *args, *kwargs)
def __init__(self, server_hostname, *args, **kwargs):
super().__init__(*args, **kwargs)
self._server_hostname = server_hostname
def wrap_socket(self, sock, *args, **kwargs):
kwargs['server_hostname'] = self._server_hostname
return super().wrap_socket(sock, *args, **kwargs)
proxy_to_server_context = WrapSSSLContext(socket.client_sni)
else:
proxy_to_server_context = ssl.SSLContext()
self.tls.conns[origin] = http.client.HTTPSConnection(
replay_server, timeout=self.timeout,
context=proxy_to_server_context, cert_file=self.cert_file)
因此,如果我想指定SNI,我就使用自定义的… … WrapSSSLContext
类,它明确地提供了我想要的server_hostname。否则,我只用标准的 ssl.SSLContext
. 我已经验证了在一个数据包捕获,这指定的SNI,我想在客户端你好。
谢谢Steffen!
本文来自投稿,不代表运维实战侠立场,如若转载,请注明出处:https://www.shizhanxia.com/668.html