Reputation: 101
I'm using NGINX for a DNS over TLS server.
However Android "private DNS" suddenly stopped working on all devices.
Using kdig still works as expected
kdig -d @my.dns.server +tls-ca +tls-host=my.dns.server example.org
However Android requests instead fail and I get the following error in NGINX logs
SSL_do_handshake() failed (SSL: error:14094415:SSL routines:ssl3_read_bytes:sslv3 alert certificate expired:SSL alert number 45) while SSL handshaking, client: **.**.**.**, server: 0.0.0.0:853
The cert is still valid however and I'm not sure why it's throwing this error.
My NGINX SSL config is
ssl_certificate /etc/letsencrypt/live/my.dns.server/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/my.dns.server/privkey.pem; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA";
ssl_handshake_timeout 10s;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 4h;
Upvotes: 3
Views: 9338
Reputation: 131
The DST Root CA X3 certificate, which letsencrypt uses, has expired. They had already started to use the new ISRG Root X1 certificate additionally for multiple years, but some old devices (for example android < 7.1.1) does not know this new certificate. This means these devices cannot use the new certificate and also should not be able to use the old one anymore.
But letsencrypt has noticed that many old ssl implementations (including android) don't check if a certificate has expired. So they can still use the old DST Root CA X3 certificate for these devices. Newer ssl implementation can use the new ISRG Root X1 certificate instead.
see: https://letsencrypt.org/2020/12/21/extending-android-compatibility.html
Sadly, some newer ssl implementation (including the android dot client) notice the old expired certificate and abort the ssl-connection, because the certificate has expired. They don't check the new certificate at all. Because of this implementation dependent behaviour, some newer programs don't work, but others work just fine.
To keep all newer ssl implementation working, you need to use only the new ISRG Root X1 certificate. To do this, you must use the ISRG Root X1 chain. But this will break the compatible with older device, which don't know the new ISRG Root X1 certificate yet.
If you use certbot you can use the following flag --preferred-chain "ISRG Root X1"
If you use the caddy webserver you can add the following lines to the beginning of your Caddyfile:
{
preferred_chains {
root_common_name "ISRG Root X1"
}
}
Upvotes: 1