Skip to content

Last updated: 2026-05-15

Traefik TLS/SSL Configuration Guide

This guide provides recommended TLS/SSL settings for Traefik reverse proxy to encrypt client connections. Traefik supports automatic certificate management via ACME (Let's Encrypt) and manual certificate configuration with fine-grained TLS options.

Prerequisites

  • Traefik 3.0 or later
  • SSL certificates (or an ACME provider such as Let's Encrypt)
  • Configuration via static file (YAML or TOML) and dynamic file or labels

Certificate Setup

Manual Certificates

Place your certificates in a dedicated directory:

mkdir -p /etc/traefik/ssl
chmod 750 /etc/traefik/ssl

cp server.crt /etc/traefik/ssl/cert.pem
cp server.key /etc/traefik/ssl/key.pem

chmod 640 /etc/traefik/ssl/*.pem

ACME (Let's Encrypt)

Configure automatic certificate provisioning in the static configuration:

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /etc/traefik/acme.json
      tlsChallenge: {}

Note: The tlsChallenge method uses TLS-ALPN-01 on port 443. Alternatively, use httpChallenge (port 80) or dnsChallenge for wildcard certificates.

Entrypoint TLS Configuration

Define HTTPS entrypoints in the static configuration file (traefik.yml):

entryPoints:
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt

To redirect all HTTP traffic to HTTPS:

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt

TLS Options

Define TLS options in the dynamic configuration to control protocol versions and cipher suites.

Protocol Versions

tls:
  options:
    default:
      minVersion: VersionTLS12
      maxVersion: VersionTLS13

Cipher Suites

Configure strong cipher suites for TLS 1.2. TLS 1.3 cipher suites are managed automatically by Go's crypto/tls library and cannot be overridden:

tls:
  options:
    default:
      minVersion: VersionTLS12
      maxVersion: VersionTLS13
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
      curvePreferences:
        - X25519
        - CurveP256
        - CurveP384

Note: The cipherSuites setting only applies to TLS 1.2. Go's TLS 1.3 implementation uses a fixed set of secure cipher suites that cannot be configured.

Client Certificate Authentication

To require client certificates (mutual TLS):

tls:
  options:
    mtls:
      minVersion: VersionTLS12
      clientAuth:
        caFiles:
          - /etc/traefik/ssl/ca.pem
        clientAuthType: RequireAndVerifyClientCert

Available clientAuthType values:

  • NoClientCert -- Do not request a client certificate
  • RequestClientCert -- Request but do not require a client certificate
  • RequireAndVerifyClientCert -- Require and verify a client certificate against the CA

See RFC 8446 ยง4.3.2 for the TLS Certificate Request specification, and Wikipedia: Mutual authentication for a general overview.

Manual Certificate Store

When not using ACME, provide certificates in the dynamic configuration:

tls:
  certificates:
    - certFile: /etc/traefik/ssl/cert.pem
      keyFile: /etc/traefik/ssl/key.pem

Complete Configuration

Static Configuration (traefik.yml)

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /etc/traefik/acme.json
      tlsChallenge: {}

providers:
  file:
    filename: /etc/traefik/dynamic.yml

Dynamic Configuration (dynamic.yml)

tls:
  options:
    default:
      minVersion: VersionTLS12
      maxVersion: VersionTLS13
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
      curvePreferences:
        - X25519
        - CurveP256
        - CurveP384
      sniStrict: true

Per-Router TLS Options

Assign specific TLS options to individual routers using labels (Docker) or dynamic configuration:

Docker Labels

labels:
  - "traefik.http.routers.myapp.tls=true"
  - "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
  - "traefik.http.routers.myapp.tls.options=default@file"

Dynamic File

http:
  routers:
    myapp:
      rule: "Host(`app.example.com`)"
      tls:
        options: default@file
        certResolver: letsencrypt
      service: myapp

Security Notes

Traefik uses Go's crypto/tls package, which has a different vulnerability history than OpenSSL:

  • POODLE (CVE-2014-3566, 2014): SSL 3.0 has never been supported in Go's TLS implementation.
  • BEAST (CVE-2011-3389, 2011): Mitigated by recommending TLS 1.2 as the minimum; AEAD-only ciphers eliminate the CBC padding oracle.
  • CRIME (CVE-2012-4929, 2012): TLS compression is not supported in Go's crypto/tls.
  • Lucky13 (2013): AEAD-only cipher list eliminates CBC padding timing side-channels entirely.
  • FREAK (CVE-2015-0204, 2015): EXPORT-grade ciphers have never been supported in Go's crypto/tls.
  • LOGJAM (CVE-2015-4000, 2015): DHE key exchange is not offered by default in Go; only ECDHE is used.
  • Sweet32 (CVE-2016-2183, 2016): 3DES was removed from Go's default cipher list in Go 1.14 (February 2020) and is excluded from the recommended configuration.
  • ROBOT (CVE-2017-13099, 2017): Static RSA key exchange is not offered in Go's crypto/tls; only ECDHE is used.
  • Downgrade attacks: TLS_FALLBACK_SCSV is supported in Go's TLS implementation.

The following are not addressable through TLS configuration alone:

  • Heartbleed (CVE-2014-0160, 2014): Not applicable. Go's crypto/tls is an independent TLS implementation and was never affected by Heartbleed.
  • BREACH (CVE-2013-3587, 2013): Exploits HTTP-level response compression (gzip/deflate on responses). Mitigated at the application layer by disabling HTTP compression or using BREACH countermeasures; TLS configuration cannot prevent it.
  • DROWN (CVE-2016-0800, 2016): Not applicable. Go's crypto/tls does not support SSLv2.

Verification

Check the Traefik dashboard (if enabled) for active routers and their TLS status.

Test the TLS connection:

openssl s_client -connect app.example.com:443 -servername app.example.com

Verify the certificate and protocol:

curl -vI https://app.example.com 2>&1 | grep -E 'SSL|TLS|subject|issuer'

Check Traefik logs for certificate events:

grep -i tls /var/log/traefik/traefik.log

Related Guides

View all Web Servers & Proxies guides →

Configured TLS? Now Monitor It.

Generator Labs alerts you before certificates expire, get revoked, or fail chain validation — across HTTPS, SMTPS, IMAPS, LDAPS, and more.

Certificate Monitoring →