Skip to main content
  1. Posts/

Use LetsEncrypt wildcard certificates with Traefik

·304 words·2 mins

For one of my use cases in my homelab, I wanted to avoid requesting a Let’s Encrypt certificate for each subdomain through Traefik every time. For this reason, I considered using a wildcard certificate.

In my homelab I have Traefik installed in a LXC container and run it as a systemd service. Please have a look at the Traefik documentation to use the Binary Distrubtion installation method.

traefik.service

I prefer to use the DNS challenge in Traefik to request certificates. For this reason, I adopted the provided systemd example to pass the Cloudflare DNS API token as an environment variable by combining EnvironmentFile and PassEnvironment:

[Unit]
Description=Traefik
Documentation=https://doc.traefik.io/traefik/
After=network-online.target

[Service]
User=traefik
EnvironmentFile=/var/lib/traefik/.env
PassEnvironment=CLOUDFLARE_DNS_API_TOKEN
AmbientCapabilities=CAP_NET_BIND_SERVICE

# configure service behavior
Type=notify
ExecStart=/usr/bin/traefik --configFile=/etc/traefik/traefik.yml
Restart=always
WatchdogSec=1s

[Install]
WantedBy=multi-user.target

traefik.yml

To do the DNS challenge with Cloudflare, I defined the Let’s Encrypt certificate resolver as follows:

---
certificatesResolvers:
  letsEncrypt:
    acme:
      email: YOUR_EMAIL
      storage: /var/lib/traefik/acme.json
      dnsChallenge:
        provider: cloudflare
        delayBeforeCheck: "30"
        resolvers:
          - "coraline.ns.cloudflare.com:53"
          - "kyrie.ns.cloudflare.com:53"

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

api:
  dashboard: true

metrics:
  prometheus: {}

providers:
  file:
    filename: /var/lib/traefik/dynamic.yml

dynamic.yaml

In this configuration file I have defined all routers and services that Traefik should use. To get the wildcard certificate for home.example.tld I had to request it the first time with a router by specifying the domains section.

During startup, Traefik requests a wildcard certificate for our main domain and uses it for each subdomain from now on.

---
http:
  routers:
    traefik:
      rule: Host(`traefik.home.example.tld`)
      service: api@internal
      tls:
        certResolver: letsEncrypt
        domains:
          - main: `home.example.tld`
            sans:
              - "*.home.example.tld"

    grafana:
      rule: Host(`grafana.home.example.tld`)
      service: grafana
      tls:
        certResolver: letsEncrypt
        domains:
          - main: `home.example.tld`
            sans:
              - "*.home.example.tld"
    prometheus:
      rule: Host(`prometheus.home.example.tld`)
      service: prometheus
      tls:
        certResolver: letsEncrypt
        domains:
          - main: `home.example.tld`
            sans:
              - "*.home.example.tld"

  services:
    grafana:
      loadBalancer:
        servers:
          - url: "http://monitoring:3000/"

    prometheus:
      loadBalancer:
        servers:
          - url: "http://monitoring:9090/"