Skip to content
Advertisement

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

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.

Advertisement