Self-Signed Certificate in Traefik v3 not trusted by client Browser

Hi everybody,
I've deploy traefik stack on Docker swarm refererence on Traefik Proxy with HTTPS - Docker Swarm Rocks ,and my Docker swarm just for intranet usage.
This's my website url(registerd on my intranet DNS Server): https://traefik.myexample.com
/opt/traefik/traefik.yml composite file as followings: (bold font means difference)

services:
  traefik:
    # Use the latest v3.0.x Traefik image available
    image: traefik:v3.0
    ports:
      # Listen on port 80, default for HTTP, necessary to redirect to HTTPS
      - 80:80
      # Listen on port 443, default for HTTPS
      - 443:443
    deploy:
      placement:
        constraints:
          # Make the traefik service run only on the node with this label
          # as the node with it has the volume for the certificates
          - node.labels.traefik-public.traefik-public-certificates == true
      labels:
        # Enable Traefik for this service, to make it available in the public network
        - traefik.enable=true
        # Use the traefik-public network (declared below)
        - traefik.docker.network=traefik-public
        # Use the custom label "traefik.constraint-label=traefik-public"
        # This public Traefik will only use services with this label
        # That way you can add other internal Traefik instances per stack if needed
        - traefik.constraint-label=traefik-public
        # https-redirect middleware to redirect HTTP to HTTPS
        # It can be re-used by other stacks in other Docker Compose files
        - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
        - traefik.http.middlewares.https-redirect.redirectscheme.permanent=true
        # traefik-http set up only to use the middleware to redirect to https
        # Uses the environment variable DOMAIN
        - traefik.http.routers.traefik-public-http.rule=Host(`traefik.myexample.com`)
        - traefik.http.routers.traefik-public-http.entrypoints=http
        - traefik.http.routers.traefik-public-http.middlewares=https-redirect
        # traefik-https the actual router using HTTPS
        # Uses the environment variable DOMAIN
        - traefik.http.routers.traefik-public-https.rule=Host(`traefik.myexample.com`)
        - traefik.http.routers.traefik-public-https.entrypoints=https
        - traefik.http.routers.traefik-public-https.tls=true
        # Use the special Traefik service api@internal with the web UI/Dashboard
        - traefik.http.routers.traefik-public-https.service=api@internal
        # Use the "le" (Let's Encrypt) resolver created below
        #- traefik.http.routers.traefik-public-https.tls.certresolver=le
        # Define the port inside of the Docker service to use
        - traefik.http.services.traefik-public.loadbalancer.server.port=8080
    volumes:
      # Add Docker as a mounted volume, so that Traefik can read the labels of other services
      - /var/run/docker.sock:/var/run/docker.sock:ro
      # Mount the volume to store the certificates
      - traefik-public-certificates:/certificates
      - /opt/traefik/traefik_data/dynamic_config.yml:/traefik/config/my_dynamic_conf/conf.yml:ro
      - /opt/certs/:/certs/
    command:
      # Enable Docker in Traefik, so that it reads labels from Docker services
      - --providers.docker
      # Add a constraint to only use services with the label "traefik.constraint-label=traefik-public"
      - --providers.docker.constraints=Label(`traefik.constraint-label`, `traefik-public`)
      # Do not expose all Docker services, only the ones explicitly exposed
      - --providers.docker.exposedbydefault=false
      # Enable Docker Swarm mode
      - --providers.swarm.endpoint=unix:///var/run/docker.sock
      # Create an entrypoint "http" listening on port 80
      - --entrypoints.http.address=:80
      # Create an entrypoint "https" listening on port 443
      - --entrypoints.https.address=:443
      - --providers.file.directory=/traefik/config/my_dynamic_conf
      # Create the certificate resolver "le" for Let's Encrypt, uses the environment variable EMAIL
      #- --certificatesresolvers.le.acme.email=${EMAIL?Variable not set}
      # Store the Let's Encrypt certificates in the mounted volume
      #- --certificatesresolvers.le.acme.storage=/certificates/acme.json
      # Use the TLS Challenge for Let's Encrypt
      #- --certificatesresolvers.le.acme.tlschallenge=true
      # Enable the access log, with HTTP requests
      - --accesslog
      # Enable the Traefik log, for configurations and errors
      - --log
      - --log.level=DEBUG
      # Enable the Dashboard and API
      - --api
    networks:
      # Use the public network created to be shared between Traefik and
      # any other service that needs to be publicly available with HTTPS
      - traefik-public
