Securing Traefik Ingress
Starting v0.21.0, Pomerium will no longer support Forward Auth. Supporting Forward Auth requires Pomerium to route requests from third-party proxies to make access control decisions. This goes against zero-trust principles as specified in the BeyondCorp model, which states that all traffic should flow through a single proxy.
Since this guide was written, Pomerium has developed into a first-class proxy service, and provides an integrated Ingress Controller for Kubernetes.
For previous versions of Pomerium up to v0.20.0, this guide will remain available for those already using Nginx with Pomerium, but we strongly encourage new users to configure Pomerium as the single method of authentication and proxying.
At the end of this guide, you will have an install of a hello-world app proxied by Traefik with authorization policy enforced by Pomerium.
This guide specifically demonstrates using Traefik and Pomerium in the context of a Kubernetes Ingress controller, but the patterns can be utilized anywhere Traefik is deployed.
Background
Traefik can be configured 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 in the Pomerium docs.
How It Works
- Install Traefik as an Ingress Controller on your Kubernetes cluster
- Install a standard Pomerium configuration with
forwardauth
enabled - Create middleware to use Pomerium for authorization
- Install an application with an
Ingress
resource configured to use the Pomerium authorizationmiddleware
- Pomerium authenticates users via Identity Provider
- 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
- Access to a Kubernetes cluster
- Helm (already initialized if using helm v2)
- A copy of the example repo checked out
- Valid credentials for your OIDC provider
- (Optional)
mkcert
to generate locally trusted certificates
This guide is optimized to run on a local kubernetes install in Docker Desktop, however the configuration should be easily portable to minikube 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 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 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
routes:
- from: https://hello.localhost.pomerium.io
to: http://hello-nginx
policy:
- allow:
or:
- domain:
is: 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"
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 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
Please note trustForwardHeader: true
must be set for the middleware to work correctly. See docs 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
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
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.
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: