Skip to content

Obtaining Let's Encrypt certificate using Cloudflare

Introduction

HTTPS is the current standard for secure access to webpages, even in your homelab environment. However, most self-hosted applications by default use HTTP. To enable HTTPS you can use self-signed certificates, but then when accessing application, you will be prompted to trust self-signed certificate. On some devices like Android, this can be very troublesome because you need to trust self-signed certificate every time you open webpage. To solve this problem you need to add RootCA certificate to the system, which is also a troublesome process. Less troublesome solution is to use Let's Encrypt certificates. In this post, I will show you how to obtain such certificate for single host in your homelab.

UPDATE 2025-11-15: Added paragraph "Bonus - Copying certificates" at the end of article describing how to auto copy certificates to other directories.

OS used: Debian 12
Software used: certbot 2.1.0

Source

Prerequisites

For Let's Encrypt to work with the instructions in this post, you will need:

  • Have a domain - Buy one that you like or if you don't want to pay you can use free and popular DuckDNS. DuckDNS can be used to obtain Let's Encrypt certificates without the need of Cloudflare, but it is out of scope of this tutorial.
  • Create free Cloudflare account - This instruction is written for use with Cloudflare free account.
  • Router with DNS server or DNS server in local network for example Pi-hole.

Let's Encrypt information

Most popular application to get certificates from Let's Encrypt is called certbot. certbot can work in different modes to get certificates:

  • HTTP challenge/response - certbot starts its own web server which is used for obtaining certificates. For this method to work, you need to have port 80 open and forwarded to your server. This limits to only one certbot running in your network (because of port forwarding on your router) and it's on you how to distribute obtained certificates to one or more hosts.
  • DNS challenge/response - Validation for obtaining certificates is put in TXT field of a DNS record. So certbot needs to edit the DNS record, which is why you need a DNS provider with a supported API for this to work.

Note

You can read more about different challenge types here Let's Encrypt documentation - Challenge Types.

Installing certbot

Install cerbot on the server where you want to obtain certificates.

$ sudo apt install certbot python3-certbot-dns-cloudflare

Automatic renewal of certificates

Let's Encrypt certificates are issued for 3 months. After that you need to get new certificates. Debian certbot package automatically creates systemd timer that checks for new certificate twice a day. Timer location is /lib/systemd/system/certbot.timer.

You can list systemd timer with command:

$ systemctl list-timers

Cloudflare configuration with your domain

Log in to Cloudflare and perform following actions (this instruction will assume that your domain is example.com).

Cloudflare DNS

Add your domain to Cloudflare:

  • Click Home > click Add site > for example example.com > click Add site
  • Click DNS > click button at the bottom Continue > find entry Cloudflare's nameservers > enter those nameservers where you bought your domain
  • In Cloudflare dashboard enter your added site
  • Click DNS > Records > click Add record:
  • Create A DNS record:
    • Type: A
    • Name: - for example myservername.homelab
    • IPv4 address: 127.0.0.1 - to annoy script kiddies pinging your host, DNS record on Cloudflare is only needed for obtaining certificate, IP address resoultion will be performed on your local DNS server
    • Proxy: disable

Cloudflare API Token

You need Cloudflare API Token for certbot to be able to modify TXT field of your DNS record.

  • Click Avatar in right top corner > My Profile > API Tokens > click Create Token > Create Custom Token:
  • Token name - enter name for your Token
  • Permissions - create 2 entries and set following values in fields:
    • Zone | Zone | Read
    • Zone | DNS | Edit
  • Zone Resources - set following
    • Include | Specific zone | chose your zone created earlier
    • Example: Include | Specific zone | example.com
  • Client IP Address Filtering - if you have dynamic Public IP you can leave it empty
  • TTL - leave empty for Token to be valid forever
  • Click Continue to summary > click Create Token
  • Copy Token - Token will be shown only once, if you loose it, delete it and generate new Token
  • Create credentials file with text editor on your server and enter there obtained Token:
$ sudo mkdir -m 700 -p /root/certbot && \
  sudo vim /root/certbot/cloudflare.ini

-m 700 - rwx --- --- permissions for /root/certbot directory

/root/certbot/cloudflare.ini
dns_cloudflare_api_token = <put-your-token-here>
  • Secure the file:
$ sudo chmod 600 /root/certbot/cloudflare.ini

DNS server configuration

Enter your domain name and IP address in your local DNS server, for example:
DNS A record: myservername.homelab.example.com | IPv4 address: 192.168.1.46.

Obtain certificate

Obtain a certificate:

$ sudo certbot certonly \
       --dns-cloudflare \
       --dns-cloudflare-credentials /root/certbot/cloudflare.ini \
       -d "myservername.homelab.example.com"

After running this command you will need to:

  • Enter email address used for urgent notices from Let's Encrypt
  • Accept Let's Encrypt Terms of Service
  • Answer it you want to receive emails from Electronic Frontier Foundation (organization that develops certbot)

Certificates

Obtained certificates will be put in folder: /etc/letsencrypt/live/<your_domain_name>/

Command to list certificates:

$ sudo certbot certificates

Now you can reference the certificate in application's configuration, create a symbolic link to it, or copy it, according to the documentation of web application you will be using with HTTPS. If you copy the certificate, remember to do this periodically with a script because the certificate is valid only for 90 days and after that time is automatically renewed by certbot in its original location.

Bonus - Copying certificates

Following instruction demonstrates how to auto copy obtained certificate to other directory. It is needed for Docker because containers can't read symlinks which certbot uses in certificate folder (/etc/letsencrypt/live/). To auto copy certificate we will use the fact that certificate renewal command is run 2 times per day by certbot.timer (which invokes certbot.service) and certbot has option to run command after successful certificate renewal. Both timer and service are located in /usr/lib/systemd/system/.

Create script file in /etc/letsencrypt/renewal-hooks/deploy/ folder that will be run after a successful certificate renewal:

$ sudo vim /etc/letsencrypt/renewal-hooks/deploy/copy-certificate
/etc/letsencrypt/renewal-hooks/deploy/copy-certificate
cp /etc/letsencrypt/live/<your_domain_name>/fullchain.pem /path/to/folder/certificate.crt
cp /etc/letsencrypt/live/<your_domain_name>/privkey.pem /path/to/folder/private.key

path/to/folder - enter path where to copy certificate and certificate private key

Make file executable:

$ sudo chmod 744 /etc/letsencrypt/renewal-hooks/deploy/copy-certificate

Force certificate renewal:

$ sudo certbot renew --force-renewal

Check if certificate and certificate private key was copied to specified folder:

$ ls -la /path/to/folder/<your_domain_name>/