Traefik ingress: redirect HTTP to HTTPS
Let’s say we need to set up HTTP to HTTPS redirection in Traefik ingress.
This article assumes that you already have Traefik ingress installed and HTTPS working.
A typical virtual host for service frontend
with domain sub.domain.example
looks something like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-traefik
namespace: frontend
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
kubernetes.io/ingress.class: traefik
labels:
app: frontend
spec:
tls:
- hosts:
- sub.domain.example
secretName: tls
rules:
- host: sub.domain.example
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 80
Now, you’d like to have an automatic HTTP => HTTPS redirect for this host. Unfortunately, Trafik ingress does not provide an easy to do that with annotations. Instead, it offers middlewares, in particular RedirectScheme.
However, RedirectScheme is a) indiscriminate and b) in some cases relies on X-Forwarded
headers, which isn’t a solid choice.
Instead, we can use RedirectRegex middleware. Gating with virtual host name will allow to apply it selectively.
First, create the middleware in Traefik’s namespace (usually traefik
):
# http => https redirect middleware
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: redirect-to-https
namespace: traefik
spec:
redirectRegex:
regex: "^http://(.*)"
replacement: "https://$1"
permanent: true
Second, add another ingress configuration to the application namespace, listening on port 80. It’s pretty much a copy of the HTTPS one, just different entrypoint and no SSL configuration:
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-traefik-http
namespace: frontend
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: traefik-redirect-to-https@kubernetescrd
kubernetes.io/ingress.class: traefik
spec:
rules:
- host:
http: sub.domain.example
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 80
That’s it! Should work now.
Comments