SEANK.H.LIAO

traefik backend tls

running TLS to the backend with traefik

TLS to the backend

Situation: you have traefik as your reverse proxy / API gateway, traefik terminates TLS for client connections, but you also want TLS for the traefik-backend part.

tldr: possible securely with static backends, insecurely with dynamic (eg k8s)

traefik

When setting the scheme to https for backend services, traefik uses TLS for connecting directly to the IP address without ServerName in the ClientHello. This causes issues since your certificate now needs to be signed for the IP address (ephemeral on kubernetes) instead of a stable domain name (any of $service, $service.$namespace, $service.$namespace.svc, $service.$namespace.svc.cluster.local would have been fine).

This appears unlikely to be fully fixed soon, partial fix in v2.4.

setup

Using internal Certificate Authority, generate CA cert+key (ex using mkcert). Inject CA cert into traefik container and run traefik with static config:

1serversTransport:
2  rootCAs:
3    - /etc/internal-ca/ca.crt

Generate backend cert+key signed by CA key for the IP address and run server with it. Ex with Cert Manager:

 1apiVersion: cert-manager.io/v1
 2kind: Certificate
 3metadata:
 4  name: http-server-internal
 5spec:
 6  secretName: http-server-internal
 7  duration: 2160h
 8  renewBefore: 360h
 9  ipAddresses:
10    # testing only
11    # guessing whick IP the pod will have
12    - "10.205.0.44"
13    - "10.205.0.45"
14    - "10.205.0.46"
15    - "10.205.0.47"
16    - "10.205.0.48"
17    - "10.205.0.49"
18    - "10.205.0.50"
19  issuerRef:
20    name: internal-ca
21    kind: ClusterIssuer

Setup and IngressRoute to point traefik to the service

 1apiVersion: traefik.containo.us/v1alpha1
 2kind: IngressRoute
 3metadata:
 4  name: http-server
 5spec:
 6  entryPoints:
 7    - https
 8  routes:
 9    - kind: Rule
10      match: Host(`http-server.example.com`)
11      services:
12        - kind: Service
13          name: http-server
14          port: 443
15          scheme: https
16  tls: {}