[ruby-core:114218] [Ruby master Bug#19770] TLS / Certificate Hostname Verification against IP fails with "address family must be specified"

Issue #19770 has been reported by Schachi65 (Joachim Schachermayer). ---------------------------------------- Bug #19770: TLS / Certificate Hostname Verification against IP fails with "address family must be specified" https://bugs.ruby-lang.org/issues/19770 * Author: Schachi65 (Joachim Schachermayer) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.4 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- 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. -- https://bugs.ruby-lang.org/

Issue #19770 has been updated by nobu (Nobuyoshi Nakada). 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? ---------------------------------------- Bug #19770: TLS / Certificate Hostname Verification against IP fails with "address family must be specified" https://bugs.ruby-lang.org/issues/19770#change-103906 * Author: Schachi65 (Joachim Schachermayer) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.4 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- 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. -- https://bugs.ruby-lang.org/

Issue #19770 has been updated by Schachi65 (Joachim Schachermayer). In that case, the hostname is a human readable IP: 192.168.55.11 ---------------------------------------- Bug #19770: TLS / Certificate Hostname Verification against IP fails with "address family must be specified" https://bugs.ruby-lang.org/issues/19770#change-103907 * Author: Schachi65 (Joachim Schachermayer) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.4 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- 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. -- https://bugs.ruby-lang.org/

Issue #19770 has been updated by jeremyevans0 (Jeremy Evans). 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/d5685ada81ac89a35a79965f1e94bbe5952a5.... 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/d5685ada81ac89a35a79965f1e94bbe5952a5...), 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. ---------------------------------------- Bug #19770: TLS / Certificate Hostname Verification against IP fails with "address family must be specified" https://bugs.ruby-lang.org/issues/19770#change-104145 * Author: Schachi65 (Joachim Schachermayer) * Status: Third Party's Issue * Priority: Normal * ruby -v: ruby 3.1.4 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- 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. -- https://bugs.ruby-lang.org/
participants (3)
-
jeremyevans0 (Jeremy Evans)
-
nobu (Nobuyoshi Nakada)
-
Schachi65 (Joachim Schachermayer)