Hello,
I'm trying to configure Traefik with Let's Encrypt using DNS-01 challenge and the pdns
provider.
I already accomplished this scenario using cert-manager instead of Traefik and it works fine, but I had to add extra configuration because I'm using a split-horizon DNS setup.
My assumption is that the resolvers config for Traefik should accomplish the same behavior.
I am using the latest version of Traefik on a standalone Docker install :
Version: 2.10.5
Codename: saintmarcelin
Go version: go1.21.3
Built: 2023-10-11T13:54:02Z
OS/Arch: linux/amd64
Here is my configuration :
docker.compose.yml
version: "3.8"
networks:
traefik_public:
external: true
services:
server:
command: "--configFile=/configs/traefik_static_config.toml"
container_name: traefik
environment:
PDNS_API_KEY: "${PDNS_API_KEY}"
PDNS_API_URL: "${PDNS_API_URL}"
image: traefik:2.10.5
networks:
- traefik_public
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
restart: always
volumes:
- "server_certs:/certs"
- "server_config:/configs"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
volumes:
server_certs:
driver_opts:
device: "${VOLUMES_BASE_PATH}/traefik/server/certs"
o: bind
type: none
server_config:
driver_opts:
device: "${VOLUMES_BASE_PATH}/traefik/server/configs"
o: bind
type: none
traefik_static_config.toml
[accessLog]
[api]
dashboard = true
[certificatesResolvers.myresolver.acme]
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
email = "letsencrypt@example.com"
storage = "/certs/acme.json"
[certificatesResolvers.myresolver.acme.dnsChallenge]
provider = "pdns"
resolvers = ["192.168.1.1:53", "192.168.1.2:53"]
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web.http]
[entryPoints.web.http.redirections]
[entryPoints.web.http.redirections.entryPoint]
to = "websecure"
scheme = "https"
[entryPoints.websecure]
address = ":443"
[log]
level = "DEBUG"
[metrics]
[metrics.prometheus]
[ping]
[providers]
[providers.docker]
exposedByDefault = false
[providers.file]
filename = "/configs/traefik_dynamic_config.toml"
traefik_dynamic_config.toml
[tls.options]
[tls.options.default]
sniStrict = true
[tls.options.intermediate]
cipherSuites = [
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
]
minVersion = "VersionTLS12"
sniStrict = true
[tls.options.modern]
minVersion = "VersionTLS13"
sniStrict = true
And the log output in DEBUG level :
time="2023-10-25T05:09:37Z" level=info msg="Configuration loaded from file: /configs/traefik_static_config.toml"
time="2023-10-25T05:09:37Z" level=info msg="Traefik version 2.10.5 built on 2023-10-11T13:54:02Z"
time="2023-10-25T05:09:37Z" level=debug msg="Static configuration loaded {...}"
time="2023-10-25T05:09:37Z" level=info msg="\nStats collection is disabled.\nHelp us improve Traefik by turning this feature on :)\nMore details on: https://doc.traefik.io/traefik/contributing/data-collection/\n"
time="2023-10-25T05:09:37Z" level=debug msg="Configured Prometheus metrics" metricsProviderName=prometheus
time="2023-10-25T05:09:37Z" level=info msg="Starting provider aggregator aggregator.ProviderAggregator"
time="2023-10-25T05:09:37Z" level=debug msg="Starting TCP Server" entryPointName=websecure
time="2023-10-25T05:09:37Z" level=debug msg="Starting TCP Server" entryPointName=traefik
time="2023-10-25T05:09:37Z" level=debug msg="Starting TCP Server" entryPointName=web
time="2023-10-25T05:09:37Z" level=info msg="Starting provider *file.Provider"
time="2023-10-25T05:09:37Z" level=debug msg="*file.Provider provider configuration: {\"watch\":true,\"filename\":\"/configs/traefik_dynamic_config.toml\"}"
time="2023-10-25T05:09:37Z" level=info msg="Starting provider *traefik.Provider"
time="2023-10-25T05:09:37Z" level=debug msg="*traefik.Provider provider configuration: {}"
time="2023-10-25T05:09:37Z" level=info msg="Starting provider *docker.Provider"
time="2023-10-25T05:09:37Z" level=debug msg="*docker.Provider provider configuration: {\"watch\":true,\"endpoint\":\"unix:///var/run/docker.sock\",\"defaultRule\":\"Host(`{{ normalize .Name }}`)\",\"swarmModeRefreshSeconds\":\"15s\"}"
time="2023-10-25T05:09:37Z" level=info msg="Starting provider *acme.Provider"
time="2023-10-25T05:09:37Z" level=debug msg="*acme.Provider provider configuration: {...}"
time="2023-10-25T05:09:37Z" level=debug msg="Attempt to renew certificates \"720h0m0s\" before expiry and check every \"24h0m0s\"" ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory" providerName=myresolver.acme
time="2023-10-25T05:09:37Z" level=info msg="Testing certificate renew..." providerName=myresolver.acme ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory"
time="2023-10-25T05:09:37Z" level=info msg="Starting provider *acme.ChallengeTLSALPN"
time="2023-10-25T05:09:37Z" level=debug msg="*acme.ChallengeTLSALPN provider configuration: {}"
time="2023-10-25T05:09:37Z" level=debug msg="Configuration received: {...}" providerName=file
time="2023-10-25T05:09:37Z" level=debug msg="Configuration received: {...}" providerName=internal
time="2023-10-25T05:09:37Z" level=debug msg="Configuration received: {...}" providerName=myresolver.acme
time="2023-10-25T05:09:37Z" level=debug msg="Provider connection established with docker 24.0.6 (API 1.43)" providerName=docker
time="2023-10-25T05:09:37Z" level=debug msg="No default certificate, fallback to the internal generated certificate" tlsStoreName=default
time="2023-10-25T05:09:37Z" level=debug msg="Added outgoing tracing middleware noop@internal" middlewareName=tracing middlewareType=TracingForwarder entryPointName=web routerName=web-to-websecure@internal
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" entryPointName=web routerName=web-to-websecure@internal middlewareName=redirect-web-to-websecure@internal middlewareType=RedirectScheme
time="2023-10-25T05:09:37Z" level=debug msg="Setting up redirection to https 443" middlewareType=RedirectScheme entryPointName=web routerName=web-to-websecure@internal middlewareName=redirect-web-to-websecure@internal
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareName=traefik-internal-recovery middlewareType=Recovery entryPointName=web
time="2023-10-25T05:09:37Z" level=debug msg="Added outgoing tracing middleware prometheus@internal" entryPointName=traefik routerName=prometheus@internal middlewareName=tracing middlewareType=TracingForwarder
time="2023-10-25T05:09:37Z" level=debug msg="Added outgoing tracing middleware ping@internal" middlewareType=TracingForwarder entryPointName=traefik routerName=ping@internal middlewareName=tracing
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareName=traefik-internal-recovery middlewareType=Recovery entryPointName=traefik
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" entryPointName=websecure middlewareName=metrics-entrypoint middlewareType=Metrics
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" entryPointName=traefik middlewareName=metrics-entrypoint middlewareType=Metrics
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" entryPointName=web middlewareName=metrics-entrypoint middlewareType=Metrics
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" entryPointName=websecure middlewareName=metrics-entrypoint middlewareType=Metrics
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareType=Metrics entryPointName=traefik middlewareName=metrics-entrypoint
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareType=Metrics entryPointName=web middlewareName=metrics-entrypoint
time="2023-10-25T05:09:37Z" level=debug msg="No default certificate, fallback to the internal generated certificate" tlsStoreName=default
time="2023-10-25T05:09:37Z" level=debug msg="Added outgoing tracing middleware noop@internal" middlewareType=TracingForwarder entryPointName=web routerName=web-to-websecure@internal middlewareName=tracing
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareName=redirect-web-to-websecure@internal middlewareType=RedirectScheme entryPointName=web routerName=web-to-websecure@internal
time="2023-10-25T05:09:37Z" level=debug msg="Setting up redirection to https 443" entryPointName=web routerName=web-to-websecure@internal middlewareName=redirect-web-to-websecure@internal middlewareType=RedirectScheme
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" entryPointName=web middlewareName=traefik-internal-recovery middlewareType=Recovery
time="2023-10-25T05:09:37Z" level=debug msg="Added outgoing tracing middleware ping@internal" middlewareType=TracingForwarder entryPointName=traefik routerName=ping@internal middlewareName=tracing
time="2023-10-25T05:09:37Z" level=debug msg="Added outgoing tracing middleware prometheus@internal" middlewareName=tracing middlewareType=TracingForwarder entryPointName=traefik routerName=prometheus@internal
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" entryPointName=traefik middlewareName=traefik-internal-recovery middlewareType=Recovery
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareName=metrics-entrypoint middlewareType=Metrics entryPointName=websecure
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" entryPointName=traefik middlewareName=metrics-entrypoint middlewareType=Metrics
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" entryPointName=web middlewareType=Metrics middlewareName=metrics-entrypoint
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" routerName=nexttest@docker serviceName=app-test middlewareName=pipelining middlewareType=Pipelining entryPointName=websecure
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareName=metrics-service middlewareType=Metrics serviceName=app-test entryPointName=websecure routerName=nexttest@docker
time="2023-10-25T05:09:37Z" level=debug msg="Creating load-balancer" routerName=nexttest@docker serviceName=app-test entryPointName=websecure
time="2023-10-25T05:09:37Z" level=debug msg="Creating server 0 http://172.19.0.3:80" entryPointName=websecure routerName=nexttest@docker serviceName=app-test serverName=0
time="2023-10-25T05:09:37Z" level=debug msg="child http://172.19.0.3:80 now UP"
time="2023-10-25T05:09:37Z" level=debug msg="Propagating new UP status"
time="2023-10-25T05:09:37Z" level=debug msg="Added outgoing tracing middleware app-test" routerName=nexttest@docker middlewareName=tracing middlewareType=TracingForwarder entryPointName=websecure
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareType=Recovery entryPointName=websecure middlewareName=traefik-internal-recovery
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareName=metrics-entrypoint middlewareType=Metrics entryPointName=websecure
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareType=Metrics entryPointName=traefik middlewareName=metrics-entrypoint
time="2023-10-25T05:09:37Z" level=debug msg="Creating middleware" middlewareName=metrics-entrypoint entryPointName=web middlewareType=Metrics
time="2023-10-25T05:09:37Z" level=debug msg="Adding route for test.example.com with TLS options modern@file" entryPointName=websecure
time="2023-10-25T05:09:37Z" level=debug msg="Trying to challenge certificate for domain [test.example.com] found in HostSNI rule" ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory" routerName=nexttest@docker rule="Host(`test.example.com`)" providerName=myresolver.acme
time="2023-10-25T05:09:37Z" level=debug msg="Looking for provided certificate(s) to validate [\"test.example.com\"]..." providerName=myresolver.acme ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory" routerName=nexttest@docker rule="Host(`test.example.com`)"
time="2023-10-25T05:09:37Z" level=debug msg="Domains [\"test.example.com\"] need ACME certificates generation for domains \"test.example.com\"." ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory" routerName=nexttest@docker rule="Host(`test.example.com`)" providerName=myresolver.acme
time="2023-10-25T05:09:37Z" level=debug msg="Loading ACME certificates [test.example.com]..." providerName=myresolver.acme ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory" routerName=nexttest@docker rule="Host(`test.example.com`)"
time="2023-10-25T05:09:37Z" level=debug msg="Building ACME client..." providerName=myresolver.acme
time="2023-10-25T05:09:37Z" level=debug msg="https://acme-staging-v02.api.letsencrypt.org/directory" providerName=myresolver.acme
time="2023-10-25T05:09:37Z" level=debug msg="Using DNS Challenge provider: pdns" providerName=myresolver.acme
time="2023-10-25T05:09:38Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Obtaining bundled SAN certificate"
time="2023-10-25T05:09:38Z" level=debug msg="legolog: [INFO] [test.example.com] AuthURL: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/9058374894"
time="2023-10-25T05:09:38Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Could not find solver for: tls-alpn-01"
time="2023-10-25T05:09:38Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Could not find solver for: http-01"
time="2023-10-25T05:09:38Z" level=debug msg="legolog: [INFO] [test.example.com] acme: use dns-01 solver"
time="2023-10-25T05:09:38Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Preparing to solve DNS-01"
time="2023-10-25T05:09:38Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Trying to solve DNS-01"
time="2023-10-25T05:09:38Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Checking DNS record propagation using [192.168.1.1:53 192.168.1.2:53]"
time="2023-10-25T05:09:40Z" level=debug msg="legolog: [INFO] Wait for propagation [timeout: 2m0s, interval: 2s]"
time="2023-10-25T05:09:50Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Waiting for DNS record propagation."
time="2023-10-25T05:10:02Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Waiting for DNS record propagation."
time="2023-10-25T05:10:14Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Waiting for DNS record propagation."
time="2023-10-25T05:10:26Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Waiting for DNS record propagation."
time="2023-10-25T05:10:38Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Waiting for DNS record propagation."
time="2023-10-25T05:10:50Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Waiting for DNS record propagation."
time="2023-10-25T05:11:02Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Waiting for DNS record propagation."
time="2023-10-25T05:11:14Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Waiting for DNS record propagation."
time="2023-10-25T05:11:26Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Waiting for DNS record propagation."
time="2023-10-25T05:11:38Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Waiting for DNS record propagation."
time="2023-10-25T05:11:40Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Cleaning DNS-01 challenge"
time="2023-10-25T05:11:41Z" level=debug msg="legolog: [INFO] Deactivating auth: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/9058374894"
time="2023-10-25T05:11:41Z" level=error msg="Unable to obtain ACME certificate for domains \"test.example.com\": unable to generate a certificate for the domains [test.example.com]: error: one or more domains had a problem:\n[test.example.com] propagation: time limit exceeded: last error: read udp 172.19.0.2:47017->10.0.0.1:53: i/o timeout\n" routerName=nexttest@docker rule="Host(`test.example.com`)" providerName=myresolver.acme ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory"
You can see in the attached logs that the resolvers
config has been detected :
time="2023-10-25T05:09:38Z" level=debug msg="legolog: [INFO] [test.example.com] acme: Checking DNS record propagation using [192.168.1.1:53 192.168.1.2:53]"
But on the last line that those resolvers are not used, and instead the resolvers defined in /etc/resolv.conf
are used :
time="2023-10-25T05:11:41Z" level=error msg="Unable to obtain ACME certificate for domains \"test.example.com\": unable to generate a certificate for the domains [test.example.com]: error: one or more domains had a problem:\n[test.example.com] propagation: time limit exceeded: last error: read udp 172.19.0.2:47017->10.0.0.1:53: i/o timeout\n" routerName=test@docker rule="Host(`test.example.com`)" providerName=myresolver.acme ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory"
Does anyone encounter the same issue?