This episode covers custom certificates: certificate file configuration via the file provider with hot reload, certificate stores and SNI-based routing, and mutual TLS for authenticating clients based on certificates with clientAuthType and CA files.

Not all certificates come from Let's Encrypt. There are times when you need to use certificates from an internal Certificate Authority, certificates bought from a vendor, or even authenticate clients with certificates — this is the territory of episode 17: custom certificates and mutual TLS (mTLS).
mTLS is the technology that makes communication between two systems trustworthy in both directions. Ever accessed an internal API that seemed "impossible" to break into? There is likely mTLS behind it. In this episode we prepare custom certificates with OpenSSL, install them through the file provider, and enable certificate-based client authentication in Traefik.
For development environments or an internal CA, create certificates with OpenSSL:
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout /certs/ca.key -out /certs/ca.crt \
-days 3650 -subj "/CN=Internal CA"
openssl req -newkey rsa:2048 -nodes \
-keyout /certs/service.key -out /certs/service.csr \
-subj "/CN=api.internal.local"
openssl x509 -req -in /certs/service.csr \
-CA /certs/ca.crt -CAkey /certs/ca.key -CAcreateserial \
-out /certs/service.crt -days 825 \
-extfile <(printf "subjectAltName=DNS:api.internal.local,DNS:*.internal.local")The steps: create a CA, create a certificate signing request (CSR), then sign the CSR with the CA. The -extfile flag adds SANs so the certificate is valid for the host names used. The resulting certificates — service.crt and service.key — are the pair to be installed in Traefik.
Custom certificates are registered through the file provider in dynamic configuration. The structure of the tls section in the file provider:
tls:
certificates:
- certFile: /certs/service.crt
keyFile: /certs/service.key
- certFile: /certs/legacy.crt
keyFile: /certs/legacy.key
stores:
default:
defaultCertificate:
certFile: /certs/service.crt
keyFile: /certs/service.keyThe file provider's advantage: changes take effect immediately without a restart. Replace the contents of service.crt, and Traefik loads the new certificate within seconds. The second certificate in the certificates list gives Traefik an additional choice that will be selected based on the request's SNI.
All certificates are gathered in the certificate store named default. When a client handshakes with the SNI api.internal.local, Traefik looks for a certificate whose SAN matches and serves that one. Without a match, the store sends defaultCertificate. For SNI-based routing at the TCP level, you can also point to a different store per router — a pattern used to separate internal and external domains.
In normal TLS, only the client verifies the server. In mTLS, it is bidirectional: the client must also present a valid certificate, and Traefik verifies it against a list of trusted CAs. The result: only machines holding certificates issued by your CA can connect.
Enable mTLS through a TLSOption with clientAuth:
http:
tlsOptions:
mtls-internal:
clientAuth:
secretNames:
- internal-ca
clientAuthType: RequireAndVerifyClientCertsecretNames: references the Secret containing the CA file in Kubernetes; in the file provider, caFiles is used instead:http:
tlsOptions:
mtls-file:
clientAuth:
caFiles:
- /certs/ca.crt
clientAuthType: RequireAndVerifyClientCertclientAuthType: RequireAndVerifyClientCert: the client must send a certificate and it must be verified against the CA.NoClientCert, RequestClientCert, RequireAnyClientCert — each lowers the strictness level.http:
routers:
api-internal:
rule: "Host(`api.internal.local`)"
entrypoints:
- websecure
service: api-svc
tls:
options: mtls-file
certResolver: letsencrypt
services:
api-svc:
loadBalancer:
servers:
- url: "http://10.0.0.70:8080"Now clients without a valid certificate from your CA are rejected at the handshake, even before an HTTP request is sent. Combining mTLS + Let's Encrypt as above shows Traefik's dual use: public encryption for humans, a certificate gateway for machines.
Warning
Make sure clientAuthType is really RequireAndVerifyClientCert for internal gateways. The value RequestClientCert only asks for a certificate without verifying it — easy to mistake for protection when it is not.
This pattern is widely used for:
Key takeaways:
clientAuthType: RequireAndVerifyClientCert is the truly secure mode.In episode 18 next we will cover TCP & UDP routing — TCP entrypoints, HostSNI-based routing, TLS termination versus passthrough for non-HTTP protocols, proxying databases, SSH, and SMTP, and UDP load balancing for DNS and game servers. Your gateway now goes beyond HTTP.