Skip to content

Instantly share code, notes, and snippets.

@LukasForst
Last active June 21, 2024 05:18
Show Gist options
  • Save LukasForst/9898e08b6290821d6ccfcd0b6ad4f376 to your computer and use it in GitHub Desktop.
Save LukasForst/9898e08b6290821d6ccfcd0b6ad4f376 to your computer and use it in GitHub Desktop.
Traefik, Authentik forward auth example

Deploying Traefik using forward proxy mode with Authentik

This is an example guide how to deploy Authentik with Traefik in forward auth proxy mode - that means that any application behind the proxy will be automatically authenticated by Traefik. This allows better reuse of code and completely moves user management to Traefik & Authentik.

In this guide we use custom DNS to make the requests nicer and to show that it works with DNS. So step #1 is to put following records to your /etc/hosts (for example by sudo nano /etc/hosts and adding these values)

# domains needed for traefik & authentik example
127.0.0.1 app.example.com
127.0.0.1 auth.example.com

Now we need to start the applications - it is not completely automated, even thought we set the dependencies, Traefik does not pick the middleware from the beginning, so it's better to start it one by one. Also check the logs per app if it started. First make sure you have correct docker-compose.yml file in the current folder (part of this gist).

  1. start databases -> docker compose up -d postgresql redis
  2. start worker & authentik server -> docker compose up -d worker server
  3. now go to http://localhost:9000/if/flow/initial-setup/ and create new account for authentik (the username is akadmin)
  4. setup application http://localhost:9000/if/admin/#/core/applications including provider
  5. when setting up provider, choose Forward auth (single application) option
  6. setup outpost http://localhost:9000/if/admin/#/outpost/outposts that points to the application
  7. click on View Deployment Info and copy token -> this token then put to the docker-compose.yml to authentik-proxy service as environment variable AUTHENTIK_TOKEN=<copied data>
  8. start proxy -> docker compose up -d authentik-proxy
  9. start our real app -> docker compose up -d whoami
  10. if logs look good (especially authentik-proxy needs to be checked), start Traefik -> docker compose up -d traefik
  11. now everything should be up & running -> app is accessible from app.example.com and authentik admin interface from auth.example.com
  12. go to app and you will be asked to log in, use credentials created in step #3
version: '3.8'
services:
traefik:
image: traefik:v2.8
container_name: traefik
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "80:80"
depends_on:
- server
- whoami
command:
- "--api"
- "--providers.docker=true"
- "--providers.docker.exposedByDefault=false"
- "--entrypoints.web.address=:80"
server:
image: ghcr.io/goauthentik/server:2022.7.3
command: server
environment:
- AUTHENTIK_REDIS__HOST=redis
- AUTHENTIK_POSTGRESQL__HOST=postgresql
- AUTHENTIK_POSTGRESQL__USER=authentik
- AUTHENTIK_POSTGRESQL__NAME=authentik
- AUTHENTIK_POSTGRESQL__PASSWORD=authentik
- AUTHENTIK_ERROR_REPORTING__ENABLED=true
- AUTHENTIK_SECRET_KEY=iO6XOk2wSIa5Q3bWt7G4263LqTlCKu4o
ports:
- "9000:9000"
depends_on:
- worker
- postgresql
- redis
labels:
- "traefik.enable=true"
- "traefik.port=9000"
- "traefik.http.routers.server.rule=Host(`auth.example.com`)"
worker:
image: ghcr.io/goauthentik/server:2022.7.3
command: worker
environment:
- AUTHENTIK_REDIS__HOST=redis
- AUTHENTIK_POSTGRESQL__HOST=postgresql
- AUTHENTIK_POSTGRESQL__USER=authentik
- AUTHENTIK_POSTGRESQL__NAME=authentik
- AUTHENTIK_POSTGRESQL__PASSWORD=authentik
- AUTHENTIK_ERROR_REPORTING__ENABLED=true
- AUTHENTIK_SECRET_KEY=iO6XOk2wSIa5Q3bWt7G4263LqTlCKu4o
user: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
authentik-proxy:
image: ghcr.io/goauthentik/proxy
ports:
- "9091:9000"
environment:
- AUTHENTIK_HOST=http://server:9000
- AUTHENTIK_INSECURE=true
- AUTHENTIK_TOKEN=setme #generated by authentik when outpost is created
- AUTHENTIK_HOST_BROWSER=http://auth.example.com
- AUTHENTIK_DEBUG=true
depends_on:
- server
labels:
- "traefik.enable=true"
- "traefik.port=9000"
- "traefik.http.routers.authentik-proxy.rule=Host(`app.example.com`) && PathPrefix(`/outpost.goauthentik.io/`)"
- "traefik.http.middlewares.authentik.forwardauth.address=http://authentik-proxy:9000/outpost.goauthentik.io/auth/traefik"
- "traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true"
- "traefik.http.middlewares.authentik.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version"
whoami:
image: containous/whoami
depends_on:
- authentik-proxy
labels:
- "traefik.enable=true"
- "traefik.port=80"
- "traefik.http.routers.whoami.rule=Host(`app.example.com`)"
- "traefik.http.routers.whoami.middlewares=authentik@docker"
postgresql:
image: postgres:12-alpine
healthcheck:
test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- database:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=authentik
- POSTGRES_USER=authentik
- POSTGRES_DB=authentik
redis:
image: redis:alpine
healthcheck:
test: [ "CMD-SHELL", "redis-cli ping | grep PONG" ]
start_period: 20s
interval: 30s
retries: 5
timeout: 3s
volumes:
database:
@Nomtest
Copy link

