Certbot DNS Challenge
I’ve been using Certbot for a while now to manage my SSL certificates, using the http challenge to validate my domain ownership, but the process is very tedious: I needed to stop the NGINX server in order to certbot start the http server for the HTTP challenge and I also needed to disable the proxy on Cloudflare.
Has you can see, this is a very cumbersome process, so I decided to use the DNS challenge instead. This way, I avoid a lot of manual steps.
In this post, I’ll show you how to use the DNS challenge with Cloudflare. I’ll assume that you already have a domain and that you already have a Cloudflare account, since I’ll not cover those steps. I ran this commands on a Ubuntu 20.04 and 22.04 server, as well as Debian 11.
First of all, install the necessary packages:
sudo apt update
sudo apt install certbot python3-certbot-nginx python3-certbot-dns-cloudflare -y
Run the following command generate the certificates:
Note: In the command, you need to successfully make the HTTP challenge.
sudo certbot --nginx -d example.com
When running with the --nginx
flag, it will automatically configure the NGINX server to use the certificates and add configuration for the domain. Since I personally prefer to manage the NGINX configuration myself, I’ll show you how to do it manually.
# comment out the config related to the domain that you used to configure nginx
sudo vim /etc/nginx/sites-enabled/default
Add the following configuration to the NGINX server in /etc/nginx/conf.d/example.com.conf
.
Note: If you don’t run the certbot command with the flag
--nginx
, it will not generage theoptions-ssl-nginx.conf
and thessl_dhparam
.
server {
server_name example.com;
location / {
proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_buffering off;
}
# Following configuration is maintained by Let's Encrypt/Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name example.com;
listen 80;
return 404; # managed by Certbot
}
Make sure you generate a Cloudflare API Token key and store it in a safe place. You’ll need it to renew the certificates.
# create the following file that stores the cloudflare token key,
# used to renew the ssl certificate
vim cloudflare.ini
dns_cloudflare_api_token = <insert token>
Finally, run the certbort command using DNS challenge to generate the certificates and check if everything is working:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /path/to/cloudflare.ini \
-d example.com
If the command runs successfully, it should tell you that the certificates were generated and that it is scheculed to renew them.