volumes:
  traefik-public-certificates:
networks:
  traefik-public:
    external: true

and I refererence Self-Signed Certificate in Traefik not trusted even when I add CA Cert to Browser
use following commnad to generate self-signed certificates:

mkcert -key-file certs/key.pem -cert-file certs/cert.pem myexample.com `*`.myexample.com

edit /opt/traefik/traefik-data/dynamic_config.yml as following:

tls:
  certificates:
    - certFile: /certs/cert.pem
      keyFile: /certs/key.pem

When I deploy traefik docker stack, it won't start up.

docker stack deploy -c /opt/traefik/traefik.yml -d traefik

I type following command, but it show nothing.

docker service logs -f traefik_traefik

How to make the self-signed certificate be trusted and start up correctly?

Here's why I post this request here
If I unmark /opt/traefik/traefik.yml composite file as following:

      # Use the "le" (Let's Encrypt) resolver created below
      - traefik.http.routers.traefik-public-https.tls.certresolver=le
      # Create the certificate resolver "le" for Let's Encrypt, uses the environment variable EMAIL
      - --certificatesresolvers.le.acme.email=${EMAIL?Variable not set}
      # Store the Let's Encrypt certificates in the mounted volume
      - --certificatesresolvers.le.acme.storage=/certificates/acme.json
      # Use the TLS Challenge for Let's Encrypt
      - --certificatesresolvers.le.acme.tlschallenge=true

and deploy traefik stack on docker swarm, then traefik log show error message as following:

2024-10-31T11:15:33+08:00 DBG github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:445 > Trying to challenge certificate for domain [traefik.myexample.com] found in HostSNI rule ACME CA=https://acme-v02.api.letsencrypt.org/directory acmeCA=https://acme-v02.api.letsencrypt.org/directory providerName=le.acme routerName=traefik-public-https@swarm rule=Host(`traefik.myexample.com`)
2024-10-31T11:15:33+08:00 DBG github.com/traefik/traefik/v3/pkg/tls/certificate.go:131 > Adding certificate for domain(s) acme challenge temp,traefik.myexample.com
2024-10-31T11:15:33+08:00 DBG github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:445 > Trying to challenge certificate for domain [passmanager.myexample.com] found in HostSNI rule ACME CA=https://acme-v02.api.letsencrypt.org/directory acmeCA=https://acme-v02.api.letsencrypt.org/directory providerName=le.acme routerName=vaultwarden-https@swarm rule=Host(`passmanager.myexample.com`)
2024-10-31T11:15:33+08:00 DBG github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:915 > Looking for provided certificate(s) to validate ["traefik.myexample.com"]... ACME CA=https://acme-v02.api.letsencrypt.org/directory acmeCA=https://acme-v02.api.letsencrypt.org/directory providerName=le.acme routerName=traefik-public-https@swarm rule=Host(`traefik.myexample.com`)
2024-10-31T11:15:33+08:00 DBG github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:915 > Looking for provided certificate(s) to validate ["passmanager.myexample.com"]... ACME CA=https://acme-v02.api.letsencrypt.org/directory acmeCA=https://acme-v02.api.letsencrypt.org/directory providerName=le.acme routerName=vaultwarden-https@swarm rule=Host(`passmanager.myexample.com`)
2024-10-31T11:15:33+08:00 DBG github.com/traefik/traefik/v3/pkg/tls/certificate.go:131 > Adding certificate for domain(s) acme challenge temp,passmanager.myexample.com
2024-10-31T11:15:33+08:00 DBG github.com/traefik/traefik/v3/pkg/tls/tlsmanager.go:321 > No default certificate, fallback to the internal generated certificate tlsStoreName=default
2024-10-31T11:15:33+08:00 DBG github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:959 > No ACME certificate generation required for domains ACME CA=https://acme-v02.api.letsencrypt.org/directory acmeCA=https://acme-v02.api.letsencrypt.org/directory domains=["traefik.myexample.com"] providerName=le.acme routerName=traefik-public-https@swarm rule=Host(`traefik.myexample.com`)
2024-10-31T11:15:33+08:00 DBG github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:959 > No ACME certificate generation required for domains ACME CA=https://acme-v02.api.letsencrypt.org/directory acmeCA=https://acme-v02.api.letsencrypt.org/directory domains=["passmanager.myexample.com"] providerName=le.acme routerName=vaultwarden-https@swarm rule=Host(`passmanager.myexample.com`)

