Score:0

openssl s_client works with IP, but does nothing with domain name

hr flag

I recently-ish set up an internal (firewalled) apache2 web server that exactly one of my colleagues cannot reach for some reason (PR_END_OF_FILE_ERROR, indicating something's wrong with the handshake/SSL/ciphers). Since I don't have a sufficiently clear idea of the underlying problem there, I'm not aiming to solve his unspecific problem with this question. But:

While trying to understand the issue behind his problems, I noticed the following odd behavior: If I run

openssl s_client -connect 111.222.333.111:443

with the IP address, then I can test all of the ciphers etc. as expected. The connection is established basically instantaneously, everything seems fine. But if I do the same with

openssl s_client -connect my_domainname.com:443

i.e., with the registered domain name, then simply nothing seems to happen, openssl-s_client doesn't never returns (as if it were still trying to establish a connection forever?) and I cannot get it to give me any output whatsoever. However, opening my_domainname.com in a browser works as expected for everyone except that one colleague, and ping, dig, nmap etc. also correctly resolve the domain name. Conversely,

openssl s_client -connect google.com:443

does work, so it seems I've misconfigured something? Or might something be going wrong with openssl's DNS resolution?

Nikita Kipriyanov avatar
za flag
Well, it looks like you still have some problem with your DNS, either your local DNS resolver or with the domain. Debugging such domain problems *requires* disclosure, so won't you mind sharing the real domain name that shows these strange symptoms?
MrArsGravis avatar
hr flag
@NikitaKipriyanov Thanks for the hint, after messing about with the DNS I figured out it was mostly my own fault for not opening the IPv6 ports despite the IPv6 address being served as a DNS reply, see my answer below if you're interested.
Score:1
hr flag

I found the problem, which might not be relevant to many other people, but it was indeed the issue in my specific case:

The problem

openssl s_client, apparently by default (?), requests both IPv4 and IPv6 addresses from DNS nameservers and then apparently tries to connect only via IPv6 if it gets a valid response to the IPv6 DNS request. The problem was that I had not opened the IPv6 HTTP(S) ports, so openssl was requesting an IPv6 address from DNS servers, getting a valid response and valid IPv6, then attempting to connect to that IPv6 address and getting blocked by the firewall.

Other programs such as nmap and Firefox were evidently either using IPv4 by default or falling back to IPv4 after noticing that IPv6 was failing, hence why I couldn't detect the issue at first.

How to detect it

If it helps someone else: I figured out that this was the issue by listening for TCP traffic on port 53 (DNS):

sudo tcpdump -n port 53

where I noticed the following exchange following my execution of openssl s_client:

18:24:57.649939 IP local-ip.50643 > dns-server.53: 12404+ [1au] A? domain-name.com. (55)
18:24:57.650293 IP local-ip.39731 > dns-server.53: 26725+ [1au] AAAA? domain-name.com. (55)
18:24:57.651843 IP dns-server.53 > local-ip.50643: 12404* 2/0/1 CNAME cname-of-server., A server-ipv4-address (146)
18:24:57.651877 IP dns-server.53 > local-ip.39731: 26725* 2/0/1 CNAME cname-of-server., AAAA server-ipv6-address (158)

indicating that openssl had requested and subsequently received both IPv4 (A) and IPv6 (AAAA) DNS questions and answers. (Here and in the following, local-ip, dns-server, cname-of-server, server-ipv6-address and server-ipv4-address are placeholders and not literal.)

Then I checked for traffic to and from the IPv4 and IPv6 addresses that were given as replies to the DNS query:

sudo tcpdump host server-ipv6-address # in one tab
sudo tcpdump host server-ipv4-address # in another tab

right before running the openssl s_client command. I noticed that there were unanswered session establishment (SYN, [S] in tcpdump output) packets for the IPv6 host, but nothing on IPv4, indicating that openssl was ignoring the IPv4 address that it received and trying to connect using only the IPv6 answer.

It works if you fix it

After I changed the firewall settings of the server to allow incoming IPv6 HTTP(S) packets, openssl s_client was able to successfully connect and tcpdump showed normal handshakes taking place with the IPv6 host. Side note: Firefox automatically switched to IPv6 after the ports were opened.

Nikita Kipriyanov avatar
za flag
You can also set precedence of IPv4 higher than IPv6 in glibc-based Linux DNS resolver by adding a line similar to `precedence ::ffff:0:0/96 100` into `/etc/gai.conf`. Probably there is similar mechanism for systemd resolver, too.
MrArsGravis avatar
hr flag
That probably also would have solved the problem, though I think it's clear that it is preferable to not have misconfigured IPv6. Ideally, `openssl s_client` could have switched to IPv4 after IPv6 timed out and informed me of the IPv6 timeout, but I couldn't find a way to make it do that.
MrArsGravis avatar
hr flag
...in other words, `openssl s_client` could implement [RFC8305](https://datatracker.ietf.org/doc/html/rfc8305) or some variant of it.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.