Caddy with Cloudflare

1. The problem I’m having:

Hi all. I’m trying to replace my nginx server with a caddy server for local reverse proxy with Cloudflare. I seem to be stuck at the certificate. I can see I’m reaching Cloudflare because caddy is creating a TXT entry when I try to reach my local server.

2. Error messages and/or full log output:

Jan 24 22:23:48 caddy-test caddy[2047]: {"level":"info","ts":1769293428.8995705,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"pihole-pves.7263377.xyz"}
Jan 24 22:23:48 caddy-test caddy[2047]: {"level":"debug","ts":1769293428.8997962,"logger":"tls.obtain","msg":"trying issuer 1/1","issuer":"acme-v02.api.letsencrypt.org-directory"}
Jan 24 22:24:12 caddy-test caddy[2047]: {"level":"error","ts":1769293452.6969388,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"pihole-pves.7263377.xyz","issuer":"acme-v02.api.letsencrypt.org-directory","error":"[pihole-pves.7263377.xyz] solving challenges: waiting for solver certmagic.solverWrapper to be ready: checking DNS propagation of \"_acme-challenge.pihole-pves.7263377.xyz.\" (relative=_acme-challenge.pihole-pves zone=7263377.xyz. resolvers=[192.168.31.20:53 192.168.31.21:53 192.168.31.22:53]): querying authoritative nameservers: dial tcp 162.159.44.99:53: i/o timeout (order=https://acme-staging-v02.api.letsencrypt.org/acme/order/260529023/31005917793) (ca=https://acme-staging-v02.api.letsencrypt.org/directory)"}
Jan 24 22:24:12 caddy-test caddy[2047]: {"level":"error","ts":1769293452.6969793,"logger":"tls.obtain","msg":"will retry","error":"[pihole-pves.7263377.xyz] Obtain: [pihole-pves.7263377.xyz] solving challenges: waiting for solver certmagic.solverWrapper to be ready: checking DNS propagation of \"_acme-challenge.pihole-pves.7263377.xyz.\" (relative=_acme-challenge.pihole-pves zone=7263377.xyz. resolvers=[192.168.31.20:53 192.168.31.21:53 192.168.31.22:53]): querying authoritative nameservers: dial tcp 162.159.44.99:53: i/o timeout (order=https://acme-staging-v02.api.letsencrypt.org/acme/order/260529023/31005917793) (ca=https://acme-staging-v02.api.letsencrypt.org/directory)","attempt":4,"retrying_in":300,"elapsed":395.339769645,"max_duration":2592000}

3. Caddy version:

v2.10.2 h1:g/gTYjGMD0dec+UgMw8SnfmJ3I9+M2TdvoRL/Ovu6U8=

4. How I installed and ran Caddy:

apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf ‘https://dl.cloudsmith.io/public/caddy/stable/gpg.key’ | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf ‘https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt’ | tee /etc/apt/sources.list.d/caddy-stable.list
chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
chmod o+r /etc/apt/sources.list.d/caddy-stable.list
apt update
apt install caddy
curl -o caddy ‘https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fcaddy-dns%2Fcloudflare’
systemctl stop caddy
chmod +x caddy
mv caddy /usr/bin/caddy
systemctl start caddy
nano /etc/caddy/.env

added the below to /etc/caddy/.env file
CLOUDFLARE_API_TOKEN=redacted_token

chmod 600 /etc/caddy/.env
chown caddy:caddy /etc/caddy/.env
systemctl edit caddy

Added the below to the caddy service
[Service]
EnvironmentFile=/etc/caddy/.env

a. System environment:

Debian 13 (trixie) AMD64 in a proxmox LXC

b. Command:

systemctl start caddy

c. Service/unit/compose file:

d. My complete Caddy config:

{
        debug
        acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
pihole-pves.7263377.xyz {

        reverse_proxy 192.168.31.21:80
}
# The Caddyfile is an easy way to configure your Caddy web server.
#
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace ":80" below with your
# domain name.

:80 {
        # Set this path to your site's directory.
        root * /usr/share/caddy

        # Enable the static file server.
        file_server

        # Another common task is to set up a reverse proxy:
        # reverse_proxy localhost:8080

        # Or serve a PHP site through php-fpm:
        # php_fastcgi localhost:9000
}

# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile

5. Links to relevant resources:

This suggests that the Cloudflare authoritative DNS servers cannot be reached. Firewall?

By the way, you can remove everything below your site block, that is, the comments and the :80 block. :slight_smile:

2 Likes

That’s kind of what I was thinking, but nginx works without issue. Not sure how they differ in how they handle DNS challenge, but they seem work in very different ways.