To answer the part of the question added in an update,
Why does it need the Host: header when SNI is on?
"Need" is a strong word but it helps to understand that SNI and HTTP headers operate at two different layers and accordingly serve two different purposes.
SNI is primarily used to determine which certificate to give the client. In a setup with multiple virtual hosts, before the payload is decrypted, the server has to present a certificate to the client. Since the certificate contains the name of the site, traditionally in the common name of the certificate subject, but lately in the X.509 extension subject alternative names, presenting the wrong certificate would cause the client to reject the connection before even sending the HTTP request to the server.
Whereas, the Host
header is primarily used to determine which resource to serve. In well behaved clients this is redundant with the name in SNI but HTTP/1.1 was developed around the same time as SSL 3.0 and thus well before the TLS-SNI extension even existed. In fact, it was the combination of HTTP/1.1 and SSL/TLS where the need for SNI was discovered in the first place.
It may be worth noting that HTTP/2 does not require the Host
header but has a functional equivalent in the form of the :authority
pseudo-header. Though the information in that header will still be redundant with TLS-SNI in most cases, it simplifies the implementation to always include it.
Always including the Host
(or :authority
) header also leaves open the possibility of barebones SSL termination (though in practice there is very little support for HTTP/2 without TLS). However, not validating that the host/authority matches the name in TLS-SNI could open up a security hole in some setups.
Host:
header, so there may be something else that is required. My expectation would be that when theHost:
header is missing, the request is handled by the default server configuration, same as for non-SSL.openssl s_client
? If so, add the-crlf
option to the end of it.