1

I have a Ruby polling script that runs on a set of servers in an IP range. I very strongly prefer to do this polling by IP address, not by hostname, because:

1) I have defined IP address ranges to poll, and hostnames are arbitrary/change a lot

2) Because they change a lot, most of the hostnames do not have a reverse DNS lookup, so I can't engineer a list of hostnames from IPs

Before our web servers had no problem with this polling, but on a new server that does not accept SSLv3 communication, this is the error I get when I run my poll:

/home/dashboard/.rvm/rubies/ruby-2.1.6/lib/ruby/2.1.0/net/http.rb:923:in `connect': SSL_connect returned=1 errno=0 state=unknown state: tlsv1 unrecognized name (OpenSSL::SSL::SSLError)

On the server side, this is the error:

nss_engine_init.c(1802): start function ownSSLSNISocketConfig for SNI
nss_engine_init.c(1827): Search [val = 172.16.99.18] failed, unrecognized name

When I run the poll with hostname, everything works fine.

Here is the crux of the HTTP Client code in Ruby:

def init_http(url)
  uri = URI.parse(url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  http.read_timeout = 10
  http.use_ssl = true
  #http.ssl_version = 'TLSv1'
  return [http, uri]
end

As you can tell, I've been playing around with TLS and SSL version, because I figured that might be the issue. My next thought (that Google only has evidence of for Java) is, "How easy is it to just disable the SNI extension on my client?" The more general question is, "Can I keep using IP addresses with Ruby net/http while taking advantage of newer, more secure communication protocols?"

ZebGir
  • 123
  • 1
  • 7

2 Answers2

0

... tlsv1 unrecognized name (OpenSSL::SSL::SSLError)

This is in most cases not a problem you can solve by disabling SNI on the client side. SNI is required when you have multiple certificates on the same IP address and if you just connect by IP address and don't send the requested hostname (i.e. disabling SNI) the server will not know which certificate it should provide - which then results in the above error.

I very strongly prefer to do this polling by IP address, not by hostname, ...

If you have to deal with server which require SNI then you have to use SNI and you have to use SNI with the proper hostname, which is not necessarily the same name as you get from reverse lookup.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Hm, the reason I thought there was hope was because I _don't believe_ the server requires SNI. I can reach the server by IP using IE and Chrome. It's only the Ruby poll that has had this issue so far. So it seems to me that it's the client that is forcing or suggesting SNI use. – ZebGir Nov 13 '15 at 13:16
  • @ZebGir: If I understand the code correctly they set the SNI hostname to whatever you give as address and there is no way to disable SNI. See also [bug 10613](https://bugs.ruby-lang.org/issues/10613) which is open for 10 month. There is also a patch on the bug so you might fix it in your installation. – Steffen Ullrich Nov 13 '15 at 14:10
0

The easiest way to solve this is to add the patch that @steffenullrich mentioned for bug 10613.

All I did was look at the diff, and edit the file myself, but you can use the Linux patch tool if you're familiar with it.

For those who are unsure of where /net/http.rb is located, it is in the same location as the rest of your Ruby sources. For example, mine was here:

/home/myuser/.rvm/rubies/ruby-2.1.6/lib/net/http.rb

Once you patch the file, set the .disable_sni property of your HTTP object to true, and SNI will not be required, allowing the use of IP addresses in mixed-TLS communication.

ZebGir
  • 123
  • 1
  • 7