Resolving Let's Encrypt Issues with CURL on macOS
Fixing CURL issues for macOS versions up to 10.15
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 .bash_profile
:
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!