Unable to obtain ACME CERT

Recently my docker install of Traefik stopped updating ACME certs. When bringing up the container I get the following error. I've tried updating my DuckDNS token to no avail.

traefik | time="2023-05-19T14:52:15-04:00" level=error msg="Unable to obtain ACME certificate for domains "XXX.duckdns.org,.XXX.duckdns.org"" rule="Host(traefik-dashboard.XXX.duckdns.org)" error="unable to generate a certificate for the domains [XXX.duckdns.org .XXX.duckdns.org]: error: one or more domains had a problem:\n[.XXX.duckdns.org] [.XXX.duckdns.org] acme: error presenting token: request to change TXT record for DuckDNS returned the following result (KO) this does not match expectation (OK) used url [https://www.duckdns.org/update?clear=false&domains=XXX.duckdns.org&token=+5XXXXXXXXXXXXXXXXXXXXXXXXXXXXX7&txt7&txt=JqrQjiu_AsVCdFXsHVWHTFGmqjjCyrm83TvZVnbzYvY]\n[XXX.duckdns.org] [XXX.duckdns.org] acme: error presenting token: request to change TXT record for DuckDNS returned the following result (KO) this does not match expectation (OK) used url [https://www.duckdns.org/update?clear=false&domains=XXX.duckdns.org&token=+5XXXXXXXXXXXXXXXXXXXXXXXXXXXXX7&txt=WvYJiyof5rSt6-mFZuobrHcGttodyCk1dBboxrhYBQQ]\n" providerName=letsencrypt.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=traefik-secure@docker

Docker-compose

 traefik:
    # The official v2 Traefik docker image
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - proxy
    ports:
      # The HTTP port
      - 80:80
      - 443:443
      # The Web UI (enabled by --api.insecure=true)
      - 8080:8080
    environment:
      - SUBDOMAINS= $SUBDOMAIN_NAME
      - DUCKDNS_TOKEN= $DUCKDNS_TOKEN
    volumes:
      # So that Traefik can listen to the Docker events, NOT SECURE
      # run without and if needed setup proxy
      - /var/run/docker.sock:/var/run/docker.sock
      # Standard
      - /opt/traefik/traefik.yml:/traefik.yml:ro
      - /opt/traefik/config.yml:/config.yml:ro
      - /etc/localtime:/etc/localtime:ro
      - /opt/traefik/acme/acme.json:/acme.json
      # .htpasswd
      - /opt/traefik/.htpasswd:/shared/.htpasswd   
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`traefik-dashboard.XXX.duckdns.org`)"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=local:ZZZZZZZZZZZZZZZZZZZZZZZZZ."
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`traefik-dashboard.XXX.duckdns.org`)"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=letsencrypt"
      - "traefik.http.routers.traefik-secure.tls.domains[0].main=XXX.duckdns.org"
      - "traefik.http.routers.traefik-secure.tls.domains[0].sans=*.XXX.duckdns.org"
      - "traefik.http.routers.traefik-secure.service=api@internal"

Traefik.yml

log:
  level: ERROR
api:
  dashboard: true
  insecure: true
  debug: true
entryPoints: 
  http:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: https
          scheme: https
  https:
    address: ":443"
serversTransport:
  insecureSkipVerify: true
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    filename: /config.yml
certificatesResolvers:
  letsencrypt:
    acme:
      email: me@web.com
      storage: acme.json
      dnsChallenge:
        provider: duckdns
        #disablePropagationCheck: true # uncomment this if you have issues pulling certificates through cloudflare, By setting this flag to true disables the need to wait for the propagation of the TXT record to all authoritative name servers.
        delayBeforeCheck: 0
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"

Config.yml

http:
 #region routers 
  routers:
    pihole:
      entryPoints:
        - "https"
      rule: "Host(`pihole.XXX.duckdns.org`)"
      middlewares:
        - default-headers
        - addprefix-pihole
        - https-redirectscheme
      tls: {}
      service: pihole
    homebridge:
      entryPoints:
        - "https"
      rule: "Host(`homebridge.XXX.duckdns.org`)"
      middlewares:
        - default-headers
        - https-redirectscheme
      tls: {}
      service: homebridge
    homeassistant:
      # For Homeassistant config, check: https://www.home-assistant.io/integrations/http/#reverse-proxies
      # This relies on Homeassistant using http. No certs are needed in the Homeassistant config.
      entryPoints:
        - "https"
      rule: "Host(`homeassistant.XXX.duckdns.org`)"
      middlewares:
        - default-headers
        - https-redirectscheme
      tls: {}
      service: homeassistant
    plex:
      entryPoints:
        - "https"
      rule: "Host(`plex.XXX.duckdns.org`)"
      middlewares:
        - default-headers
        - https-redirectscheme
      tls: {}
      service: plex
    #testing servers
    #tadarr:
     # entrypoints:
      # - "https"
      #rule: "host('tadarr.XXX.duckdns.org')"
      #middlewares:
      #  - default-headers
      #  - https-redirectscheme
      #tls: {}
      #service: tadarr    

#endregion
#region services
  services:
    pihole:
      loadBalancer:
        servers:
          - url: "http://192.168.1.2:80"
        passHostHeader: true
    homebridge:
      loadBalancer:
        servers:
          - url: "http://192.168.1.102:10999"
        passHostHeader: true
    homeassistant:
      loadBalancer:
        servers:
          - url: "http://192.168.1.102:10999"
        passHostHeader: true
    plex:
      loadBalancer:
        servers:
          - url: "https://192.168.1.4:32400"
        passHostHeader: true
    #testing    
    #tdarr:
     #loadBalancer:
      # servers:
       #  - url: "https://192.168.1."