It will show error message when I use chrome/edge to browse website traefik.myexample.com in intranet.


When I click 'view certificate' link, it will show following message

It use TRAEFIK DEFAULT CERT, and show CA certification is untrusted.
Click detail tab page,it will show following message

Click 'certificate path' tab page,it will show following message

certificate path: TRAEFIK DEFAULT CERT
certificate state: this ca certificate is untrusted....

Back to first error message, click "I understand risk and want to continue" link,it will show following message


This message was cause by kaspersky end-point server on our organization.
Then when I click continue button, it will enter https://traefik.myexample.com finally.

Because the whole process bother us and spend a few time, so I wanna ask for help here to skip these process.

I'm... not sure what the final question is. It seems the problem isn't with Traefik but with the browser?

Self-signed certificates aren't trusted by default. You'd need to add a self-signed certificate to the list of trusted certificates on the machine which is accessing your URL (i.e. where the browser is being used), and this has nothing to do with Traefik itself.

PS. Could you please format your question with ```, to mark the beginning and end of the code-block, for readability?

hi mbender,
thanks for your answer.
I just want the same as mention in topic Self-Signed Certificate in Traefik not trusted even when I add CA Cert to Browser

Once more this seems like more of a problem with certificates and not specific to Traefik itself.

In general you need

  • a certificate for local.domain or *.local.domain (note that the certificate consists of at leas 2 "named" elements)
  • the certificate added to the list of trusted certificates
  • a website you can access using the local.domain URL or subdomain.local.domain (depending on which certificate was created previously)

You seem to be struggling with the second part of the above (but I'm still having a bit of a hard time reading and fully understanding your original question due to the rather poor formatting; please try and fix it). This step is not related to Traefik at all and is dependant on the OS / browser you might be using.

Please format your config with 3 backticks before/after to make it readable and preserve spacing, which is important in yaml.

Thanks for mbender, there's something I still not sure...

  • a certificate for local.domain or *.local.domain (note that the certificate consists of at leas 2 "named" elements)

This mean I can make a root cert for my intranet, like following command:

mkcert -key-file /certs/key.pem -cert-file /certs/cert.pem local.domain *.local.domain
  • the certificate added to the list of trusted certificates

This mean add key.pem cert.pem to local host trusted certificatese(my host Ubuntu 22.04 LTS)?

  • a website you can access using the local.domain URL or subdomain.local.domain (depending on which certificate was created previously)

This's part most confusing me. I wanna generate this certificate for website as following:
traefik.local.domain
run following command:

mkcert -key-file /certs/traefik-key.pem -cert-file /certs/traefik-cert.pem traefik.local.domain

and then how to use this traefik-key.pem traefik-cert.pem used by traefik stack on docker swarm?

Thanks to bluepuma77, I've use this quote notation on original post.

Based on edited initial post and the screenshots it seems the page you're accessing is using the default Traefik certificate, rather than the one you had generated.

Do not use resolvers and LE - this won't work, since LE will not work with a custom, local domain.

You have a good idea with the dynamic config file (it follows the documentation at Traefik TLS Documentation - Traefik), but... is that the WHOLE file?

Also, why are you using docker stack if you want the service to run on your current node only? I'd rewrite the initial compose YAML to a regular one, with no deploy section, and just use docker compose up instead for ease-of-use. And it would make it much easier to find potential problems with the setup.

Thanks to mbender's suggestion.
I found step-ca maybe another solution, and will test if it work.