# Securing Traefik Ingress

This guide's sources can be found on github (opens new window).

At the end, you will have an install of a hello-world app proxied by Traefik (opens new window) with authorization policy enforced by Pomerium.

This guide specifically demonstrates using Traefik and Pomerium in the context of a Kubernetes Ingress (opens new window) controller, but the patterns can be utilized anywhere Traefik is deployed (opens new window).

# Background

Traefik can be configured (opens new window) to authorize requests by calling a remote authorization service. Pomerium is compatible with this protocol and can thus be used to protect services behind Traefik. In this configuration, Pomerium does not directly proxy traffic, but only performs authorization decisions on behalf of Traefik. This is useful for integrating into existing load balancer infrastructure.

For more information on using Pomerium as an external authorization endpoint, see forward auth (opens new window) in the Pomerium docs.

# How It Works

  • Install Traefik as an Ingress Controller (opens new window) on your Kubernetes cluster
  • Install a standard Pomerium configuration with forwardauth enabled
  • Create middleware (opens new window) to use Pomerium for authorization
  • Install an application with an Ingress resource configured to use the Pomerium authorization middleware
  • Pomerium authenticates users via Identity Provider (opens new window)
  • Traefik queries Pomerium on each request to verify the traffic is authorized
  • Pomerium verifies the traffic against policy, responding to Traefik
  • Traefik proxies the traffic or responds with an error

# Pre-requisites

This guide is optimized to run on a local kubernetes install in Docker Desktop (opens new window), however the configuration should be easily portable to minikube (opens new window) or traditional clusters.

If running in minikube or other non-local clusters, you will need to use kubectl port-forward to forward traffic from 127.0.0.1:[80,443] to the Traefik service in Kubernetes, or replace *.localhost.pomerium.io references with your own domain.

For the purposes of the guide, all resources are installed inside the namespace pomerium.

# Certificates (optional)

This demo comes with its own certificates, but they will generate warnings in your browser. You may instead provide your own or use mkcert (opens new window) to generate locally trusted certificates.

After installing mkcert, run the following inside the example repo:

mkcert -install
   mkcert '*.localhost.pomerium.io'

This will install a trusted CA and generate a new wildcard certificate:

  • _wildcard.localhost.pomerium.io.pem
  • _wildcard.localhost.pomerium.io-key.pem

To provide your own certificates (opens new window) through another mechanism, please overwrite these files or update the Ingress configurations accordingly.

# Configure

# Pomerium

Update values/pomerium.yaml with your Identity Provider settings, domain names and policy

authenticate:
  idp:
    provider: REPLACEME
    url: REPLACEME
    clientID: REPLACEME
    clientSecret: REPLACEME

config:
  rootDomain: localhost.pomerium.io
  sharedSecret: R0+XRoGVpcoi4PfB8tMlvnrS5XUasO+D1frAEdYcYjs=
  cookieSecret: FLPCOQKigK5EQnyXlBhchl5fgzNKqi3ubtvOGt477Dg=
  generateTLS: true
  policy:
    - from: https://hello.localhost.pomerium.io
      to: http://hello-nginx
      allowed_domains:
        - gmail.com
ingress:
  annotations:
    traefik.ingress.kubernetes.io/router.tls: "true"
  secretName: wildcard-tls
forwardAuth:
  enabled: true
  internal: true

# Traefik

Helm chart values:

additionalArguments:
  - "--serverstransport.insecureskipverify=true"
  - "--entryPoints.websecure.forwardedHeaders.insecure"

TIP

Please note forwardedHeaders.insecure must be set on the entrypoint in front of Pomerium proxy if you are routing forward auth requests through Traefik. See docs (opens new window) for more information.

Middleware:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: auth
spec:
  forwardAuth:
    address: https://pomerium-proxy.pomerium
    tls:
      insecureSkipVerify: true
    trustForwardHeader: true

WARNING

Please note trustForwardHeader: true must be set for the middleware to work correctly. See docs (opens new window) for more information.

# Hello

Helm chart values:

ingress:
  enabled: true
  hosts:
    - name: hello.localhost.pomerium.io
      path: /

  annotations:
    traefik.ingress.kubernetes.io/router.middlewares: pomerium-auth@kubernetescrd
    traefik.ingress.kubernetes.io/router.tls: "true"
  tls:
    - hosts:
        - hello.localhost.pomerium.io
      secretName: wildcard-tls
service:
  type: ClusterIP

# Install

# Add helm repos

#!/bin/bash -x

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add pomerium https://helm.pomerium.io
helm repo add traefik https://containous.github.io/traefik-helm-chart

# Install charts and CRDs

#!/bin/bash -x

kubectl create namespace pomerium

# Create shared TLS secret
kubectl create secret tls wildcard-tls \
    --namespace pomerium \
    --cert=_wildcard.localhost.pomerium.io.pem \
    --key=_wildcard.localhost.pomerium.io-key.pem

# Install Traefik helm chart
helm upgrade --install --wait \
    --namespace pomerium \
    traefik traefik/traefik \
    --values values/traefik.yaml

# Install Pomerium helm chart
helm upgrade --install --wait \
    --namespace pomerium \
    pomerium pomerium/pomerium \
    --values values/pomerium.yaml

# Create middleware
kubectl --namespace pomerium apply -f crds/middleware.yaml

# Install hello app
helm upgrade --install --wait \
    --namespace pomerium \
    --version 6.2.1 \
    hello bitnami/nginx \
    --values values/hello.yaml

After 1-2 minutes, browse to hello.localhost.pomerium.io (opens new window).

You should be prompted to log in through your IdP and then granted access to the deployed hello instance.

# That's it!

Your hello application is protected by Pomerium.

Here's a run through of the steps in this demo: