Beginner having troubles with wildcard certificates

Hey all, I am currently on school break and have spent almost 6 full days (and several nights) on traefik now. I have a whole configuration in mind, but it just doesn't want to work. It seems to be a certificate problem, since traefik does not seem to create any wildcard wertificate at all.

So this is my traefik.yml:

#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: "mysubdomain.duckdns.org"
            sans:
              - "*.mysubdomain.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 }}.jvr2.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: "mymailbox@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: "INFO"
  filePath: "/var/log/traefik/traefik.log"
accessLog:
  filePath: "/var/log/traefik/access.log"

This is my config.yml:

                                                                                                                                                                                                                                                                                                                               
#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


    #REST MOET IK NOG MAKEN








#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




# Generated 2021-08-12, Mozilla Guideline v5.6, Traefik 2.4.8
#   https://ssl-config.mozilla.org/#server=traefik&version=2.4.8&config=old&guideline=5.6
#   https://ssl-config.mozilla.org/#server=traefik&version=2.4.8&config=intermediate&guideline=5.6

And this is my traefik docker container (it was a portainer stack, but i changed some things in the GUI):

Portainer:

image: traefik:v3.1

ports: 80:80 443:443 8080:8080

command: 'traefik' '--log.level=DEBUG'
entrypoint: /entrypoint.sh

volumes: 
/var/run/docker.sock:/var/run/docker.sock
/etc/localtime:/etc/localtime
traefik_config:/etc/traefik
traefik_traefik-logs:/var/log/traefik

network: traefik-net

env: 
TZ=Europe/Amsterdam
DUCKDNS_TOKEN=MYDUCKDNSTOKEN
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin (something that came automatic, I think)

labels:
traefik.http.routers.traefik-secure.service=api@internal

restart-policy: unless-stoped


As an example, I then give my docker containers the following labels in portainer:

A CONTAINER PUBLICLY ACCESSIBLE FROM BELGIUM


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

network: traefik-net

A CONTAINERS THAT CAN ONLY BE ACCESSED LOCALLY


traefik.enable=true

traefik.http.routers.stirling-pdf.entrypoints=https

traefik.http.routers.stirling-pdf.middlewares=local@file

traefik.http.routers.stirling-pdf.tls.options=modern@file

network: traefik-net

--> This only seems to work half the time due to certificate issues. Traefik often does not create certificates, and certainly not wildcard certificates (which is what it is supposed to do)! Could someone please relieve me of my mounting frustration? Thanks in advance!!!! :slight_smile:

What are the messages in Traefik debug log?

Note that you can’t use static config in traefik.yml and command: at the same time, decide for one (doc).

Will DuckDNS create wildcards? The free service only allows 5 sub-domains AFAIK.

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

There is a single error:

Did you manually create vault.example.duckdns.org with DuckDNS?

Do you have a paid DuckDNS account?

I set up example.duckdns.org with the free edition. This automatically gives me all *.example.duckdns.org domains.