From 9abf5645b76e9a1fa18feb2e598ed0ab99082665 Mon Sep 17 00:00:00 2001 From: Thom Seddon Date: Fri, 24 Apr 2020 14:22:29 +0100 Subject: [PATCH] Add kubernetes examples + better document methods of applying authentication Closes #33 --- README.md | 113 +++++++++++- examples/docker-compose-dev.yml | 48 ----- examples/traefik-v1.7/kubernetes/README.md | 10 ++ .../advanced-separate-pod/README.md | 16 ++ .../advanced-separate-pod/kustomization.yaml | 3 + .../traefik-forward-auth/deployment.yaml | 65 +++++++ .../traefik-forward-auth/ingress.yaml | 17 ++ .../traefik-forward-auth/kustomization.yaml | 22 +++ .../traefik-forward-auth/service.yaml | 14 ++ .../traefik-forward-auth.env | 3 + .../traefik-forward-auth.ini | 8 + .../whoami/deployment.yaml | 19 ++ .../advanced-separate-pod/whoami/ingress.yaml | 16 ++ .../whoami/kustomization.yaml | 7 + .../advanced-separate-pod/whoami/service.yaml | 14 ++ .../kubernetes/advanced-single-pod/README.md | 18 ++ .../traefik/configs/traefik-forward-auth.ini | 8 + .../traefik/configs/traefik.toml | 169 ++++++++++++++++++ .../traefik/deployment.yaml | 92 ++++++++++ .../advanced-single-pod/traefik/ingress.yaml | 36 ++++ .../traefik/kustomization.yaml | 28 +++ .../advanced-single-pod/traefik/pvc.yaml | 17 ++ .../advanced-single-pod/traefik/rbac.yaml | 52 ++++++ .../traefik/secrets/traefik-forward-auth.env | 3 + .../advanced-single-pod/traefik/service.yaml | 36 ++++ .../whoami/deployment.yaml | 19 ++ .../advanced-single-pod/whoami/ingress.yaml | 16 ++ .../whoami/kustomization.yaml | 7 + .../advanced-single-pod/whoami/service.yaml | 14 ++ .../kubernetes/simple-separate-pod/README.md | 43 +++++ .../simple-separate-pod/k8s-app.yml | 62 +++++++ .../k8s-traefik-forward-auth.yml | 87 +++++++++ .../swarm}/docker-compose-auth-host.yml | 0 .../swarm}/docker-compose-oidc.yml | 0 .../swarm}/docker-compose.yml | 0 .../{ => traefik-v1.7/swarm}/traefik.toml | 1 + 36 files changed, 1029 insertions(+), 54 deletions(-) delete mode 100644 examples/docker-compose-dev.yml create mode 100644 examples/traefik-v1.7/kubernetes/README.md create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/README.md create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/kustomization.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/deployment.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/ingress.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/kustomization.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/service.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/traefik-forward-auth.env create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/traefik-forward-auth.ini create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/deployment.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/ingress.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/kustomization.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/service.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/README.md create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/configs/traefik-forward-auth.ini create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/configs/traefik.toml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/deployment.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/ingress.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/kustomization.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/pvc.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/rbac.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/secrets/traefik-forward-auth.env create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/service.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/deployment.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/ingress.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/kustomization.yaml create mode 100644 examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/service.yaml create mode 100644 examples/traefik-v1.7/kubernetes/simple-separate-pod/README.md create mode 100644 examples/traefik-v1.7/kubernetes/simple-separate-pod/k8s-app.yml create mode 100644 examples/traefik-v1.7/kubernetes/simple-separate-pod/k8s-traefik-forward-auth.yml rename examples/{ => traefik-v1.7/swarm}/docker-compose-auth-host.yml (100%) rename examples/{ => traefik-v1.7/swarm}/docker-compose-oidc.yml (100%) rename examples/{ => traefik-v1.7/swarm}/docker-compose.yml (100%) rename examples/{ => traefik-v1.7/swarm}/traefik.toml (99%) diff --git a/README.md b/README.md index 8b63490..7a41e2d 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,11 @@ A minimal forward authentication service that provides OAuth/SSO login and authe - [Concepts](#concepts) - [Forwarded Headers](#forwarded-headers) - [User Restriction](#user-restriction) + - [Applying Authentication](#applying-authentication) + - [Universal Authentication](#universal-authentication) + - [Individual Ingress Authentication in Kubernetes](#individual-ingress-authentication-in-kubernetes) + - [Individual Container Authentication in Swarm](#individual-container-authentication-in-swarm) + - [Rules Based Authentication](#rules-based-authentication) - [Operation Modes](#operation-modes) - [Overlay Mode](#overlay-mode) - [Auth Host Mode](#auth-host-mode) @@ -92,14 +97,13 @@ traefik.toml: [docker] endpoint = "unix:///var/run/docker.sock" -network = "traefik" ``` #### Advanced: -Please see the examples directory for a more complete [docker-compose.yml](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/docker-compose.yml) and full [traefik.toml](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/traefik.toml). +Please see the examples directory for a more complete [docker-compose.yml](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/traefik-v1.7/swarm/docker-compose.yml) or [kubernetes/simple-separate-pod](https://github.com/thomseddon/traefik-forward-auth/blob/masterexamples/traefik-v1.7/kubernetes/simple-separate-pod/) and full [traefik.toml](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/traefik-v1.7/swarm/traefik.toml). -Also in the examples directory is [docker-compose-auth-host.yml](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/docker-compose-auth-host.yml) which shows how to configure a central auth host, along with some other options. +Also in the examples directory is [docker-compose-auth-host.yml](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/traefik-v1.7/swarm/docker-compose-auth-host.yml) and [kubernetes/advanced-separate-pod](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/traefik-v1.7/kubernetes/advanced-separate-pod/) which shows how to configure a central auth host, along with some other options. #### Provider Setup @@ -320,7 +324,104 @@ Note, if you pass `whitelist` then only this is checked and `domain` is effectiv ### Forwarded Headers -The authenticated user is set in the `X-Forwarded-User` header, to pass this on add this to the `authResponseHeaders` config option in traefik, as shown [here](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/docker-compose-dev.yml). +The authenticated user is set in the `X-Forwarded-User` header, to pass this on add this to the `authResponseHeaders` config option in traefik, as shown below in the [Applying Authentication](#applying-authentication) section. + +### Applying Authentication + +Authentication can be applied in a variety of ways, either universally across all requests, or to individual containers/ingresses. + +#### Universal Authentication + +This can be achieved by enabling forward authentication for an entire entrypoint, for example, with http only: + +```toml +[entryPoints] + [entryPoints.http] + address = ":80" + + [entryPoints.http.auth.forward] + address = "http://traefik-forward-auth:4181" + authResponseHeaders = ["X-Forwarded-User"] +``` + +Or https: + +``` +[entryPoints] + [entryPoints.http] + address = ":80" + + [entryPoints.http.redirect] + entryPoint = "https" + + [entryPoints.https] + address = ":443" + + [entryPoints.https.tls] + + [entryPoints.https.auth.forward] + address = "http://traefik-forward-auth:4181" + authResponseHeaders = ["X-Forwarded-User"] +``` + +#### Individual Ingress Authentication in Kubernetes + +If you choose not to enable forward authentication for a specific entrypoint, you can apply annotations to selected ingresses: + +``` +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: whoami + labels: + app: whoami + annotations: + kubernetes.io/ingress.class: traefik + ingress.kubernetes.io/auth-type: forward + ingress.kubernetes.io/auth-url: http://traefik-forward-auth:4181 + ingress.kubernetes.io/auth-response-headers: X-Forwarded-User +spec: + rules: + - host: whoami.example.com + http: + paths: + - backend: + serviceName: whoami + servicePort: http +``` + +See the examples directory for more examples. + +#### Individual Container Authentication in Swarm + +You can apply labels to selected containers: + +``` +whoami: + image: containous/whoami + labels: + - traefik.frontend.rule=Host:whoami.example.com + - traefik.port=80 + - traefik.frontend.auth.forward.address=http://traefik-forward-auth:4181 + - traefik.frontend.auth.forward.authResponseHeaders=X-Forwarded-User + - traefik.frontend.auth.forward.trustForwardHeader=true +``` + +See the examples directory for more examples. + +#### Rules Based Authentication + +You can also leverage the `rules` config to selectively apply authentication via traefik-forward-auth. For example if you enabled universal authentication by enabling forward authentication for an entire entrypoint, you can still exclude some patterns from requiring authentication: + +``` +# Allow requests to 'dash.example.com' +rule.1.action = allow +rule.1.rule = Host(`dash.example.com`) + +# Allow requests to `app.example.com/public` +rule.two.action = allow +rule.two.rule = Host(`app.example.com`) && Path(`/public`) +``` ### Operation Modes @@ -341,7 +442,7 @@ As the hostname in the `redirect_uri` is dynamically generated based on the orig #### Auth Host Mode -This is an optional mode of operation that is useful when dealing with a large number of subdomains, it is activated by using the `auth-host` config option (see [this example docker-compose.yml](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/docker-compose-auth-host.yml)). +This is an optional mode of operation that is useful when dealing with a large number of subdomains, it is activated by using the `auth-host` config option (see [this example docker-compose.yml](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/traefik-v1.7/swarm/docker-compose-auth-host.yml)). For example, if you have a few applications: `app1.test.com`, `app2.test.com`, `appN.test.com`, adding every domain to Google's console can become laborious. To utilise an auth host, permit domain level cookies by setting the cookie domain to `test.com` then set the `auth-host` to: `auth.test.com`. @@ -362,7 +463,7 @@ Two criteria must be met for an `auth-host` to be used: 1. Request matches given `cookie-domain` 2. `auth-host` is also subdomain of same `cookie-domain` -Please note: For Auth Host mode to work, you must ensure that requests to your auth-host are routed to the traefik-forward-auth container, as demonstrated with the service labels in the [docker-compose-auth.yml](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/docker-compose-auth-host.yml) example. +Please note: For Auth Host mode to work, you must ensure that requests to your auth-host are routed to the traefik-forward-auth container, as demonstrated with the service labels in the [docker-compose-auth.yml](https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/traefik-v1.7/swarm/docker-compose-auth-host.yml) example. ## Copyright diff --git a/examples/docker-compose-dev.yml b/examples/docker-compose-dev.yml deleted file mode 100644 index f962058..0000000 --- a/examples/docker-compose-dev.yml +++ /dev/null @@ -1,48 +0,0 @@ -version: '3' - -services: - traefik: - image: traefik - command: -c /traefik.toml - # command: -c /traefik.toml --logLevel=DEBUG - ports: - - "8085:80" - - "8086:8080" - networks: - - traefik - volumes: - - ./traefik.toml:/traefik.toml - - /var/run/docker.sock:/var/run/docker.sock - - whoami1: - image: emilevauge/whoami - networks: - - traefik - labels: - - "traefik.backend=whoami1" - - "traefik.enable=true" - - "traefik.frontend.rule=Host:whoami.localhost.com" - - whoami2: - image: emilevauge/whoami - networks: - - traefik - labels: - - "traefik.backend=whoami2" - - "traefik.enable=true" - - "traefik.frontend.rule=Host:whoami.localhost.org" - - traefik-forward-auth: - build: ../ - environment: - - PROVIDERS_GOOGLE_CLIENT_ID=your-client-id - - PROVIDERS_GOOGLE_CLIENT_SECRET=your-client-secret - - SECRET=something-random - - INSECURE_COOKIE=true - - COOKIE_DOMAIN=localhost.com - - AUTH_HOST=auth.localhost.com - networks: - - traefik - -networks: - traefik: diff --git a/examples/traefik-v1.7/kubernetes/README.md b/examples/traefik-v1.7/kubernetes/README.md new file mode 100644 index 0000000..850e04f --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/README.md @@ -0,0 +1,10 @@ + +# Kubernetes + +These examples show how to deploy traefik-forward-auth alongside traefik v1.7. + +The "seperate pod" examples show traefik-forward-auth in it's own pod and leave the deployment of traefik as an exercise for the user (e.g. if using helm). + +The "single pod" examples show traefik and traefik-forward-auth in a single pod. + +Please see the README's in each example for more details. diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/README.md b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/README.md new file mode 100644 index 0000000..e4d884d --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/README.md @@ -0,0 +1,16 @@ + +# Kubernetes - Advanced Separate Pod Example + +This is an advanced example of how to deploy traefik-forward-auth in it's own pod. This example is a good starting point for those who already have traefik deployed (e.g. using helm). + +This example uses [Individual Authentication](https://github.com/thomseddon/traefik-forward-auth/blob/master/README.md#individual-ingress-authentication-in-kubernetes) to selectively apply forward authentication to each individual ingress, a simple example "whoami" application (deployment, service and ingress) is included for completeness. + +This example leverages kustomise to define Secrets and ConfigMaps, example deployment: + +``` +# Deploy traefik-forward-auth +kubectl apply -k traefik-forward-auth + +# Deploy example whoami app +kubectl apply -k whoami +``` diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/kustomization.yaml b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/kustomization.yaml new file mode 100644 index 0000000..df98ba7 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/kustomization.yaml @@ -0,0 +1,3 @@ +resources: +- traefik-forward-auth +- whoami diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/deployment.yaml b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/deployment.yaml new file mode 100644 index 0000000..eb2c80a --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/deployment.yaml @@ -0,0 +1,65 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: traefik-forward-auth + labels: + app: traefik-forward-auth +spec: + replicas: 1 + selector: + matchLabels: + app: traefik-forward-auth + strategy: + type: Recreate + template: + metadata: + labels: + app: traefik-forward-auth + spec: + terminationGracePeriodSeconds: 60 + containers: + - image: thomseddon/traefik-forward-auth:2 + name: traefik-forward-auth + ports: + - containerPort: 4181 + protocol: TCP + env: + - name: CONFIG + value: "/config" + - name: DOMAIN + value: "example.com" + # Remove COOKIE_DOMAIN if not using auth host mode + - name: COOKIE_DOMAIN + value: "example.com" + # Remove AUTH_HOST if not using auth host mode + - name: AUTH_HOST + value: "auth.example.com" + - name: LOG_LEVEL + value: "info" + - name: PROVIDERS_GOOGLE_CLIENT_ID + valueFrom: + secretKeyRef: + name: secrets + key: google-client-id + - name: PROVIDERS_GOOGLE_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: secrets + key: google-client-secret + - name: COOKIE_SECRET + valueFrom: + secretKeyRef: + name: secrets + key: cookie-secret + volumeMounts: + - name: configs + mountPath: /config + subPath: traefik-forward-auth.ini + + volumes: + - name: configs + configMap: + name: configs + - name: secrets + secret: + secretName: secrets diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/ingress.yaml b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/ingress.yaml new file mode 100644 index 0000000..328828c --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/ingress.yaml @@ -0,0 +1,17 @@ +# +# NOTE: This is only needed if you are using auth-host mode +# +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: traefik-forward-auth + labels: + app: traefik-forward-auth +spec: + rules: + - host: auth.example.com + http: + paths: + - backend: + serviceName: traefik-forward-auth + servicePort: auth-http diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/kustomization.yaml b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/kustomization.yaml new file mode 100644 index 0000000..5d82550 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/kustomization.yaml @@ -0,0 +1,22 @@ +commonLabels: + app: traefik-forward-auth + +resources: +- deployment.yaml +- service.yaml +- ingress.yaml # Only needed for auth-host mode + +# +# Configs +# +configMapGenerator: +- name: configs + files: + - traefik-forward-auth.ini + +# +# Secrets +# +secretGenerator: +- name: secrets + env: traefik-forward-auth.env diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/service.yaml b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/service.yaml new file mode 100644 index 0000000..12862bf --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: traefik-forward-auth + labels: + app: traefik-forward-auth +spec: + type: ClusterIP + selector: + app: traefik-forward-auth + ports: + - name: auth-http + port: 4181 + targetPort: 4181 diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/traefik-forward-auth.env b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/traefik-forward-auth.env new file mode 100644 index 0000000..1541c47 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/traefik-forward-auth.env @@ -0,0 +1,3 @@ +google-client-id=client-id +google-client-secret=client-secret +cookie-secret=something-random diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/traefik-forward-auth.ini b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/traefik-forward-auth.ini new file mode 100644 index 0000000..1bf8868 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/traefik-forward-auth/traefik-forward-auth.ini @@ -0,0 +1,8 @@ +rule.example_public.action=allow +rule.example_public.rule=Host("stats.example.com") && PathPrefix("/api/public") + +rule.example_api.action=allow +rule.example_api.rule=Host("api.example.com") && Headers("X-API-Authorization", "a-long-api-key") + +rule.example_api_query.action=allow +rule.example_api_query.rule=Host("api.example.com") && && Query("api_key=a-long-api-key") diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/deployment.yaml b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/deployment.yaml new file mode 100644 index 0000000..0c61e82 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/deployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: whoami + labels: + app: whoami +spec: + replicas: 1 + selector: + matchLabels: + app: whoami + template: + metadata: + labels: + app: whoami + spec: + containers: + - image: containous/whoami + name: whoami diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/ingress.yaml b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/ingress.yaml new file mode 100644 index 0000000..f53ad49 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/ingress.yaml @@ -0,0 +1,16 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: whoami + labels: + app: whoami + annotations: + kubernetes.io/ingress.class: traefik +spec: + rules: + - host: whoami.example.com + http: + paths: + - backend: + serviceName: whoami + servicePort: http diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/kustomization.yaml b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/kustomization.yaml new file mode 100644 index 0000000..917c852 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/kustomization.yaml @@ -0,0 +1,7 @@ +commonLabels: + app: whoami + +resources: +- deployment.yaml +- service.yaml +- ingress.yaml diff --git a/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/service.yaml b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/service.yaml new file mode 100644 index 0000000..77c8eb0 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-separate-pod/whoami/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: whoami + labels: + app: whoami +spec: + type: ClusterIP + ports: + - name: http + port: 80 + selector: + app: whoami + diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/README.md b/examples/traefik-v1.7/kubernetes/advanced-single-pod/README.md new file mode 100644 index 0000000..a095cf8 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/README.md @@ -0,0 +1,18 @@ + +# Kubernetes - Advanced Single Pod Example + +This is an advanced example of how to deploy traefik and traefik-forward-auth in a single pod. This example is a good starting point for those who already have a manually defined traefik config (e.g. not using helm). + +This example uses [Universal Authentication](https://github.com/thomseddon/traefik-forward-auth/blob/master/README.md#universal-authentication) to apply authentication for the entire `https` entrypoint. + +This example also includes SSL via traefik acme/lesencrypt, auth host mode, exposes the traefik dashboard and leverages kustomise. No special config if required for your applications, but a simple example "whoami" application (deployment, service and ingress) is included for completeness. + +Example deployment: + +``` +# Deploy traefik+traefik-forward-auth +kubectl apply -k traefik + +# Deploy whoami app +kubectl apply -k whoami +``` diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/configs/traefik-forward-auth.ini b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/configs/traefik-forward-auth.ini new file mode 100644 index 0000000..1bf8868 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/configs/traefik-forward-auth.ini @@ -0,0 +1,8 @@ +rule.example_public.action=allow +rule.example_public.rule=Host("stats.example.com") && PathPrefix("/api/public") + +rule.example_api.action=allow +rule.example_api.rule=Host("api.example.com") && Headers("X-API-Authorization", "a-long-api-key") + +rule.example_api_query.action=allow +rule.example_api_query.rule=Host("api.example.com") && && Query("api_key=a-long-api-key") diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/configs/traefik.toml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/configs/traefik.toml new file mode 100644 index 0000000..9939f85 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/configs/traefik.toml @@ -0,0 +1,169 @@ +################################################################ +# Global configuration +################################################################ + +# Enable debug mode +# +# Optional +# Default: false +# +# debug = true + +# Log level +# +# Optional +# Default: "ERROR" +# +logLevel = "INFO" + +# Entrypoints to be used by frontends that do not specify any entrypoint. +# Each frontend can specify its own entrypoints. +# +# Optional +# Default: ["http"] +# +defaultEntryPoints = ["http", "https"] + +# If set to true invalid SSL certificates are accepted for backends. +# This disables detection of man-in-the-middle attacks so should only be used on secure backend networks. +# +# Optional +# Default: false +# +insecureSkipVerify = true + +################################################################ +# Entrypoints configuration +################################################################ + +# Entrypoints definition +# +# Optional +# Default: +[entryPoints] + [entryPoints.http] + address = ":80" + compress = true + + [entryPoints.http.redirect] + entryPoint = "https" + + [entryPoints.https] + address = ":443" + compress = true + + [entryPoints.https.tls] + + [entryPoints.https.auth.forward] + address = "http://127.0.0.1:4181" + authResponseHeaders = ["X-Forwarded-User"] + + [entryPoints.traefik] + address = ":8080" + +################################################################ +# Traefik logs configuration +################################################################ + +# Traefik logs +# Enabled by default and log to stdout +# +# Optional +# +[traefikLog] + format = "json" + +# Sets the filepath for the traefik log. If not specified, stdout will be used. +# Intermediate directories are created if necessary. +# +# Optional +# Default: os.Stdout +# +# filePath = "log/traefik.log" + +# Format is either "json" or "common". +# +# Optional +# Default: "common" +# +# format = "common" + +################################################################ +# Access logs configuration +################################################################ + +# Enable access logs +# By default it will write to stdout and produce logs in the textual +# Common Log Format (CLF), extended with additional fields. +# +# Optional +# +# [accessLog] + +# Sets the file path for the access log. If not specified, stdout will be used. +# Intermediate directories are created if necessary. +# +# Optional +# Default: os.Stdout +# +# filePath = "/path/to/log/log.txt" + +# Format is either "json" or "common". +# +# Optional +# Default: "common" +# +# format = "common" + +################################################################ +# API and dashboard configuration +################################################################ + +# Enable API and dashboard +[api] + + # Name of the related entry point + # + # Optional + # Default: "traefik" + # + # entryPoint = "traefik" + + # Enabled Dashboard + # + # Optional + # Default: true + # + # dashboard = false + +################################################################ +# Ping configuration +################################################################ + +# Enable ping +[ping] + + # Name of the related entry point + # + # Optional + # Default: "traefik" + # + # entryPoint = "traefik" + +################################################################ +# Docker configuration backend +################################################################ + +# Enable Kubernetes configuration backend +[kubernetes] + +[acme] +KeyType = "RSA4096" +email = "you@example.com" +storage = "/acme/acme.json" +entryPoint = "https" +onHostRule = true +acmeLogging = true + +[acme.httpChallenge] + entryPoint = "http" diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/deployment.yaml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/deployment.yaml new file mode 100644 index 0000000..ff93d63 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/deployment.yaml @@ -0,0 +1,92 @@ +# +# Traefik + Traefik Forward Auth Deployment +# +apiVersion: apps/v1 +kind: Deployment +metadata: + name: traefik + labels: + app: traefik +spec: + replicas: 1 + selector: + matchLabels: + app: traefik + strategy: + type: Recreate + template: + metadata: + labels: + app: traefik + spec: + serviceAccountName: traefik + terminationGracePeriodSeconds: 60 + containers: + - image: traefik:1.7.12 + name: traefik + args: + - --configfile=/config/traefik.toml + ports: + - name: http + containerPort: 80 + hostPort: 80 + protocol: TCP + - name: https + containerPort: 443 + hostPort: 443 + protocol: TCP + - name: dash + containerPort: 8080 + protocol: TCP + volumeMounts: + - mountPath: /config + name: configs + - mountPath: /acme + name: acme + + - image: thomseddon/traefik-forward-auth:2 + name: traefik-forward-auth + ports: + - containerPort: 4181 + protocol: TCP + env: + - name: CONFIG + value: "/config" + - name: COOKIE_DOMAIN + value: "example.com" + - name: DOMAIN + value: "example.com" + - name: AUTH_HOST + value: "auth.example.com" + - name: LOG_LEVEL + value: "info" + - name: PROVIDERS_GOOGLE_CLIENT_ID + valueFrom: + secretKeyRef: + name: secrets + key: google-client-id + - name: PROVIDERS_GOOGLE_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: secrets + key: google-client-secret + - name: COOKIE_SECRET + valueFrom: + secretKeyRef: + name: secrets + key: cookie-secret + volumeMounts: + - name: configs + mountPath: /config + subPath: traefik-forward-auth.ini + + volumes: + - name: configs + configMap: + name: configs + - name: secrets + secret: + secretName: secrets + - name: acme + persistentVolumeClaim: + claimName: traefik-acme diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/ingress.yaml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/ingress.yaml new file mode 100644 index 0000000..89df622 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/ingress.yaml @@ -0,0 +1,36 @@ +# +# Auth Ingress +# +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: traefik-forward-auth + labels: + app: traefik +spec: + rules: + - host: auth.example.com + http: + paths: + - backend: + serviceName: traefik-forward-auth + servicePort: auth-http + +--- +# +# Dash Ingress +# +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: traefik-dashboard + labels: + app: traefik +spec: + rules: + - host: traefik.example.com + http: + paths: + - backend: + serviceName: traefik-dashboard + servicePort: dashboard-http diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/kustomization.yaml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/kustomization.yaml new file mode 100644 index 0000000..4212c9d --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/kustomization.yaml @@ -0,0 +1,28 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: default +commonLabels: + app: traefik + +resources: +- deployment.yaml +- service.yaml +- ingress.yaml +- pvc.yaml +- rbac.yaml + +# +# Configs +# +configMapGenerator: +- name: configs + files: + - configs/traefik.toml + - config/traefik-forward-auth.ini + +# +# Secrets +# +secretGenerator: +- name: secrets + env: secrets/traefik-forward-auth.env diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/pvc.yaml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/pvc.yaml new file mode 100644 index 0000000..3a131ae --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/pvc.yaml @@ -0,0 +1,17 @@ +# Source: traefik/templates/acme-pvc.yaml +# +# PVC +# +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: traefik-acme + labels: + app: traefik +spec: + accessModes: + - "ReadWriteOnce" + resources: + requests: + storage: "1Gi" + storageClassName: "local-traefik-acme" diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/rbac.yaml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/rbac.yaml new file mode 100644 index 0000000..ad1443c --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/rbac.yaml @@ -0,0 +1,52 @@ +# +# RBAC +# Source: traefik/templates/rbac.yaml +# +kind: ServiceAccount +apiVersion: v1 +metadata: + name: traefik +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: traefik +rules: + - apiGroups: + - "" + resources: + - pods + - services + - endpoints + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - ingresses/status + verbs: + - update +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: traefik +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: traefik +subjects: +- kind: ServiceAccount + name: traefik + namespace: kube-system diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/secrets/traefik-forward-auth.env b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/secrets/traefik-forward-auth.env new file mode 100644 index 0000000..1541c47 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/secrets/traefik-forward-auth.env @@ -0,0 +1,3 @@ +google-client-id=client-id +google-client-secret=client-secret +cookie-secret=something-random diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/service.yaml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/service.yaml new file mode 100644 index 0000000..9629917 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/traefik/service.yaml @@ -0,0 +1,36 @@ +# +# Auth Service +# +apiVersion: v1 +kind: Service +metadata: + name: traefik-forward-auth + labels: + app: traefik +spec: + type: ClusterIP + selector: + app: traefik + ports: + - name: auth-http + port: 4181 + targetPort: 4181 + +--- +# +# Dash Service +# +apiVersion: v1 +kind: Service +metadata: + name: traefik-dashboard + labels: + app: traefik +spec: + type: ClusterIP + selector: + app: traefik + ports: + - name: dashboard-http + port: 8080 + targetPort: 8080 diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/deployment.yaml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/deployment.yaml new file mode 100644 index 0000000..0c61e82 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/deployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: whoami + labels: + app: whoami +spec: + replicas: 1 + selector: + matchLabels: + app: whoami + template: + metadata: + labels: + app: whoami + spec: + containers: + - image: containous/whoami + name: whoami diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/ingress.yaml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/ingress.yaml new file mode 100644 index 0000000..f53ad49 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/ingress.yaml @@ -0,0 +1,16 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: whoami + labels: + app: whoami + annotations: + kubernetes.io/ingress.class: traefik +spec: + rules: + - host: whoami.example.com + http: + paths: + - backend: + serviceName: whoami + servicePort: http diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/kustomization.yaml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/kustomization.yaml new file mode 100644 index 0000000..917c852 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/kustomization.yaml @@ -0,0 +1,7 @@ +commonLabels: + app: whoami + +resources: +- deployment.yaml +- service.yaml +- ingress.yaml diff --git a/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/service.yaml b/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/service.yaml new file mode 100644 index 0000000..77c8eb0 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/advanced-single-pod/whoami/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: whoami + labels: + app: whoami +spec: + type: ClusterIP + ports: + - name: http + port: 80 + selector: + app: whoami + diff --git a/examples/traefik-v1.7/kubernetes/simple-separate-pod/README.md b/examples/traefik-v1.7/kubernetes/simple-separate-pod/README.md new file mode 100644 index 0000000..5756915 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/simple-separate-pod/README.md @@ -0,0 +1,43 @@ + +# Kubernetes - Simple Separate Pod Example + +This is a simple example of how to deploy traefik-forward-auth in it's own pod with minimal configuration. This example is a good starting point for those who already have traefik deployed (e.g. using helm). + +This example uses annotations to apply authentication to selected ingresses (see `k8s-app.yml`). This means ingresses will not be protected by default, only those with these annotations will require forward authentication. For example: + +``` +# +# Ingress +# +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: whoami + labels: + app: whoami + annotations: + kubernetes.io/ingress.class: traefik + ingress.kubernetes.io/auth-type: forward + ingress.kubernetes.io/auth-url: http://traefik-forward-auth:4181 + ingress.kubernetes.io/auth-response-headers: X-Forwarded-User +spec: + rules: + - host: whoami.example.com + http: + paths: + - backend: + serviceName: whoami + servicePort: http +``` + + +Example deployment: +``` +# Deploy traefik-forward-auth +kubectl apply -f k8s-traefik-forward-auth.yml + +# Deploy example whoami app +kubectl apply -f k8s-app.yml +``` + +Please see the advanced examples for more details. diff --git a/examples/traefik-v1.7/kubernetes/simple-separate-pod/k8s-app.yml b/examples/traefik-v1.7/kubernetes/simple-separate-pod/k8s-app.yml new file mode 100644 index 0000000..bd42d93 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/simple-separate-pod/k8s-app.yml @@ -0,0 +1,62 @@ +# +# Example Application Deployment +# +apiVersion: apps/v1 +kind: Deployment +metadata: + name: whoami + labels: + app: whoami +spec: + replicas: 1 + selector: + matchLabels: + app: whoami + template: + metadata: + labels: + app: whoami + spec: + containers: + - name: whoami + image: emilevauge/whoami +--- +# +# Service +# +apiVersion: v1 +kind: Service +metadata: + name: whoami + labels: + app: whoami +spec: + ports: + - name: http + port: 80 + selector: + app: whoami + +--- +# +# Ingress +# +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: whoami + labels: + app: whoami + annotations: + kubernetes.io/ingress.class: traefik + ingress.kubernetes.io/auth-type: forward + ingress.kubernetes.io/auth-url: http://traefik-forward-auth:4181 + ingress.kubernetes.io/auth-response-headers: X-Forwarded-User +spec: + rules: + - host: whoami.example.com + http: + paths: + - backend: + serviceName: whoami + servicePort: http diff --git a/examples/traefik-v1.7/kubernetes/simple-separate-pod/k8s-traefik-forward-auth.yml b/examples/traefik-v1.7/kubernetes/simple-separate-pod/k8s-traefik-forward-auth.yml new file mode 100644 index 0000000..56008d5 --- /dev/null +++ b/examples/traefik-v1.7/kubernetes/simple-separate-pod/k8s-traefik-forward-auth.yml @@ -0,0 +1,87 @@ +# +# Traefik Forward Auth Deployment +# +apiVersion: apps/v1 +kind: Deployment +metadata: + name: traefik-forward-auth + labels: + app: traefik-forward-auth +spec: + replicas: 1 + selector: + matchLabels: + app: traefik-forward-auth + strategy: + type: Recreate + template: + metadata: + labels: + app: traefik-forward-auth + spec: + terminationGracePeriodSeconds: 60 + containers: + - image: thomseddon/traefik-forward-auth:2 + name: traefik-forward-auth + ports: + - containerPort: 4181 + protocol: TCP + env: + - name: DOMAIN + value: "example.com" + - name: PROVIDERS_GOOGLE_CLIENT_ID + valueFrom: + secretKeyRef: + name: secrets + key: traefik-forward-auth-google-client-id + - name: PROVIDERS_GOOGLE_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: secrets + key: traefik-forward-auth-google-client-secret + - name: COOKIE_SECRET + valueFrom: + secretKeyRef: + name: secrets + key: traefik-forward-auth-cookie-secret + +--- +# +# Auth Service +# +apiVersion: v1 +kind: Service +metadata: + name: traefik-forward-auth + labels: + app: traefik-forward-auth +spec: + type: ClusterIP + selector: + app: traefik-forward-auth + ports: + - name: auth-http + port: 4181 + targetPort: 4181 + +--- +# +# Secrets +# +# Kubernetes requires secret values to be converted to base64 when defined +# explicitly like this. (use `echo -n 'secret-value' | base64`) +# +# These are here for completeness, in reality you may define these elsewhere, +# for example using kustomize (shown in advanced examples) +# +apiVersion: v1 +kind: Secret +metadata: + name: traefik-forward-auth-secrets + labels: + app: traefik-forward-auth +type: Opaque +data: + traefik-forward-auth-google-client-id: base64-client-id + traefik-forward-auth-google-client-secret: base64-client-secret + traefik-forward-auth-cookie-secret: base64-something-random diff --git a/examples/docker-compose-auth-host.yml b/examples/traefik-v1.7/swarm/docker-compose-auth-host.yml similarity index 100% rename from examples/docker-compose-auth-host.yml rename to examples/traefik-v1.7/swarm/docker-compose-auth-host.yml diff --git a/examples/docker-compose-oidc.yml b/examples/traefik-v1.7/swarm/docker-compose-oidc.yml similarity index 100% rename from examples/docker-compose-oidc.yml rename to examples/traefik-v1.7/swarm/docker-compose-oidc.yml diff --git a/examples/docker-compose.yml b/examples/traefik-v1.7/swarm/docker-compose.yml similarity index 100% rename from examples/docker-compose.yml rename to examples/traefik-v1.7/swarm/docker-compose.yml diff --git a/examples/traefik.toml b/examples/traefik-v1.7/swarm/traefik.toml similarity index 99% rename from examples/traefik.toml rename to examples/traefik-v1.7/swarm/traefik.toml index 4aa9882..4091d4f 100644 --- a/examples/traefik.toml +++ b/examples/traefik-v1.7/swarm/traefik.toml @@ -135,3 +135,4 @@ # Enable Docker configuration backend [docker] exposedByDefault = false +network = "traefik"