TLS and HTTPS
HTTPS is where a reverse proxy earns its keep most visibly: one place that holds certificates, terminates the encryption, and speaks plain HTTP to the backends behind it, which never have to know. This chapter does it the hand-made way — a local certificate authority, a certificate, a redirect — because doing it once by hand is what makes the automatic way (Let's Encrypt, at the end) readable. The hand-made way is also the right way for names that only exist on your own network.
Certificates in dynamic configuration
Certificates are dynamic configuration:
they can be added and replaced without
restarting Traefik. The lab's
examples/dynamic-tls.yml:
tls:
certificates:
- certFile: ./certs/lab.crt
keyFile: ./certs/lab.key
http:
routers:
fern-secure:
rule: "Host(`fern.test`)"
entryPoints:
- websecure
service: fern
tls: {}
Three pieces: the certificate and its
private key are named under
tls.certificates; the router sits on
the websecure entrypoint; and its
tls: {} line is the switch that says
"this router speaks HTTPS" — without it,
the router would answer the TLS
entrypoint with plain HTTP behaviour and
confuse everyone.
Certificate paths are resolved from Traefik's working directory when the file provider reads them. Keep certificates in one known folder and say so plainly in the config; a certificate that cannot be found is a certificate Traefik silently replaces with its own built-in default — chapter 15 has the symptom.
A certificate authority of one's own
A certificate is trusted because a
certificate authority (CA) signed it
and the visitor's machine trusts that CA.
For public sites the CA is a public one.
For fern.test, the authority is you:
# 1. The CA: one key, one certificate
openssl req -x509 -newkey rsa:2048 \
-keyout ca.key -out ca.crt -days 3650 \
-nodes -subj "/CN=Mere Mortals Lab CA"
# 2. The site's key and a signing request
openssl req -newkey rsa:2048 \
-keyout lab.key -out lab.csr -nodes \
-subj "/CN=fern.test"
# 3. The names the certificate covers
printf 'subjectAltName=DNS:fern.test,DNS:otter.test\n' > san.ext
# 4. The CA signs it
openssl x509 -req -in lab.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-out lab.crt -days 825 -extfile san.ext
The subjectAltName list in step 3 is
the part modern browsers and tools
actually check; the name on the
certificate's subject is decoration.
Transcript t06 verifies the finished
certificate carries both lab names.
Then the proof, three ways (t06):
curl --cacert ca.crt https://fern.test:8443/helloworks — trusting the lab CA makes the lab's certificates trustworthy.- The same request without
--cacertfails, curl exit 60, certificate not trusted. That failure is the system working: a private CA convinces only machines you give it to. To make a home setup feel real, installca.crtinto the trust store of each of your devices — and understand you have made yourself an authority whose key (ca.key) can now mint trust for any name at all. Guard it like a password, because it is one. - A self-signed site certificate (no CA) gives the same exit 60. The CA's value is not the signature; it is that one trust decision covers every certificate it signs.
Sending HTTP visitors to HTTPS
A redirectScheme middleware on the
plain-HTTP router:
to-https:
redirectScheme:
scheme: https
port: "8443"
Transcript t06: the answer to
http://fern.test:8000/hello is
302 Found with
Location: https://fern.test:8443/hello.
Two details matter: the port: line
exists because the lab's HTTPS is not on
the standard port, and real deployments
on 443 omit it; and every HTTP router
needs the redirect (or the entrypoint
needs a global redirection, which static
configuration offers) — a router you
forget stays quietly available in plain
HTTP, passwords and all.
Let's Encrypt: the automatic way
This section is documented, not
verified: issuing a real certificate
needs a public domain and a server the
internet can reach, and the lab sandbox
is neither. For public names, Traefik
can act as its own CA client — the ACME
protocol, in practice Let's Encrypt.
Static configuration names a
certificatesResolvers entry with your
email and a storage file for the
certificates; a router's tls block then
says certResolver: that-name instead of
{}, and Traefik obtains, serves and
renews the certificate by itself, proving
you control the name either by answering
an HTTP challenge on port 80 or a DNS
challenge through your DNS provider's
API. The storage file becomes a secret
to back up (chapter 11) and the email is
where expiry warnings go if renewal ever
fails. Everything else in this chapter —
entrypoints, tls:, redirects — is
identical; only the certificate's origin
changes.