Beginner having troubles with wildcard certificates

Thank you for your reply!

In this post, I have replaced my domain with example.duckdns.org each time.

I deleted the commands, emptied acme.json and recreated traefik. This is my debug log now (they end with one error):

.......
2024-09-03T17:27:39+02:00 DBG github.com/go-acme/lego/v4@v4.17.4/log/logger.go:48 > [INFO] [vault.example.duckdns.org] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/398856408616 lib=lego

2024-09-03T17:27:39+02:00 DBG github.com/go-acme/lego/v4@v4.17.4/log/logger.go:48 > [INFO] [vault.example.duckdns.org] acme: Could not find solver for: tls-alpn-01 lib=lego

2024-09-03T17:27:39+02:00 DBG github.com/go-acme/lego/v4@v4.17.4/log/logger.go:48 > [INFO] [vault.example.duckdns.org] acme: Could not find solver for: http-01 lib=lego

2024-09-03T17:27:39+02:00 DBG github.com/go-acme/lego/v4@v4.17.4/log/logger.go:48 > [INFO] [vault.example.duckdns.org] acme: use dns-01 solver lib=lego

2024-09-03T17:27:39+02:00 DBG github.com/go-acme/lego/v4@v4.17.4/log/logger.go:48 > [INFO] [vault.example.duckdns.org] acme: Preparing to solve DNS-01 lib=lego

2024-09-03T17:27:44+02:00 DBG github.com/go-acme/lego/v4@v4.17.4/log/logger.go:48 > [INFO] [vault.example.duckdns.org] acme: Trying to solve DNS-01 lib=lego

2024-09-03T17:27:49+02:00 DBG github.com/go-acme/lego/v4@v4.17.4/log/logger.go:48 > [INFO] [vault.example.duckdns.org] acme: Checking DNS record propagation. [nameservers=1.1.1.1:53,8.8.8.8:53] lib=lego

2024-09-03T17:27:51+02:00 DBG github.com/go-acme/lego/v4@v4.17.4/log/logger.go:48 > [INFO] Wait for propagation [timeout: 1m0s, interval: 2s] lib=lego

2024-09-03T17:27:51+02:00 DBG github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:305 > Delaying 200000000000 rather than validating DNS propagation now. providerName=letsEncrypt.acme

2024-09-03T17:31:22+02:00 DBG github.com/go-acme/lego/v4@v4.17.4/log/logger.go:48 > [INFO] [vault.example.duckdns.org] acme: Cleaning DNS-01 challenge lib=lego

