If ruby is using openssl with TLS extensions, and we attempt to connect to a server which supports TLS, but not SNI, the connection fails.
e.g.:
uri=URI.parse("https://example.com")# a server that supports TLSv1 but not the TLS extensionshttp=Net::HTTP.new(uri.host,uri.port)http.use_ssl=truehttp.ssl_version=:TLSv1http.verify_mode=OpenSSL::SSL::VERIFY_PEERresponse=http.get(url)
The patch adds the ability to turn off SNI triggering behavior, but by default it continues the previous behavior.
Not all SSL servers support SNI, and by forcing SNI without an option to disable it, makes it impossible to communicate with an conforming TLS implementation.
We're using this patch on our ruby installations, but I think this is something that would be widely useful to the community, especially since it's not obvious why a TLS negotiation would fail with some servers.
Please let me know if I need to do anything to help get this merged in.
Unfortunately, I don't know any details about the server. It's not a box that we own.
I am connecting over an SSH tunnel, so the hostname being used for SNI is 127.0.0.1. The server simply returns a 400; my best guess is that it's not configured to use a default certificate for unknown hostnames. (I can make things work by editing /etc/hosts locally, but that's not a viable approach in our production environment.)
I am able to set the Host and Location headers, but have not been able to find a better solution than mokeypatching Net::HTTP#connect to disable SNI for connections to this server.
In my case, the cert on this server is expired, so I don't even verify it. For what it's worth, cURL does not perform SNI when certificate checking is disabled (using the -k or --insecure flag.)
(Sorry for the delay in getting back to you, I had just created my account and wasn't watching this issue.)
I am connecting over an SSH tunnel, so the hostname being used for SNI is 127.0.0.1. The server simply returns a 400; my best guess is that it's not configured to use a default certificate for unknown hostnames. (I can make things work by editing /etc/hosts locally, but that's not a viable approach in our production environment.)
Connecting to HTTPS server with a raw IP address is not supported currently because the domain name is required for the SNI and also for the certificate verification on connection time.
There is a rejected ticket about specifying the IP address to connect, though in Japanese: [Feature #5180]. Editing /etc/hosts and overriding TCPSocket.open are the suggested workaround.
Not sure about what is the best way if net/http wants to support such usage, but I can say adding an option to turn off SNI is not on the right track.