Using caddy with cloudflare DNS

1. The problem I’m having:

I was trying to set up caddy to provide automatic SSL certificates for my server for the communication between my server and cloudflare’s proxy.

I was following this article to update my existing configuration: How to use Caddy with Cloudflare's SSL settings

So I’ve generated an API TOKEN and set it up as an ENV variable on my server. I tested it whether caddy sees it with the caddy environ command and it successfully included the ENV I’ve set.

After that I’ve introduced a new entry into my Caddyfile with the proper tls setting and then reloaded caddy. And then it failed on the acme dns-01 challenge all the time.

2. Error messages and/or full log output:

May 14 12:25:31 pasztor-ubuntu caddy[766427]: {"level":"debug","ts":1715689531.0842526,"logger":"events","msg":"event","name":"cert_obtaining","id":"338c67bb-96ce-4e6b-bf31-bc6ac8e7a47c","origin":"tls","data":{"identifier":"bajnok.dev"}}
May 14 12:25:32 pasztor-ubuntu caddy[766427]: {"level":"info","ts":1715689532.163229,"logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"bajnok.dev","challenge_type":"dns-01","ca":"https://acme-staging-v02.api.letsencrypt.org/directory"}
May 14 12:25:32 pasztor-ubuntu caddy[766427]: {"level":"error","ts":1715689532.8927324,"logger":"tls.issuance.acme.acme_client","msg":"cleaning up solver","identifier":"bajnok.dev","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.bajnok.dev\" (usually OK if presenting also failed)"}
May 14 12:25:33 pasztor-ubuntu caddy[766427]: {"level":"error","ts":1715689533.3383815,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"bajnok.dev","issuer":"acme-v02.api.letsencrypt.org-directory","error":"[bajnok.dev] solving challenges: presenting for challenge: adding temporary record for zone \"bajnok.dev.\": got error status: HTTP 400: [{Code:6003 Message:Invalid request headers ErrorChain:[{Code:6111 Message:Invalid format for Authorization header}]}] (order=https://acme-staging-v02.api.letsencrypt.org/acme/order/148135954/16523492464) (ca=https://acme-staging-v02.api.letsencrypt.org/directory)"}
May 14 12:25:34 pasztor-ubuntu caddy[766427]: {"level":"info","ts":1715689534.337831,"logger":"tls.issuance.zerossl.acme_client","msg":"trying to solve challenge","identifier":"bajnok.dev","challenge_type":"dns-01","ca":"https://acme.zerossl.com/v2/DV90"}
May 14 12:25:35 pasztor-ubuntu caddy[766427]: {"level":"error","ts":1715689535.0150466,"logger":"tls.issuance.zerossl.acme_client","msg":"cleaning up solver","identifier":"bajnok.dev","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.bajnok.dev\" (usually OK if presenting also failed)"}
May 14 12:25:35 pasztor-ubuntu caddy[766427]: {"level":"error","ts":1715689535.3173115,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"bajnok.dev","issuer":"acme.zerossl.com-v2-DV90","error":"[bajnok.dev] solving challenges: presenting for challenge: adding temporary record for zone \"bajnok.dev.\": got error status: HTTP 400: [{Code:6003 Message:Invalid request headers ErrorChain:[{Code:6111 Message:Invalid format for Authorization header}]}] (order=https://acme.zerossl.com/v2/DV90/order/zTuE1iwK78z6rJduOQJyQg) (ca=https://acme.zerossl.com/v2/DV90)"}
May 14 12:25:35 pasztor-ubuntu caddy[766427]: {"level":"debug","ts":1715689535.3173385,"logger":"events","msg":"event","name":"cert_failed","id":"6fa41cb7-0620-4f4c-bb4f-b41ec9407742","origin":"tls","data":{"error":{},"identifier":"bajnok.dev","issuers":["acme-v02.api.letsencrypt.org-directory","acme.zerossl.com-v2-DV90"],"renewal":false}}
May 14 12:25:35 pasztor-ubuntu caddy[766427]: {"level":"error","ts":1715689535.3173678,"logger":"tls.obtain","msg":"will retry","error":"[bajnok.dev] Obtain: [bajnok.dev] solving challenges: presenting for challenge: adding temporary record for zone \"bajnok.dev.\": got error status: HTTP 400: [{Code:6003 Message:Invalid request headers ErrorChain:[{Code:6111 Message:Invalid format for Authorization header}]}] (order=https://acme.zerossl.com/v2/DV90/order/zTuE1iwK78z6rJduOQJyQg) (ca=https://acme.zerossl.com/v2/DV90)","attempt":2,"retrying_in":120,"elapsed":68.599980178,"max_duration":2592000}

3. Caddy version:

v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=

4. How I installed and ran Caddy:

a. System environment:

Distributor ID: Ubuntu
Description: Ubuntu 22.04.4 LTS
Release: 22.04
Codename: jammy

b. Command:

sudo systemctl daemon-reload 
sudo systemctl enable --now caddy

c. Service/unit/compose file:

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

d. My complete Caddy config:

{
        debug
        email vencel@bajnok.hu
        #       acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
        http_port 880
}

#: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
#}

bajnok.dev {
        tls {
                dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
        }
}

https://bajnok.hopto.org:9092 {
        reverse_proxy localhost:9091

        log {
                output file /var/log/caddy/transmission-client-access.log
        }
}

#https://transmission.bajnok.dev {
#       reverse_proxy localhost:9091
#
#        tls {
#               dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
#       }
#
#       log {
#                output file /var/log/caddy/transmission-client-access.log
#       }
#}

https://bajnok.hopto.org:2023 {
        reverse_proxy localhost:2024

        log {
                output file /var/log/caddy/vaultwarden-access.log
        }
}

#https://vault.bajnok.dev {
#        reverse_proxy localhost:2024
#        tls {
#                dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
#        }
#        log {
#                output file /var/log/caddy/vaultwarden-access.log
#        }
#}

https://bajnok.hopto.org:7000 {
        reverse_proxy localhost:32400

        log {
                output file /var/log/caddy/plex-access.log
        }
}

#https://champflix.bajnok.dev {
#        reverse_proxy localhost:32400
#
#       tls {
#               dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
#        }
#
#       log {
#                output file /var/log/caddy/plex-access.log
#        }
#}

https://bajnok.hopto.org:443 {
        reverse_proxy localhost:11000

        log {
                output file /var/log/caddy/nextcloud-access.log
        }
}

#https://bajnok.hopto.org:10001 {
#       reverse_proxy localhost:10000 {
#       }

#       log {
#               output file /var/log/caddy/webmin.log
#       }
#}
# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile

5. Links to relevant resources:

The caddy environ command will show the environment for your current user, not for the user Caddy runs as under systemd, i.e. the caddy user.

See Keep Caddy Running — Caddy Documentation for how to set up systemd config overrides, including setting env vars.

2 Likes