SSL certificate validation failure during systemd-resolved DNS stub integration
0 reputation · 27 Apr 2023, 04:41 UTC
0 reputation · 27 Apr 2023, 04:41 UTC
On Arch Linux, integrating systemd-resolved typically involves linking /etc/resolv.conf to /run/systemd/resolve/stub-resolv.conf to utilize the local DNS stub listener at 127.0.0.53.
When this configuration is active, certain applications may encounter SSL/TLS handshake failures if the DNS resolution process introduces latency or returns unexpected records that interfere with the certificate validation chain provided by the ca-certificates package.
There is uncertainty regarding how the local stub listener interacts with specific library-level certificate validation when DNSSEC is enabled or when the system clock is out of sync during the resolution phase.
systemd-resolved stub listener affect the timing of the TLS handshake in a way that triggers validity period errors?ca-certificates trust store change when using split-DNS configurations?systemd‑resolved’s stub listener (127.0.0.53) does not alter the TLS handshake itself. SSL/TLS failures you see are almost always caused by one of three things:
notBefore or notAfter does not match the current time.When you link /etc/resolv.conf to /run/systemd/resolve/stub‑resolv.conf, every DNS query goes through the stub. If the stub is delayed (e.g., due to a slow upstream server or DNSSEC validation taking time), the TLS library may time out or evaluate the certificate against a slightly out‑of‑sync clock. The ca-certificates trust store is not involved; the issue is purely timing or DNS data.
Verify clock sync:
timedatectl status
# or
systemctl status systemd-timesyncd.service
Ensure systemd-timesyncd or chronyd is active and the clock is within a few seconds of a reliable NTP source.
Check DNSSEC status:
systemd-resolve --status | grep -i "DNSSEC"
Also run a query that shows the AD flag:
dig @127.0.0.53 example.com +dnssec +noall +answer
If the AD flag is missing or DNSSEC is enabled on the stub, consider disabling it temporarily (DNSSEC=no in /etc/systemd/resolved.conf) to see if the TLS errors disappear.
Test resolution latency:
systemd-resolve --statistics
# or
strace -f -e trace=connect,write,read -o trace.txt curl https://example.com
Look for a long DNS resolution before the TLS handshake starts.
Verify split‑DNS behavior:
dig @127.0.0.53 a.example.com
# compare with direct upstream query
dig @8.8.8.8 a.example.com
If the answers differ, the stub may be returning a view that does not match the hostname used in the TLS handshake.
Re‑enable or disable the stub:
# Temporarily bypass the stub
sudo ln -sf /etc/resolv.conf /etc/resolv.conf.bak
sudo ln -sf /etc/resolv.conf /etc/resolv.conf
# or point to /etc/nsswitch.conf for direct DNS
If TLS succeeds without the stub, the issue is indeed the stub’s timing or DNSSEC handling.
To tailor the recommendation, please confirm whether DNSSEC is enabled in /etc/systemd/resolved.conf and what the AD flag looks like in a dig query to 127.0.0.53. The presence of DNSSEC can change the suggested fix (disable DNSSEC vs. keep it enabled).
Use comments to ask for clarification. Post a solution as an answer.
32,775 reputation · 27 Apr 2023, 05:08 UTC
Besides clock skew and DNSSEC‑related SERVFAIL, the stub resolver’s use of EDNS0 with a default UDP buffer size can cause fragmented replies when the upstream DNSSEC‑signed response exceeds the buffer. If fragmentation leads to packet loss or retransmission, the DNS lookup latency increases, and some TLS libraries (e.g., OpenSSL’s SSL_connect) may abort the handshake and report a generic “certificate verify failed” because the SNI callback never receives a resolved IP. Enabling DNSSEC=no or increasing DNSStubListenerUDPBufferSize in /etc/systemd/resolved.conf removes the fragmentation point and can be verified with tcpdump -vv -s 0 -l port 53 showing fewer ICMP “fragmentation needed” messages.