I’m writing some Python code that needs to communicate with a remote host via a TLS connection. I set up an SSL context like this:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) cxt.check_hostname = False ctx.verify_mode = ssl.CERT_NONE
Then, I connected to domain d
over port p
like this:
s = ctx.wrap_socket(socket.create_connection(d, p))
I was met with a protocol violation on an unexpected EOF. The fix was to create the socket like this:
s = ctx.wrap_socket(socket.create_connection(d, p), server_hostname=d)
As I know next to nothing about TLS, this is pretty confusing. Why would the server hostname be required for a successful connection?
If it matters, I tested a connection to domain d = 'drewdevault.com'
on port p = 1965
; I’m writing a Gemini client. This was not reproducible with all remote hosts.
Advertisement
Answer
The server_hostname
argument will be used in the TLS handshake to provide the server with the expected hostname. It is not strictly required in TLS, but it is needed one servers which have multiple certificates for different domain but on the same IP address. Without this information the server does not know which certificate to provide to the client.