Nomtest commented Oct 24, 2022

Hello,

how to know default value for postgresql password or other default values of secrets ?

Maybe my previous question is a misunderstanding : I have to set my own value in the secrets files and these values are used and set during the 1st start when the DB is generated ?

And so : how to change these value in 3 months by example to match with a policy of change ?

Thank for your help.

@LukasForst
Copy link
Author

Hey @Nomtest - check https://hub.docker.com/_/postgres documentation. In a nutshell - when you set POSTGRES_PASSWORD env variable for the container, it uses this password during the first startup.
How to change it - then you need to docker exec into the container and run commands from here - https://stackoverflow.com/a/12721095 . Once you do that, don't forget to update env variable for the authentik! Otherwise it wouldn't be able to connect.

@ja-softdevel
Copy link

This is the first example I've seen with authentik/proxy. Good example, but I'm trying to setup authentik to answer on a path/route ie: localhost.test/auth.

I'm still trying to learn authentik. Why are you using authentik/proxy? I thought the server could handle all of it.

@LukasForst
Copy link
Author

I do not think this is possible as of now (months ago, the last time I tried), we had to use different domain where we run Authentik. It's because their frontend is not compatible and expects to be running on the / path.

@ja-softdevel
Copy link

I had it working. You have to use middlewares in traefik to stripe the route and it was overly complicated. So I went the subdomain way and it works pretty straightforward after that.

@42Fourward
Copy link

42Fourward commented Jun 2, 2023

Hello,
Did you manage to make the project work?
For my part, when I request app.example.com, I am redirected to auth.example.com to authenticate myself. After authenticating, I can't access the whoami service, I have a blank page. In the logs of the authentik-proxy service, I have this:

level=warning event="failed to redeem code" error="oidc: id token issued by a different provider, expected "http://server:9000/application /o/whoami/" got "http://app.example.com/application/o/whoami/\"" logger=authentik.outpost.proxyv2.application name=whoami-proxy

An idea ?

[EDIT]
I just found the solution. For those interested, I removed the AUTHENTIK_HOST_BROWSER variable and set the AUTHENTIK_HOST variable to http://auth.example.com. Finally, I created an alias for this FQDN on Traefik, so that the flow can go through the reverse proxy (because the container does not listen on port 80 but port 9000)

@Aetherinox
Copy link

My confusion comes from app.example.com.
It doesn't make sense to specify app.example.com within authentik-proxy:. I have multiple apps that need to be redirected from Authentik. And in the other examples I've seen, the traefik host redirecting outpost is placed in the authentik-server, not the proxy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment