1. The problem I’m having:
Hello
I am not able to obtain an ACME certificate through the cloudflare tunnel.
The connection diagram is
client → https ->(bnc.xxx.com via cloudflare tunnel) → caddy → https → NextCloud
If the certificate is generated internally, caddy works (tls internal) but the DNS challenge times out.
I am using the correct module and I have added the suggested configuration in each timeout but nothing, there is no way.
In the Cloudflare dashboard I see that the record is created correctly.
P.S: It worked one time, when @timelordx told me that I have to do a DNS challenge but now I’m trying to create another certificate and I only get time outs.
Greetings and thanks in advance
2. Error messages and/or full log output:
caddy | {"level":"error","ts":1754503423.4597075,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"bnc.enunlugarignotoeinefable.com","issuer":"acme-v02.api.letsencrypt.org-directory","error":"[bnc.enunlugarignotoeinefable.com] solving challenges: waiting for solver certmagic.solverWrapper to be ready: timed out waiting for record to fully propagate; verify DNS provider configuration is correct - last error: <nil> (order=https://acme-v02.api.letsencrypt.org/acme/order/2566972211/415143911347) (ca=https://acme-v02.api.letsencrypt.org/directory)"}
3. Caddy version:
4. How I installed and ran Caddy:
FROM caddy:2.10.0-builder AS builder
RUN xcaddy build \\
–with github.com/corazawaf/coraza-caddy/v2@latest \\
–with github.com/hslatman/caddy-crowdsec-bouncer/http@main \\
–with github.com/hslatman/caddy-crowdsec-bouncer/appsec@main \\
–with github.com/hslatman/caddy-crowdsec-bouncer/layer4@main \\
–with github.com/WeidiDeng/caddy-cloudflare-ip \\
–with github.com/mholt/caddy-dynamicdns \\
–with github.com/caddy-dns/cloudflare \\
–with github.com/caddy-dns/duckdns
FROM caddy:2.10.0
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
a. System environment:
Raspbian x64
b. Command:
sudo docker compose up --build in order to see the log
c. Service/unit/compose file:
services:
caddy:
build:
context: .
dockerfile: Dockerfile
container_name: caddy
restart: unless-stopped
cap_add:
- NET_ADMIN
environment:
- CLOUDFLARE_API_TOKEN=$CLOUDFLARE_API_TOKEN
- DUCKDNS_API_TOKEN=$DUCKDNS_API_TOKEN
ports:
- 80:80
- 443:443
# - 443:443/udp
- 8123:8123
- 8443:8443
- 4080:4080
volumes:
- $DOCKERDIR/caddy/log:/var/log
- $DOCKERDIR/caddy/ruleset:/ruleset
- $DOCKERDIR/caddy/Caddyfile:/etc/caddy/Caddyfile
- $DOCKERDIR/caddy/data:/data
- $DOCKERDIR/caddy/config:/config
- $DOCKERDIR/certs/:/config/rlyeh
# Aquí irían las webs si siquiera meterlas o las configuraciones específicas para cada URL, como reglas personalizadas CRS
# - $DOCKERDIR/caddy/site:/srv
networks:
crowdsec:
security_opt:
- no-new-privileges=true
crowdsec:
image: docker.io/crowdsecurity/crowdsec:latest
container_name: crowdsec
restart: unless-stopped
environment:
- GID=1000
- COLLECTIONS=crowdsecurity/caddy crowdsecurity/http-cve crowdsecurity/base-http-scenarios crowdsecurity/appsec-generic-
rules crowdsecurity/linux crowdsecurity/sshd crowdsecurity/whitelist-good-actors crowdsecurity/iptables
- BOUNCER_KEY_CADDY=${CROWDSEC_API_KEY}
ports:
- 8080:8080
- 7422:7422
volumes:
- $DOCKERDIR/caddy/crowdsec_config:/etc/crowdsec
- crowdsec_db:/var/lib/crowdsec/data/
- $DOCKERDIR/caddy/log:/var/log/caddy:ro
networks:
crowdsec:
security_opt:
- no-new-privileges=true
volumes:
crowdsec_db:
networks:
crowdsec:
driver: bridge
d. My complete Caddy config:
{
#Esta es la zona de la definición de configuración global
#Se puedes deshabitar el auto_https para usar certificados propios, sino por defecto Caddy usa unos autofirmados para>
#auto_https off
#Token de la API Cloudflare que usa el módulo para la gestión ACME de Cloudflare
acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
#Configuración para el módulo de aceptar solo el tráfico proveniente del rango de IPs de cloudflare
servers {
trusted_proxies cloudflare {
interval 12h
timeout 15s
}
}
# Definición de duckdns como proveedor DNS par el módulo "caddy-dns/duckdns". Ver documento sobre porque está comentado.
# dns duckdns {env.DUCKDNS_API_TOKEN}
#Configuración para el módulo de gestión de duckdns
dynamic_dns {
provider duckdns {env.DUCKDNS_API_TOKEN}
domains {
duckdns.org xxx
}
}
# Ponemos el log de debug (crowsec usa los log para detectar anomalías)
log {
level DEBUG
}
#Habilitamos coraza
order coraza_waf first
#Habilitamos y configuramos crowdsec
crowdsec {
api_url http://localhost:8080
api_key <api_key>
ticker_interval 15s
appsec_url http://localhost:7422
disable_streaming
#enable_hard_fails
}
}
#Fin de la zona de configuración global
#Esta es la zona de definición de sites
#Configuración de reserve proxy (esto incluye la configuración para la inspección de coraza)
#Home Assistant
https://bha.xxx.com {
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
resolvers 1.1.1.1
propagation_timeout 10m
}
# coraza_waf {
# load_owasp_crs
# directives `
# Include @coraza.conf-recommended
# Include @crs-setup.conf.example
# Include @owasp_crs/*.conf
# SecRuleEngine On
# `
# }
reverse_proxy http://192.168.8.22:8123 {
# header_up X-Real-IP {client_ip}
# header_up X-Real-IP {remote_host}
}
log {
output file /var/log/caddy/homeassistant.log
}
}
#NextCloud
https://bnc.xxx.com {
#tls internal
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
resolvers 1.1.1.1
propagation_timeout 10m
}
# coraza_waf {
# load_owasp_crs
# directives `
# Include @coraza.conf-recommended
# Include @crs-setup.conf.example
# Include @owasp_crs/*.conf
# SecRuleEngine On
# `
# }
reverse_proxy https://192.168.8.20:5443 {
header_up X-Real-IP {remote_host}
transport http {
tls_trust_pool file /config/rlyeh/rlyeh-ca.pem
}
}
log {
output file /var/log/caddy/nextcloud.log
}
}