Skip to main content

TLS & HTTPS Redirect

Force all HTTP traffic to redirect to HTTPS and configure TLS version enforcement using Traefik's redirectScheme Middleware and TLSOption CRDs.

Prerequisites​

base/base-values.yaml

image:
registry: docker.io
repository: traefik/whoami
tag: latest
port: 80

Configuration​

envs/prod/values.yaml

deployment:
enabled: true
replicas: 1

service:
enabled: true

customResources:
- |
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: https-redirect
spec:
redirectScheme:
scheme: https
permanent: true
- |
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: tls-strict
spec:
minVersion: VersionTLS12
- |
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app-http
annotations:
kubernetes.io/ingress.class: public-traefik
external-dns.alpha.kubernetes.io/target: public-v2.{{ .Values.captain_domain }}
spec:
entryPoints:
- web
routes:
- match: Host(`{{ include "app.name" . }}.apps.{{ .Values.captain_domain }}`)
kind: Rule
middlewares:
- name: https-redirect
services:
- name: '{{ include "app.name" . }}'
namespace: '{{ include "app.namespace" . }}'
port: 80
- |
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app-https
annotations:
kubernetes.io/ingress.class: public-traefik
external-dns.alpha.kubernetes.io/target: public-v2.{{ .Values.captain_domain }}
spec:
entryPoints:
- websecure
routes:
- match: Host(`{{ include "app.name" . }}.apps.{{ .Values.captain_domain }}`)
kind: Rule
services:
- name: '{{ include "app.name" . }}'
namespace: '{{ include "app.namespace" . }}'
port: 80
tls:
options:
name: tls-strict

How It Works​

Two IngressRoutes handle the two entrypoints:

IngressRouteEntryPointBehavior
my-app-httpweb (port 80)Applies https-redirect middleware → 301 redirect to HTTPS
my-app-httpswebsecure (port 443)Serves the app with TLS options enforced

The TLSOption resource enforces:

  • minVersion: VersionTLS12 — Rejects connections using TLS 1.0 or 1.1

Verify​

# HTTP → should redirect to HTTPS (301)
curl -v http://my-app-prod.apps.nonprod.antoniostacos.onglueops.com 2>&1 | grep -i location
# Location: https://my-app-prod.apps.nonprod.antoniostacos.onglueops.com/

# HTTPS → should serve the app
curl https://my-app-prod.apps.nonprod.antoniostacos.onglueops.com

# Test TLS version enforcement (TLS 1.1 should fail)
curl --tls-max 1.1 https://my-app-prod.apps.nonprod.antoniostacos.onglueops.com
# Should fail with an SSL error
note

The -prod suffix matches your environment folder name (envs/prod/). If you deploy to a different environment like envs/uat/, the suffix changes accordingly (e.g., my-app-uat).

Available TLS Versions​

ValueTLS Version
VersionTLS10TLS 1.0
VersionTLS11TLS 1.1
VersionTLS12TLS 1.2
VersionTLS13TLS 1.3
info

For most applications, VersionTLS12 is the recommended minimum. Set VersionTLS13 if you only need to support modern clients.

Key Points​

  • The permanent: true flag sends a 301 Moved Permanently redirect. Use permanent: false for a 302 Found (temporary) redirect
  • Both IngressRoutes need the external-dns annotation since DNS needs to resolve for both HTTP and HTTPS endpoints
  • The tls.options.name in the HTTPS IngressRoute references the TLSOption resource by name