Let’s Encrypt DNS-01 Challenge & the Cloudflare API

Last modified date

Comments: 0

There are a number of ways Let’s Encrypt (LE) can validate a request to issue an SSL certificate via the ACME standards, with the two most common ones being HTTP-01 and DNS-01. The LE documentation details each with the advantages and disadvantages here.

I’ve started using the DNS-01 challenge method for internal systems in my lab as it means I don’t need to configure any port forwarding on my firewall and it avoids exposing servers to the Internet.

I moved the DNS for my lab domain to Cloudflare so I can use it’s API to automate the issuing of certificates. The free tier offers everything I need so it’s great for the job and my wallet. Until August 2019, Cloudflare only supported a single API key. These had a number of a weaknesses as a single key provided full access to all functionality on your entire Cloudflare account. Thus if you wanted to use the ACME DNS-01 challenge you were giving access (to your Cloudflare account) way beyond what is actually needed to issue the certificate (create and remove a single TXT record on your DNS zone). In addition, if you used DNS-01 on multiple servers and wanted to roll the API key for security, you’ve got to change it everywhere.

With API tokens you can create a much more restricted level of access, even limiting access to use a particular token by IP address. I covered creating an API key in my PRTG & Let’s Encrypt walk-through.

There is one further gotcha here though and that’s why I’ve written this post. Due to the way Cloudflare built their API token system, a DNS-01 challenge may need permissions higher than you’d expect. The Certbot DNS-01 documentation explains it nicely:

However, due to some shortcomings in Cloudflare’s implementation of Tokens, Tokens created for Certbot currently require Zone:Zone:Read and Zone:DNS:Edit permissions for all zones in your account. While this is not ideal, your Token will still have fewer permission than the Global key, so it’s still worth doing. Hopefully Cloudflare will improve this in the future.

Some additional background can be found on this Certbot Github issue.

As an open-standard, there are many tools for working with ACME to obtain certificates. Acme.sh supports a whole raft of DNS providers including Cloudflare. If the SSL you are requesting is only for a single zone (eg mycert.mydomain.co.uk) , you can specify the Cloudflare Zone ID alongside the API token and Account ID – the benefit of this is the API token can then be locked down as tightly as possible. From what I can tell, support for this method was added in version 2.8.6 of acme.sh.

export CF_Token="sdfsdfsdfljlbjkljlkjsdfoiwje"
export CF_Account_ID="xxxxxxxxxxxxx"
export CF_Zone_ID="xxxxxxxxxxxxx"

Although you configure these values as environment variables using the export command (so they shouldn’t persist across SSH sessions), acme.sh copies them into account.conf. That file obviously needs looking after.

Chris

Leave a Reply

Your email address will not be published. Required fields are marked *

Post comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.