🛡️ Reverse proxy¶
Important
Usually the ca service will be deployed behind a reverse proxy, which requires special attention.
To make the CA work behind a reverse proxy, follow these rules:
Remove all direct port mappings (i.e.
8443)Point your reverse proxy to port
8443instead (the only exposed port)Pass through TLS connections to the CA, don’t intercept them on the reverse proxy
Disable strict SNI checking
Put the CA into the same network as the proxy
Below there are some examples for reverse proxies.
Traefik¶
CA deployment¶
To deploy the CA service behind Traefik proxy, the following labels must be added to the container:
services:
ca:
# … existing config (see Deployment chapter)
# Passthrough connections from Traefik directly to CA.
labels:
- traefik.enable=true
- traefik.tcp.routers.ca.rule=HostSNI(`ca.example.net`)
- traefik.tcp.routers.ca.tls.passthrough=true
# Add CA to proxy network.
networks:
- proxy
# Make proxy network available for Compose service.
networks:
proxy:
external: true
Hint
If you’ve strict SNI checking enabled, create a new dynamic config such as this:
tls:
options:
sniStrictDisable:
sniStrict: false
Then use the option as another label:
labels:
# … existing labels
- traefik.tcp.routers.ca.tls.options=sniStrictDisable@file
ACME¶
To issue certificates via the CA’s ACME provisioner, add a certificate resolver to the static config:
certificatesResolvers:
ca:
acme:
caServer: https://{FQDN}/acme/acme/directory
storage: /acme/ca.json
tlsChallenge: {}
Then make Traefik trust the root certificate via environment variable:
environment:
LEGO_CA_CERTIFICATES: /path/to/root_ca.crt
Use the resolver on a router as usual:
labels:
- traefik.http.routers.{router}.tls.certresolver=ca
mTLS¶
To use the CA for mTLS in Traefik proxy, use the following TLS configuration:
tls:
options:
mTLS:
clientAuth:
caFiles:
- /path/to/ca.pem
clientAuthType: RequireAndVerifyClientCert
Hint
If you’ve default options, and you want to extend them to the mTLS options, you can use YAML anchors like this:
tls:
options:
default: &defaultOptions
# your default options here
mTLS:
<<: *defaultOptions
clientAuth:
caFiles:
- /path/to/ca.pem
clientAuthType: RequireAndVerifyClientCert
Caddy¶
CA deployment¶
Caddy doesn’t support TLS passthrough out of the box, so you’ll need a custom build that includes the caddy-l4 (Layer 4) plugin:
xcaddy build --with github.com/mholt/caddy-l4
Then pass through the CA’s TLS connections via listener wrapper in the global options of your Caddyfile:
{
servers {
listener_wrappers {
layer4 {
@ca tls sni ca.example.net
route @ca {
proxy ca:8443
}
}
tls
}
}
}
Note
Connections not matching the @ca route fall through to Caddy’s regular TLS handling, so your other sites keep working.
ACME¶
To issue certificates via the CA’s ACME provisioner, configure the ca & ca_root subdirectives in your Caddyfile:
example.com {
tls {
ca https://{FQDN}/acme/acme/directory
ca_root /path/to/root_ca.crt
}
reverse_proxy backend:8080
}
Hint
To use the CA for all sites, use the acme_ca & acme_ca_root global options instead.
mTLS¶
To use the CA for mTLS in Caddy, configure the client_auth directive in your Caddyfile:
example.com {
tls {
client_auth {
mode require_and_verify
trusted_ca_cert_file /path/to/ca.pem
}
}
reverse_proxy backend:8080
}
Hint
If multiple sites should require mTLS, define a snippet and import it:
(mtls) {
tls {
client_auth {
mode require_and_verify
trusted_ca_cert_file /path/to/ca.pem
}
}
}
example.com {
import mtls
reverse_proxy backend:8080
}