On 30 September, the DST Root CA X3 certificate, which Let's Encrypt were using to "cross-sign", expired. This root certificate was important as it allowed older clients to trust, relatively, new Let's Encrypt certificates which were also signed with their own root certificate (ISRG Root X1).
Now that the DST Root CA X3 root certificate has expired, clients that do not trust ISRG Root X1, now the only valid root for Let's Encrypt, will not be able to verify a Let's Encrypt SSL certificate is valid.
For most people, this is not a problem, as the supported platforms list is fairly extensive and covers most modern platforms that end users will be using. In the case of macOS, this is supported from macOS 10.12.1 which was released in October 2016. However, if you use the
curl command in macOS, you may find yourself hitting a roadblock, which can be especially problematic in a CI/CD environment.
The Problem 🤔
If you try to
curl a website which is using a Let's Encrypt certificate, like Let's Encrypt's own homepage, you will find you receive the following error:
$ curl https://letsencrypt.org curl: (60) SSL certificate problem: certificate has expired More details here: https://curl.haxx.se/docs/sslcerts.html curl failed to verify the legitimacy of the server and therefore could not establish a secure connection to it. To learn more about this situation and how to fix it, please visit the web page mentioned above. Exited with code exit status 60
Yet if you open Safari and head to the same URL, there will be no problem at all! Why is this?
It appears that the default installation of
curl in macOS does not use the default system keychain, or security framework, in macOS. The system keychain includes a copy of the new ISRG Root X1 certificate which allows any apps that use the security framework in macOS to trust Let's Encrypt SSL certificates. Therefore
curl does not know this new certificate as it appears that Apple has not updated
curl's certificate store to add the ISRG Root X1 certificate - this only works out of the box in Big Sur and higher.
The Solution 🙌
Thankfully all is not lost! We can point
curl to include an additional CA bundle to allow validation of Let's Encrypt certificates.
The curl project provides updated certificate stores every few months on their website, so we can use this to resolve the error message seen above.
Firstly, we need to download the certificate bundle. You can either do this by heading to the download page, or by using
curl. It is important to note that if you use
curl, you will need to use the
-k option to skip validation of the SSL certificate as the curl project website also uses the ISRG Root X1 certificate - a chicken and the egg scenario 🐣!
curl -k https://curl.se/ca/cacert.pem -o ~/.cacert.pem
We then simply need to set
CURL_CA_BUNDLE to the path of the new CA bundle which contains the ISRG Root X1 certificate. The easiest way to do this is to add it to your
echo 'export CURL_CA_BUNDLE=~/.cacert.pem' >> ~/.bash_profile
Now reload your shell, or
source ~/.bash_profile and you will once again be able to use
curl with any URL using Let's Encrypt!