Bug #19770
closedTLS / Certificate Hostname Verification against IP fails with "address family must be specified"
Description
I dont't use Ruby directly but indirectly via Fluentd-1.16.1 (https://www.fluentd.org/). Fluentd uses Ruby 3.1.4.
The problem is, that a TLS connection from a Fluentd Client to a Fluentd Server fails, if the connection is established using the IP address of the server and tls_verify_hostname is switched to on. In the servers certificate, in the SubjectAlternativeNames extention, there is the servers IP address set with the correct value. I get the error message " address family must be specified ".
Probable cause :
ext/openssl/lib/openssl/ ssl.rb line 288:
Here the Methode IPAddr.new(hostname) is called with just one argument:
return true if san.value == IPAddr.new( hostname ).hton
lib/ ipaddr.rb line 594:
Here the exception is raised with the observed error message:
when Socket::AF_UNSPEC
raise AddressFamilyError, " address family must be specified "
The exception is raised, because the variable "family" has the value " Socket::AF_UNSPEC " because thats the default value of "family" if there is no additional parameter in the call to "initialize()".
The documumentation of "initialize()" says in line 575/576/577: "Although the address family is determined automatically from a specified string, you can specify one explicitly by the optional second argument."
But that automatic address determination is done too late. If no second parameter is given, it is not done at all because that exception is raised (assumption: the addr i always a string).
Probable solution :
If the address family is set to Socket::AF_UNSPEC with the call of "initialize()", dont't raise an exception now but do the in the comment announced automatic adress family detection here.
Updated by nobu (Nobuyoshi Nakada) almost 2 years ago
The document of IPAddr#initialize
says:
Creates a new ipaddr object either from a human readable IP
address representation in string, or from a packed in_addr value
followed by an address family.
and
In the former case, ...
(snip)...
Although the address family is determined automatically from a specified string,
Actually the code raising the exception is inside if !addr.kind_of?(String)
.
What is hostname
in that case?
Updated by Schachi65 (Joachim Schachermayer) almost 2 years ago
In that case, the hostname is a human readable IP: 192.168.55.11
Updated by jeremyevans0 (Jeremy Evans) over 1 year ago
- Status changed from Open to Third Party's Issue
Schachi65 (Joachim Schachermayer) wrote in #note-2:
In that case, the hostname is a human readable IP: 192.168.55.11
The line raising the exception is only reached if you pass a non-String to IPAddr.new
. Your "(assumption: the addr i always a string)" is unfortunately incorrect. From searching in Fluentd, it appears the problem comes from https://github.com/fluent/fluentd/blob/d5685ada81ac89a35a79965f1e94bbe5952a5d3a/lib/fluent/plugin_helper/socket.rb#L183. Looking at the code leading up to that, if the host you are trying to verify is an IP address, it doesn't set fqdn
(https://github.com/fluent/fluentd/blob/d5685ada81ac89a35a79965f1e94bbe5952a5d3a/lib/fluent/plugin_helper/socket.rb#L103), so it is passing nil
to post_connection_check
(which eventually results in passing nil
to IPAddr.new
). The best fix is probably for Fluentd to not default the verify_fqdn
argument to true
if host_is_ipaddress
, and do verification some other way in that case (maybe comparing the IP address you are connecting to to the IP address in the certificate?).
As you already reported this to Fluentd (https://github.com/fluent/fluentd/issues/4244), I recommend you update that issue to include the above information, since the problem is in Fluentd and not in Ruby.