2024-09-03T17:31:31+02:00 DBG github.com/go-acme/lego/v4@v4.17.4/log/logger.go:48 > [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz-v3/398856408616 lib=lego

2024-09-03T17:31:32+02:00 ERR github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:396 > Unable to obtain ACME certificate for domains error="unable to generate a certificate for the domains [vault.example.duckdns.org]: error: one or more domains had a problem:\n[vault.example.duckdns.org] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Incorrect TXT record \"\" found at _acme-challenge.vault.example.duckdns.org\n" ACME CA=https://acme-v02.api.letsencrypt.org/directory acmeCA=https://acme-v02.api.letsencrypt.org/directory domains=[vault.example.duckdns.org] providerName=letsEncrypt.acme routerName=vault@docker rule=Host(`vault.example.duckdns.org`)

2024-09-03T17:43:58+02:00 DBG github.com/traefik/traefik/v3/pkg/tls/tlsmanager.go:216 > TLS: strict SNI enabled - No certificate found for domain: "vault.example.duckdns.org", closing connection

2024-09-03T17:43:58+02:00 DBG log/log.go:245 > http: TLS handshake error from 192.168.1.50:54711: tls: no certificates configured

2024-09-03T17:43:58+02:00 DBG github.com/traefik/traefik/v3/pkg/tls/tlsmanager.go:216 > TLS: strict SNI enabled - No certificate found for domain: "vault.example.duckdns.org", closing connection

2024-09-03T17:43:58+02:00 DBG log/log.go:245 > http: TLS handshake error from 192.168.1.50:54712: tls: no certificates configured

I am using example.duckdns.org as the main domain and *.example.duckdns.org as subdomains. So this way I can create as many subdomains as I want since they are actually sub-subdomains. In nginx proxy manager, wildcard certificates always worked fine for me and that was also with letsEncrypt.

It seems that I currently have 2 problems:

  • no wildcard certificate is requested
  • letsEncrypt is not set as the certificate resolver by default (unless I add traefik.http.routers.vault.tls.certresolver=letsEncrypt, as I did with vaultwarden only in this example --> see accompanying error in the log)

MY CONFIGURATION AT THE MOMENT:

COMPOSE

services:
  traefik:
    image: traefik:v3.1
    container_name: traefik
    security_opt:
      - no-new-privileges:true
    environment:
      - TZ=Europe/Amsterdam # Change this to your timezone
      - DUCKDNS_TOKEN=xxxxxxxxxxxxxxxxxx
    networks:
      - traefik-net
    ports:
      - 80:80 # HTTP entryPoints
      - 443:443 # HTTPS entryPoints
      - 8080:8080 # Dashbaord WebGui 
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - traefik_config:/etc/traefik  
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - traefik_traefik-logs:/var/log/traefik
    labels:
      - traefik.http.routers.https.service=api@internal
networks:
  traefik-net:
    external: true

volumes:
  traefik_config:
    external: true
  traefik_traefik-logs:
    external: true

TRAEFIK.YML

# Traefik static configuration file (/etc/traefik/traefik.yml)


#INSTALLEERT DE GEOBLOCK PLUG-IN

experimental:
  plugins:
    geoblock:
      moduleName: "github.com/PascalMinder/geoblock"
      version: "v0.2.5"


#SCHAKELT HET DASHBOARD IN

api:
  dashboard: true # Enable the dashboard
  insecure: true
#  debug: true


#IEDEREEN KOMT BINNEN VIA HHTPS MET CROWDSEC-BEVEILIGING

entryPoints:
  http:
    address: :80
    http:
      redirections:
        entryPoint:
          to: https
          scheme: https

  https:
    address: :443
    http:
      tls:
        certResolver: letsEncrypt
        domains:
          - main: "example.duckdns.org"
            sans:
              - "*.example.duckdns.org"
      middlewares:
        - crowdsec-bouncer@file                           # Create the HTTPS entrypoint on port 443


#ANDERE SHIT

serversTransport:
  insecureSkipVerify: true

global:
  checknewversion: true                       # Periodically check if a new version has been released.
  sendanonymoususage: false                    # Periodically send anonymous usage statistics.


#VERBINDING MET DE DOCKER LABELS

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"   # Listen to the UNIX Docker socket
    exposedByDefault: false                   # Only expose container that are explicitly enabled (using label traefik.enabled)
#    network: "traefik-net"                    # Default network to use for connections to all containers.
    defaultRule: "Host(`{{ if index .Labels \"com.docker.compose.service\" }}{{ index .Labels \"com.docker.compose.service\" }}{{ else }}{{ .Name }}{{ end }}.example.duckdns.org`)" #EERST IF OPTIE IS VOOR CONTAINERS GEMAAKT MET COMPOSE --> GEBRUIKT CONTAINER-NAAM
  file:
    filename: "/etc/traefik/config.yml"       # Link to the dynamic configuration
    watch: true                               # Watch for modifications
  providersThrottleDuration: 10               # Configuration reload frequency


#LET'S ENCRYPT CERTIFICATEN

certificatesResolvers:               # Certificate Resolvers are responsible for retrieving certificates from an ACME server
  letsEncrypt:                       # See https://doc.traefik.io/traefik/https/acme/#certificate-resolvers
    acme:
      email: "xxxxxxx@hotmail.com"  # Email address used for registration
      storage: "/etc/traefik/acme/acme.json"    # File or key used for certificates storage
      caServer: https://acme-v02.api.letsencrypt.org/directory # prod (default)
      # caServer: https://acme-staging-v02.api.letsencrypt.org/directory # staging
      dnsChallenge:
        provider: duckdns
        disablePropagationCheck: true
        delayBeforeCheck: 200
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"


#LOGS VOOR CROWDSEC

log:
  level: "DEBUG"
#  filePath: "/var/log/traefik/traefik.log"
accessLog:
  filePath: "/var/log/traefik/access.log"

CONFIG.YML

# Traefik dynamic configuration file
# See https://doc.traefik.io/traefik/getting-started/configuration-overview/#the-dynamic-configuration




#MIDDLEWARES

http:
  middlewares:


#PRESETS: LOKAAL, AUTH, AUTHAPP, PUBLIEK, PUBLIEKBE

    #PUBLIEKBE --> Use with traefik.http.routers.myRouter.middlewares: "publiekbe@file"
    publiekbe:
      chain:
        middlewares:
          - default-security-headers
          - error-pages
          - BE-GeoBlock


    #LOKAAL --> Use with traefik.http.routers.myRouter.middlewares: "lokaal@file"
    lokaal:
      chain:
        middlewares:
          - default-security-headers
          - error-pages
          - BE-GeoBlock
          - iplokaal


    #AUTH, AUTHAPP, PUBLIEK -----> not made yet








#VERSCHILLENDE MIDDLE-WARES DEFINIËREN

    iplokaal:
      ipAllowList:
        sourceRange:
          - "192.168.1.0/24"

    crowdsec-bouncer:
      forwardauth:
        address: http://bouncer-traefik:8080/api/v1/forwardAuth
        trustForwardHeader: true

    traefikAuth:               # A basic authentification middleware, to protect the Traefik dashboard to anyone except myself
      basicAuth:               # Use with traefik.http.routers.myRouter.middlewares: "traefikAuth@file"
        users:
          - "admin:hashedpassword"

    default-security-headers:                 # Use with traefik.http.routers.myRouter.middlewares: "default-security-headers@file"
      headers:
        browserXssFilter: true                            # X-XSS-Protection=1; mode=block
        contentTypeNosniff: true                          # X-Content-Type-Options=nosniff
        forceSTSHeader: true                              # Add the Strict-Transport-Security header even when the connection is HTTP
        frameDeny: true                                   # X-Frame-Options=deny
        referrerPolicy: "strict-origin-when-cross-origin"
        sslRedirect: true                                 # Allow only https requests
        stsIncludeSubdomains: true                        # Add includeSubdomains to the Strict-Transport-Security header
        stsPreload: true                                  # Add preload flag appended to the Strict-Transport-Security header
        stsSeconds: 63072000                              # Set the max-age of the Strict-Transport-Security header (63072000 = 2 years)

    BE-GeoBlock:
      plugin:
        geoblock:
          silentStartUp: false
          allowLocalRequests: true
          logLocalRequests: false
          logAllowedRequests: false
          logApiRequests: false
          api: "https://get.geojs.io/v1/ip/country/{ip}"
          apiTimeoutMs: 500
          cacheSize: 25
          forceMonthlyUpdate: true
          allowUnknownCountries: false
          unknownCountryApiResponse: "nil"
          countries:
            - BE

    error-pages:                           # Serve the error pages when the status is included inside the following ranges
      errors:                              # Use with traefik.http.routers.myRouter.middlewares: "error-pages@file"
        query: "erreur{status}/"
        service: traefik-error-pages
        status:
          - "403-404"
          - "500"
          - "503"


  services:
    # Error pages
    traefik-error-pages:
      loadBalancer:
        servers:
          - url: "https://www.usherbrooke.ca/error-pages/"


#DEFINIËREN VAN TLS VERSIES: MODERN, INTERMEDIATE en OLD

tls:                                                           # See https://doc.traefik.io/traefik/https/tls/

  options:


    # To use with the label "traefik.http.routers.myrouter.tls.options=modern@file"
    modern:
      minVersion: "VersionTLS13"                          # Minimum TLS Version
      sniStrict: true                                     # Strict SNI Checking


    # To use with the label "traefik.http.routers.myrouter.tls.options=intermediate@file"
    intermediate:
      cipherSuites:
        - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
        - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
        - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
        - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
        - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"
        - "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
      minVersion: "VersionTLS12"                          # Minimum TLS Version
      sniStrict: true                                     # Strict SNI Checking


    # To use with the label "traefik.http.routers.myrouter.tls.options=old@file"
    old:
      cipherSuites:
        - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
        - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
        - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
        - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
        - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"
        - "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
        - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
        - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
        - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
        - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
        - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
        - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
        - "TLS_RSA_WITH_AES_128_GCM_SHA256"
        - "TLS_RSA_WITH_AES_256_GCM_SHA384"
        - "TLS_RSA_WITH_AES_128_CBC_SHA256"
        - "TLS_RSA_WITH_AES_128_CBC_SHA"
        - "TLS_RSA_WITH_AES_256_CBC_SHA"
        - "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
      minVersion: "TLSv1"                                 # Minimum TLS Version
      sniStrict: true                                     # Strict SNI Checking


#STANDAARD LETSENCRYPT CERTIFICAAT INSTELLEN


#  stores:
#    default:
#      defaultGeneratedCert:
#        resolver: letsEncrypt
#        domain:
#          - main: "example.duckdns.org"
#            sans:
#              - "*.example.duckdns.org"

VAULTWARDEN LABELS

traefik.enable=true
traefik.http.routers.vault.entrypoints=https
traefik.http.routers.vault.middlewares=lokaal@file
traefik.http.routers.vault.rule=Host(`vault.example.duckdns.org`)
traefik.http.routers.vault.tls=true
traefik.http.routers.vault.tls.certresolver=letsEncrypt
traefik.http.routers.vault.tls.options=modern@file
traefik.http.services.vault.loadbalancer.server.port=80

RALLLY LABELS

traefik.enable=true
traefik.http.routers.rallly.entrypoints=https
traefik.http.routers.rallly.middlewares=publiekbe@file
traefik.http.routers.rallly.tls.options=modern@file
traefik.http.services.rallly.loadbalancer.server.port=3000