#endregion
  middlewares:
    addprefix-pihole:
      addPrefix:
        prefix: "/admin"
    https-redirectscheme:
      redirectScheme:
        scheme: https
        permanent: true

    default-headers:
      headers:
        frameDeny: true
        browserXssFilter: true
        contentTypeNosniff: true
        forceSTSHeader: true
        stsIncludeSubdomains: true
        stsPreload: true
        stsSeconds: 15552000
        customFrameOptionsValue: SAMEORIGIN
        customRequestHeaders:
          X-Forwarded-Proto: https

    default-whitelist:
      ipWhiteList:
        sourceRange:
        - "10.0.0.0/8"
        - "192.168.0.0/24"
        - "172.16.0.0/12"

    secured:
      chain:
        middlewares:
        - default-whitelist
        - default-headers

Do you use latest version v2.10 of Traefik?

Currently running V2.10.1

Share your Traefik static and dynamic config, and docker-compose.yml if used.

Why not use simpler tlsChallenge? You usually only need dnsChallenge for wildcard certs.

Added them to the intial post.

Don't I need wildcards or is a there another way to host all of the pages?

If you have plain Host() for every router you can simply use tlsChallenge.

I did the following per your recommendation listed below. After recreating acme.json and Traefik, I no longer get a CERT error with 2 differents CERTs contained. Now I am getting a bunch of host errors and still can only successful get to Traefik via 8080. Local and domain https are giving "404 page not found" but xxx.duckdns.org is now secure, lol.

errors

time="2023-05-20T11:27:37-04:00" level=info msg="Configuration loaded from file: /traefik.yml"
time="2023-05-20T11:27:38-04:00" level=error msg="no args for matcher Host" routerName=pihole@file entryPointName=https
time="2023-05-20T11:27:38-04:00" level=error msg="no args for matcher Host" routerName=plex@file entryPointName=https
time="2023-05-20T11:27:38-04:00" level=error msg="no args for matcher Host" routerName=traefik@docker entryPointName=http
time="2023-05-20T11:27:38-04:00" level=error msg="no args for matcher Host" entryPointName=https routerName=plex@file
time="2023-05-20T11:27:38-04:00" level=error msg="no args for matcher Host" entryPointName=https routerName=traefik-secure@docker
time="2023-05-20T11:27:38-04:00" level=error msg="no args for matcher Host" entryPointName=https routerName=pihole@file
time="2023-05-20T11:27:46-04:00" level=error msg="no args for matcher Host" routerName=traefik@docker entryPointName=http
time="2023-05-20T11:27:46-04:00" level=error msg="no args for matcher Host" routerName=pihole@file entryPointName=https
time="2023-05-20T11:27:46-04:00" level=error msg="no args for matcher Host" entryPointName=https routerName=plex@file
time="2023-05-20T11:27:46-04:00" level=error msg="no args for matcher Host" routerName=traefik-secure@docker entryPointName=https
time="2023-05-20T11:27:54-04:00" level=error msg="no args for matcher Host" routerName=traefik@docker entryPointName=http
time="2023-05-20T11:27:54-04:00" level=error msg="no args for matcher Host" routerName=pihole@file entryPointName=https
time="2023-05-20T11:27:54-04:00" level=error msg="no args for matcher Host" entryPointName=https routerName=plex@file
time="2023-05-20T11:27:54-04:00" level=error msg="no args for matcher Host" entryPointName=https routerName=traefik-secure@docker
time="2023-05-20T11:28:02-04:00" level=error msg="no args for matcher Host" entryPointName=http routerName=traefik@docker
time="2023-05-20T11:28:02-04:00" level=error msg="no args for matcher Host" routerName=pihole@file entryPointName=https
time="2023-05-20T11:28:02-04:00" level=error msg="no args for matcher Host" entryPointName=https routerName=plex@file
time="2023-05-20T11:28:02-04:00" level=error msg="no args for matcher Host" entryPointName=https routerName=traefik-secure@docker

Compose: commenting out sans for wildcard and making traefiks host rule plain.

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      #- "traefik.http.routers.traefik.rule=Host(`traefik-dashboard.XXX.duckdns.org`)"
      - "traefik.http.routers.traefik.rule=Host()"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=local:$$apr1$$ZZZZZZZ."
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      #- "traefik.http.routers.traefik-secure.rule=Host(`traefik-dashboard.XXX.duckdns.org`)"
      - "traefik.http.routers.traefik-secure.rule=Host()"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=letsencrypt"
      - "traefik.http.routers.traefik-secure.tls.domains[0].main=XXX.duckdns.org"
      #- "traefik.http.routers.traefik-secure.tls.domains[0].sans=*.XXX.duckdns.org"
      - "traefik.http.routers.traefik-secure.service=api@internal"

config.yml: example making pihole plain.

http:
 #region routers 
  routers:
    pihole:
      entryPoints:
        - "https"
      rule: "Host()"
      middlewares:
        - default-headers
        - addprefix-pihole
        - https-redirectscheme
      tls: {}
      service: pihole

traefik.yml for TLS

certificatesResolvers:
  letsencrypt:
    acme:
      tlsChallenge: {}

Sorry I was unclear, of course you need to put the domain into Host(). But you need no main/sans. Check this simple Traefik example.

Thank you. HTTPS works now but only if I use https://domain.duckdns.org, if I included www. It wont work. Nor does HTTP redirect. That's fine though now to figure out how to make the rest play nice without wildcards.

You need to make sure to include the additional www. domain in your router

.rule=Host(`whoami.example.com`) || Host(`www.whoami.example.com`)

And you need to make sure you have both domains registered with DuckDNS and have both point to your Traefik instance IP.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.