Renewing SSL Certificates Behind CloudFlare

Posted in Uncategorized

For the longest time now I’ve been having issues with certbot not being able to create a certificate for my domain, returning the error

Attempting to renew cert (mydomain.com) from /home/ubuntu/.certbot/config/renewal/mydomain.com.conf produced an unexpected error: Failed authorization procedure. mydomain.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from https://mydomain.com/.well-known/acme-challenge/-jYlHtpK6x6LZ8B4KjHeY7RgchNFPoouXADS_XQtowc [2606:4700:3035::681c:1e6e]: “<!DOCTYPE html>\n<!–[if lt IE 7]> <html class=\”no-js ie6 oldie\” lang=\”en-US\”> <html class=\”no-js “. Skipping.

I think the reason for this is because I’m using Full (Strict) encryption mode in CloudFlare dashboard which requires a valid SSL certificate be present when communicating between my web server and CloudFlare.

Full (strict) SSL/TLS encryption mode with CloudFlare

The solution for this is instead of using certbot’s default authentication method, we instead make use of the certbot-dns-cloudflare plugin that will handle the Lets Encrypt challenge through DNS. This works by automatically creating and deleting our CloudFlare DNS TXT record for us during the certbot renew. Let’s set this up now.

Step 1 – Set up Certbot and Certbot-DNS-CloudFlare

Follow the installation instructions for certbot and certbot-dns-cloudflare. For me on Ubuntu 18.10 this was as simple as:

sudo snap install --classic certbot
snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare --beta

Step 2 – Retrieve your CloudFlare API Token

  • Head to your Cloudflare Dashboard API Tokens page by going to Profile – My Profile – API Tokens and under the API Tokens section click Create Token.
  • Click the Use template button next to Edit zone DNS
  • Under Zone Resources set the dropdown so it says “Include Specific zone mydomain.com”
  • Click Continue to Summary then Create Token.

Now just create the credentials file to be used with certbot-dns-cloudflare with your new token:

tee -a ~/.secrets/certbot/cloudflare.mydomain.ini > /dev/null <<EOT
# Cloudflare API token used by Certbot for all domains on mydomain account
dns_cloudflare_api_token = your_api_token
chmod 600 ~/.secrets/certbot/cloudflare.mydomain.ini

Step 3 – Retrieve the certificate

To retrieve the wildcard certificate for my domain I ran

sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.mydomain.ini -d *.mydomain.com

If all goes well you should see

Saving debug log to /home/ubuntu/.certbot/logs/letsencrypt.log
Plugins selected: Authenticator dns-cloudflare, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for mydomain.com
Waiting 10 seconds for DNS changes to propagate
Waiting for verification…
Cleaning up challenges
Non-standard path(s), might not work with crontab installed by your operating system package manager


  • Congratulations! Your certificate and chain have been saved at:
    Your key file has been saved at:
    Your cert will expire on 2020-12-30. To obtain a new or tweaked
    version of this certificate in the future, simply run certbot
    again. To non-interactively renew all of your certificates, run
    “certbot renew”
  • If you like Certbot, please consider supporting our work by: Donating to ISRG / Let’s Encrypt: https://letsencrypt.org/donate
    Donating to EFF: https://eff.org/donate-le

Note that this only created the certificate, it didn’t install it automatically like it normally would.