On Sep 30, 2021, Let's Encrypt had one of their intermediate certificates expire (an old DST Root CA X3 certificate).
This certificate is still present in the public certificates that they issue
to attempt maintaining compatibility with old android devices.
Normally, this would not be a problem, because Let's Encrypt offers
another valid signature. However, broken SSL implementations
will reject the certificate. This includes OpenBSD 6.9 release and older,
and older versions of mIRC.
Switching to another certificate authority would normally help. However, mIRC
users have complained about validation errors. It seems they are missing one
of the certificate authorities used by buypass. For this reason, do
not use buypass for your TLS certificates.
Let's Encrypt allows you to request a certificate without this expired chain,
using --preferred-chain 'ISRG Root X1'
on certbot for example,
however openbsd's acme-client does not support this.
The best solution is to use Let's Encrypt issued certificates
while also deleting the extra intermediate certificate that has expired.
Go to /etc/ssl/
where your public certificates are stored and edit
/etc/ssl/example.com.fullchain.pem
. Delete the lines of the third
(and last) certificate by running this command as root:
# awk '/END CERTIFICATE/ { cert++; } { print $0; if (cert == 2) exit;}' /etc/ssl/example.com.fullchain.pem > /etc/ssl/example.com.fullchain.pem.fixed
# mv /etc/ssl/example.com.fullchain.pem.fixed /etc/ssl/example.com.fullchain.pem
You should repeat this for every single SSL cert you have. Then,
if the daemon that serves the cert is running inside a chroot, make sure
to copy the SSL cert into the chroot. For example, for ngircd:
$ doas cp /etc/ssl/example.com.fullchain.pem /etc/ssl/private/example.com.key /etc/ngircd/
$ doas chown _ngircd:_ngircd /etc/ngircd/example.com.{fullchain.pem,key}
$ doas pkill -HUP ngircd
We make sure to set the proper permissions as well as send a HUP
signal to ngircd to cause it to reload its cert.
For ZNC, we would run:
$ doas cp /etc/ssl/example.com.fullchain.pem /etc/ssl/private/example.com.key /home/znc/home/znc/.znc/
$ doas chown -R znc:znc /home/znc/home/znc/.znc/
Make sure that certs are properly copied into place for all your services.
Test to see if every one of your SSL certs work. It's best to use
a wide variety of web browsers, email clients, and IRC clients on preferably
different operating systems. For example, an SSL cert might validate
on Firefox on Debian but not on lynx on OpenBSD or mIRC on Windows.
Recommended Testing:
Try testing with mIRC from Windows if you have it, or irssi on unpatched
OpenBSD 6.9 release to your IRC server/ZNC bouncer. Also, try lynx/w3m on
OpenBSD to your website, and mutt on OpenBSD to your mail server. Try to
see if you can trigger the error before deleting the certificate, and if
you have a valid certificate after it's deleted.
For a primitive method of checking (which specifically only applies to
LetsEncrypt certs), you can also try simply counting the number of certs
that get offered:
$ openssl s_client -showcerts -connect example.com:443 </dev/null 2>/dev/null | grep '\-----END CERTIFICATE-----' | wc -l
1
means your trust chain is missing, making it unverifiable by most devices
2
is correct
3
means you still have the expired cert in your trust chain
Patching OpenBSD
In Errata for OpenBSD 6.9, a patch
is provided so that OpenBSD will verify trusted certificates first:
$ doas syspatch
See also http://undeadly.org/cgi?action=article;sid=20211001073034