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
tlsChallengemethod uses TLS-ALPN-01 on port 443. Alternatively, usehttpChallenge(port 80) ordnsChallengefor 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
cipherSuitessetting 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/tlsis 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/tlsdoes 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