Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Solved] Forward Auth in Traefik / Docker environment not working #2180

Closed
agrimpelhuber opened this issue Jan 28, 2022 · 32 comments
Closed
Labels
question Further information is requested

Comments

@agrimpelhuber
Copy link

agrimpelhuber commented Jan 28, 2022

Describe your question

Trying to set up Forward Auth in front of a simple web application (Nginx+php-fpm in a container, for testing purposes) within a Docker / Traefik environment, description below. Whatever I try, no matter how much documentation or code I read, I end up with 2 different scenarios, depending on the setup.

Single Application setup: At best an infinite loop on Authentik's login form
Domain Application setup: HTTP code 400 and

{
	"Message": "no app for hostname",
	"Host": "auth.mydomain.com",
	"Detail": "Check the outpost settings and make sure 'auth.mydomain.com' is included."
}

EDIT: The most likely cause for this problem is the routing in Traefik. The above message does not come from the Forward Auth proxy outpost, but rather from Authentik itself, running under the same domain auth.mydomain.com as the proxy does . It's very likely you need to adjust route priorities in Traefic. Specifics in the comments.

---- Original post ----

Assuming that I'm doing something wrong, I give as much information as possible below for someone smart to spot the probably simple / stupid / obvious mistake I'm making. If it's not that obvious, I'll provide more info straight away.

Relevant infos
Setup I'm starting with:

  • Web application (nginx + php-fpm in container, listening on port 80 in internal docker network)
  • Traefik, also running in a container, routes HTTPS traffic to the application on subdomain app.mydomain.com
  • The same applies to Authentik. It can be reached on auth.mydomain.com from the internet
  • All 3 containers are connected to a bridged docker network called "common-bridge" (172.128.0.0/16)
  • All components are running smoothly prior to my attempt to implement forward auth

Trying to set up Forward Auth with the following steps / configuration:

  1. Application in Authentik:
Name: Forward Auth
Slug: forward-auth
Provider: Forward Auth
Policy: ANY [...]
UI settings / Launch URL: https://app.mydomain.com
  1. Provider in Authentik:
Type: Proxy Provider
Name: Forward Auth
Authorization flow: default-provider-authorization-explicit-consent
[Type:] Forward Auth (domain level)
Authentication URL: https://auth.mydomain.com
Cookie domain: mydomain.com
  1. Outpost in Authentik:
Name: Forward Auth
Type: Proxy
Integration: Local Docker connection
Applications: Forward Auth (https://auth.mydomain.com)
Configuration (leaving out the standard Kubernetes stuff):
    log_level: trace
    docker_labels:
      traefik.http.routers.ak-outpost-b650b531e5384d3ba8e8e605eac1938d-router.entrypoints: websecure
      traefik.http.routers.ak-outpost-b650b531e5384d3ba8e8e605eac1938d-router.tls.certresolver: myresolver
    authentik_host: https://auth.mydomain.com
    docker_network: common-bridge
    container_image: null
    docker_map_ports: false
    authentik_host_browser: ""
    object_naming_template: authentik-outpost-%(name)s
    authentik_host_insecure: false
  1. Traefik middleware configuration in docker-compose of web app:
labels:
- "traefik.http.routers.nginx-2.middlewares=authentik-php@docker"
- "traefik.http.middlewares.authentik-php.forwardauth.address=http://authentik-outpost-forward-auth:9000/akprox/auth/traefik"
- "traefik.http.middlewares.authentik-php.forwardauth.trustForwardHeader=true"
- "traefik.http.middlewares.authentik-php.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"
  1. On startup, everything seems to be fine:
  • Authentik brings up the "authentik-outpost-forward-auth" proxy container
  • The container registers in Traefik with the rule Host(`auth.mydomain.com`) && PathPrefix(`/akprox`)
  • No errors in the logs files, as far as I can see (log level "trace")
  • All the (internal) network connections seem to be working

However, when I call https://app.mydomain.com, I'm automatically redirected (even when not authorized) to https://auth.mydomain.com/akprox/start with the "no app for hostname" output.

Screenshots
n/a

Logs
Output of container "authentik-outpost-forward-auth" (trace):

{"app":"Forward Auth","event":"Found app based on cookie domain","host":"app.mydomain.com","level":"debug","logger":"authentik.outpost.proxyv2","timestamp":"2022-01-28T15:22:38Z"}
{"event":"passing to application mux","host":"app.mydomain.com","level":"trace","logger":"authentik.outpost.proxyv2","timestamp":"2022-01-28T15:22:38Z"}
{"event":"tracing headers for debug","header":{"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"Accept-Encoding":["gzip, deflate, br"],"Accept-Language":["de-DE,de;q=0.9,en;q=0.8,en-US;q=0.7"],"Dnt":["1"],"Sec-Ch-Ua":["\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\""],"Sec-Ch-Ua-Mobile":["?0"],"Sec-Ch-Ua-Platform":["\"Windows\""],"Sec-Fetch-Dest":["document"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-Site":["none"],"Sec-Fetch-User":["?1"],"Upgrade-Insecure-Requests":["1"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"],"X-Forwarded-For":["xx.180.177.202"],"X-Forwarded-Host":["app.mydomain.com"],"X-Forwarded-Method":["GET"],"X-Forwarded-Port":["443"],"X-Forwarded-Proto":["https"],"X-Forwarded-Server":["b7eb2436cf7c"],"X-Forwarded-Uri":["/handler.php"],"X-Real-Ip":["xx.180.177.202"]},"level":"trace","logger":"authentik.outpost.proxyv2.application","name":"Forward Auth","timestamp":"2022-01-28T15:22:38Z"}
{"event":"traefik forwarded url","level":"trace","logger":"authentik.outpost.proxyv2.application","name":"Forward Auth","timestamp":"2022-01-28T15:22:38Z","url":"https://app.mydomain.com/handler.php"}
{"event":"Matching URL against allow list","level":"trace","logger":"authentik.outpost.proxyv2.application","name":"Forward Auth","regex":"https://app.mydomain.com/handler.php","timestamp":"2022-01-28T15:22:38Z","url":"https://app.mydomain.com/handler.php"}
{"event":"Redirecting to login","level":"debug","logger":"authentik.outpost.proxyv2.application","name":"Forward Auth","timestamp":"2022-01-28T15:22:38Z","url":"https://auth.mydomain.com/akprox/start"}
{"event":"/akprox/auth/traefik","host":"app.mydomain.com","level":"info","logger":"authentik.outpost.proxyv2.application","method":"GET","name":"Forward Auth","remote":"172.128.0.10:41948","request_protocol":"HTTP/1.1","request_useragent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36","runtime":"0.960","size":78,"status":307,"timestamp":"2022-01-28T15:22:38Z","upstream":""}

What is weird: The call to https://app.mydomain.com/handler.php does not even seem to reach the authentic core.

Version and Deployment (please complete the following information):

  • authentik version: 2022.1.3
  • traefik version: 2.6.0
  • docker version: current
  • Deployment: docker-compose (authentik, traefik in different containers) + portainer
  • Single server, single domain and subdomains for different applications

Additional context
n/a

@agrimpelhuber agrimpelhuber added the question Further information is requested label Jan 28, 2022
@Jafner
Copy link

Jafner commented Jan 31, 2022

+1 for this.
I would also like to use Authentik with Traefik ForwardAuth. And I am encountering the same issue.

@sungyoonc
Copy link

I'm having the same issue. It's seems like the outpost has problem with the connection through traefik. When I directly connect to the outpost it doesn't have any issue.

@agrimpelhuber
Copy link
Author

Hi! Thanks for the feedback. Don't know when the intergration was last used / tested successfully, but there is a slight chance that a recent update of Traefik might have caused this. @winterolym and @Jafner , can you state the versions of Traefik and Authentik as well as the type of installation (assuming docker) you are running, to help someone more knowledgeable than us to find a clue?

In order to help debugging the Traefik side, I have set up another Nginx/PHP-fpm container as a fake forward auth proxy / traefik middleware. That container simply returns the 200 code (authenticated), but logs all the headers received from traefik. Traefik contacts that host on the internal docker network via http://172.128.0.x/handler.php.

Here are the relevant headers when I call /_phpinfo.php on the target host:

    [HTTP_X_REAL_IP] => 91.my.pcs.ip
    [HTTP_X_FORWARDED_URI] => /_phpinfo.php
    [HTTP_X_FORWARDED_SERVER] => b7eb2436cf7c
    [HTTP_X_FORWARDED_PROTO] => https
    [HTTP_X_FORWARDED_PORT] => 443
    [HTTP_X_FORWARDED_METHOD] => GET
    [HTTP_X_FORWARDED_HOST] => app.mydomain.com
    [HTTP_X_FORWARDED_FOR] => 91.my.pcs.ip
    [HTTP_UPGRADE_INSECURE_REQUESTS] => 1
    [HTTP_SEC_FETCH_USER] => ?1
    [HTTP_SEC_FETCH_SITE] => none
    [HTTP_SEC_FETCH_MODE] => navigate
    [HTTP_SEC_FETCH_DEST] => document
    [HTTP_SEC_CH_UA_PLATFORM] => "Windows"
    [HTTP_SEC_CH_UA_MOBILE] => ?0
    [HTTP_SEC_CH_UA] => " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
    [HTTP_DNT] => 1
    [HTTP_COOKIE] => SessionID=12345
    [HTTP_ACCEPT_LANGUAGE] => de-DE,de;q=0.9,en;q=0.8,en-US;q=0.7
    [HTTP_ACCEPT_ENCODING] => gzip, deflate, br
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
    [HTTP_HOST] => nginx-php-2
    [SCRIPT_FILENAME] => /var/www/html/handler.php

Next step would be to debug how the Authentik proxy uses that data, and whether there is something wrong with this initial data it gets from Traefik in the first place. Hope that help.

I'd be willing to dig deeper into this, but without help, I haven't been able to figure out the exact workflow that follows in the Authentik Forward Auth proxy.

@sungyoonc
Copy link

@agrimpelhuber I'm running both traefik 2.6.0 and authentik 2022.1.3 with docker compose.

BeryJu added a commit that referenced this issue Feb 1, 2022
…h_domain

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#2180
@BeryJu
Copy link
Member

BeryJu commented Feb 1, 2022

@agrimpelhuber @Jafner @winterolym could you try out the latest build, which should fix this issue

See https://goauthentik.io/docs/installation/beta, just replace gh-next with gh-master

@agrimpelhuber
Copy link
Author

Sorry, no change, neither in the result nor in the log output. Here's the output from the forward proxy:

{"app":"Forward Auth","event":"Found app based on cookie domain","host":"app.mydomain.com","level":"debug","logger":"authentik.outpost.proxyv2","timestamp":"2022-02-01T09:54:43Z"}
{"event":"passing to application mux","host":"app.mydomain.com","level":"trace","logger":"authentik.outpost.proxyv2","timestamp":"2022-02-01T09:54:43Z"}
{"event":"tracing headers for debug","header":{"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"Accept-Encoding":["gzip, deflate, br"],"Accept-Language":["de-DE,de;q=0.9,en;q=0.8,en-US;q=0.7"],"Cookie":["SessionID=12345; authentik_proxy=MTY0MzcwODc3MHxOd3dBTkZKV01rUkhRemRMVEZjM1J6TXlTek0zVms1QldUTTBTRUpPVVRZMFRFTXpSMWhFUzBRek5FdzBUVFJWTmtsR1IxVkNSVkU9fLt-vqA3eVyrfpKq3rkd3SON8XsSBWkntvs801b41PS0"],"Dnt":["1"],"Sec-Ch-Ua":["\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\""],"Sec-Ch-Ua-Mobile":["?0"],"Sec-Ch-Ua-Platform":["\"Windows\""],"Sec-Fetch-Dest":["document"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-Site":["none"],"Sec-Fetch-User":["?1"],"Upgrade-Insecure-Requests":["1"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"],"X-Forwarded-For":["91.my.pcs.ip"],"X-Forwarded-Host":["app.mydomain.com"],"X-Forwarded-Method":["GET"],"X-Forwarded-Port":["443"],"X-Forwarded-Proto":["https"],"X-Forwarded-Server":["b7eb2436cf7c"],"X-Forwarded-Uri":["/handler.php"],"X-Real-Ip":["91.my.pcs.ip"]},"level":"trace","logger":"authentik.outpost.proxyv2.application","name":"Forward Auth","timestamp":"2022-02-01T09:54:43Z"}
{"event":"traefik forwarded url","level":"trace","logger":"authentik.outpost.proxyv2.application","name":"Forward Auth","timestamp":"2022-02-01T09:54:43Z","url":"https://app.mydomain.com/handler.php"}
{"event":"Matching URL against allow list","level":"trace","logger":"authentik.outpost.proxyv2.application","name":"Forward Auth","regex":"https://app.mydomain.com/handler.php","timestamp":"2022-02-01T09:54:43Z","url":"https://app.mydomain.com/handler.php"}
{"event":"Redirecting to login","level":"debug","logger":"authentik.outpost.proxyv2.application","name":"Forward Auth","timestamp":"2022-02-01T09:54:43Z","url":"https://auth.mydomain.com/akprox/start"}
{"event":"/akprox/auth/traefik","host":"app.mydomain.com","level":"info","logger":"authentik.outpost.proxyv2.application","method":"GET","name":"Forward Auth","remote":"172.128.0.10:43860","runtime":"1.045","scheme":"","size":78,"status":307,"timestamp":"2022-02-01T09:54:43Z","upstream":"","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"}

What can I do?

@BeryJu
Copy link
Member

BeryJu commented Feb 1, 2022

Which error do you get with that? From the logs it seems all right, application is found based on cookie domain, it's detected the traefik params, and is redirecting you to login, which should carry forward to your browser

@agrimpelhuber
Copy link
Author

agrimpelhuber commented Feb 1, 2022

Sorry, I implied that - the same as above:

{
	"Message": "no app for hostname",
	"Host": "auth.mydomain.com",
	"Detail": "Check the outpost settings and make sure 'auth.mydomain.com' is included."
}

@sungyoonc
Copy link

sungyoonc commented Feb 1, 2022

If I connect to the https://app.mydomain.com it will redirect me to https://auth.mydomain.com/akprox/start and it gives me this error.

{
	"Message": "no app for hostname",
	"Host": "auth.mydomain.com",
	"Detail": "Check the outpost settings and make sure 'auth.mydomain.com' is included."
}

However when I bypass traefik and go to http://auth.mydomain.com:9000/akprox/start it redirects me to this url
http://auth.mydomain.com:9000/application/o/authorize/?client_id=<some token>&redirect_uri=https://auth.mydomain.com/akprox/callback&response_type=code&scope=email+profile+openid+ak_proxy&state=<some token>

If I change the url to this
https://auth.mydomain.com/application/o/authorize/?client_id=&redirect_uri=https://auth.mydomain.com/akprox/callback&response_type=code&scope=email+profile+openid+ak_proxy&state=<some token>
and it shows me the login page.

After I login I get redirected to this url
https://auth.mydomain.com/akprox/callback?code=<some token>
and if I change this url to
http://auth.mydomain.com:9000/akprox/callback?code=<some token>
and visit it, it redirects me to the correct application.

@agrimpelhuber
Copy link
Author

@BeryJu , I tried to follow your code in order to provide more information, but got lost between the redirect to auth.mydomain.com/akprox/start and the browser message, obviously created by func (ps *ProxyServer) Handle(rw http.ResponseWriter, r *http.Request) {. This is due to a lack of experience, but:

The more I look at it, the more I get the feeling that we need some more log output between those stages. For example, is the function handleRedirect still involved in the whole thing? What is written into which cookie, and is something lost, due to Traefik? The findings of @winterolym suggest this.

@BeryJu
Copy link
Member

BeryJu commented Feb 1, 2022

I'm pretty sure I actually know whats causing this; from the looks of it both of you are running authentik on auth.domain.tld, and then also using auth.domain.tld as external host for an outpost. This leads to requests to app.domain.tld going internally to the outpost, but since thats configured for auth.domain.tld, it redirects to that, however on that domain the embedded outpost seems to have a higher routing priority, and since the embedded outpost does not have the application selected, it errors. Can both of you try using the embedded outpost instead of a separate outpost?

@sungyoonc
Copy link

After giving the outpost the higher priority in traefik everything works now. Thank you so much.

@agrimpelhuber
Copy link
Author

agrimpelhuber commented Feb 1, 2022

@BeryJu , you are a genius! Thanks ever so much!

@winterolym has beaten me by 2 hours. Maybe because I was running the integrated outpost, and had to figure out how to set the priority there, and to what values:

  • I set the priority of the authentic docker container in docker-compose to 1, just to be on the safe side:
      - "traefik.enable=true"
      - "traefik.http.routers.authentik.priority=1"
  • In the Authentic outpost configuration, I set the priority to 50, using the docker_labels option:
docker_labels:
  traefik.http.routers.ak-outpost-b650b531e5384d3ba8e8e605eac1938d-router.priority: "50"

What I wasn't aware of was not only the fact that the priority was part of the problem, but that traefik actually calculates the priority based on the actual number of characters in the router's rule. Thus, "50" didn't work for the proxy without setting "1" for Authentik itself, because the rule of he authentic docker was way longer.

Which again was another problem I had caused by accident: When you'd normally think that the rule with "/akprox" would be naturally longer than the one without, ...

Host(`auth.mydomain.com`) && PathPrefix(`/akprox`) #Higher Priority
Host(`auth.mydomain.com`) #Lower Priority

... it fell on my feet because in order to debug far more basic stuff, I had configured 2 subdomains for Authentic - doh

Host(`auth.mydomain.com`) && PathPrefix(`/akprox`) #Lower Priority
Host(`auth.mydomain.com`) || Host(`login.mydomain.com`) #Higher Priority

I hope this helps other people to avoid similar mistakes.

@BeryJu, I didn't succeed to use variables like %(name)s in the docker_labels configuration to avoid writing "b650b531e5384d3ba8e8e605eac1938d" time and time again. But that would be luxury - at least it's working now!

@BeryJu
Copy link
Member

BeryJu commented Feb 1, 2022

I'll add something to the docs for this setup, is there any reason you aren't using the embedded outpost? That shouldn't cause any of these issues.

For the labels @agrimpelhuber I'm gonna change it so labels aren't based on the UUID and instead follow the same naming template as the container itself

@agrimpelhuber
Copy link
Author

I'm using the embedded outpost, so I guess the question applies to @winterolym. In hindsight, my problem was the long traefik rule itself. To be positive, we would never have found the cause without my initial mistake in the first place.

Thanks for the labels! Looking forward (-auth - pun intended) to put all my apps behind authentik now!

@agrimpelhuber agrimpelhuber changed the title Forward Auth in Traefik / Docker environment not working / Help wanted [Solved] Forward Auth in Traefik / Docker environment not working / Help wanted Feb 1, 2022
@agrimpelhuber agrimpelhuber changed the title [Solved] Forward Auth in Traefik / Docker environment not working / Help wanted [Solved] Forward Auth in Traefik / Docker environment not working Feb 1, 2022
@sungyoonc
Copy link

@BeryJu I couldn't get the embedded outpost to redirect properly after the authentication. It redirected me to https://auth.domain.tld/if/user/#/library instead of the application.

@Jafner
Copy link

Jafner commented Feb 1, 2022

I'll add something to the docs for this setup, is there any reason you aren't using the embedded outpost? That shouldn't cause any of these issues.

For the labels @agrimpelhuber I'm gonna change it so labels aren't based on the UUID and instead follow the same naming template as the container itself

I am using the embedded proxy and I am encountering these issues.

I'm getting a little lost in all the configuration changes I've been making, so I'll post here where I'm starting from:

Authentik compose file:

version: '3.2'

services:
  postgresql:
    image: postgres:12-alpine
    restart: unless-stopped
    networks:
      - authentik
    volumes:
      - database:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=${PG_PASS}
      - POSTGRES_USER=${PG_USER:-authentik}
      - POSTGRES_DB=${PG_DB:-authentik}
    env_file:
      - .env

  redis:
    image: redis:alpine
    networks:
      - authentik
    restart: unless-stopped

  server:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.1.3}
    networks:
      authentik:
      web:
        aliases:
          - authentik-server
    #ports: 
    #  - 9000:9000
    restart: unless-stopped
    command: server
    environment:
      AUTHENTIK_HOST: https://auth.jafner.net
      #AUTHENTIK_HOST: http://authentik-server:9000
      AUTHENTIK_HOST_BROWSER: https://auth.jafner.net
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_POSTGRESQL__HOST: postgresql
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
    volumes:
      - ${DOCKER_DATA}/media:/media
      - ${DOCKER_DATA}/custom-templates:/templates
    env_file:
      - .env
    labels:
      traefik.http.routers.authentik.rule: Host(`auth.mydomain.com`) 
      traefik.http.routers.authentik.entrypoints: websecure
      traefik.http.routers.authentik-auth.rule: Host(`app.mydomain.dev`) && PathPrefix(`/akprox/`)
      traefik.http.routers.authentik-auth.entrypoints: websecure
      traefik.http.routers.authentik.tls.certresolver: lets-encrypt
      traefik.http.services.authentik.loadbalancer.server.port: 9000
      traefik.http.middlewares.authentik.forwardauth.address: https://auth.mydomain.com/akprox/auth/traefik
      #traefik.http.middlewares.authentik.forwardauth.address: http://authentik-server:9000/akprox/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

  worker:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.1.3}
    restart: unless-stopped
    networks:
      - authentik
    command: worker
    environment:
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_POSTGRESQL__HOST: postgresql
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
    user: root
    volumes:
      - ${DOCKER_DATA}/backups:/backups
      - ${DOCKER_DATA}/media:/media
      - ${DOCKER_DATA}/certs:/certs
      - /var/run/docker.sock:/var/run/docker.sock
      - ${DOCKER_DATA}/custom-templates:/templates
    env_file:
      - .env

volumes:
  database:
    driver: local

networks:
  authentik:
  web:
    external: true

Authentik Compose .env file

DOCKER_DATA=/path/to/my/data

PG_PASS=my pg pass
AUTHENTIK_SECRET_KEY=my authentik secret key

AUTHENTIK_IMAGE=ghcr.io/goauthentik/dev-server
AUTHENTIK_TAG=gh-next
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-next


############## EMAIL STUFF #################
# SMTP Host Emails are sent to
AUTHENTIK_EMAIL__HOST=localhost
AUTHENTIK_EMAIL__PORT=25
# Optionally authenticate (don't add quotation marks to you password)
AUTHENTIK_EMAIL__USERNAME=
AUTHENTIK_EMAIL__PASSWORD=
# Use StartTLS
AUTHENTIK_EMAIL__USE_TLS=false
# Use SSL
AUTHENTIK_EMAIL__USE_SSL=false
AUTHENTIK_EMAIL__TIMEOUT=10
# Email address authentik will send from, should have a correct @domain
AUTHENTIK_EMAIL__FROM=authentik@localhost

Application labels

labels:
      - traefik.http.routers.app.rule=Host(`app.mydomain.com`)
      - traefik.http.routers.app.tls.certresolver=lets-encrypt
      - traefik.http.routers.app.middlewares=authentik@docker

Authentik Embedded Outpost configuration

Name: authentik Embedded Outpost
Type: Proxy
Integration: Local Docker connection (Docker Service-Connection)
Applications:
  - app (https://app.mydomain.com)
  - app2 (https://app-2.mydomain.com)
Configuration:
  - log_level: debug
  - authentik_host: https://auth.mydomain.com
  - docker_network: null
  - container_image: null
  - docker_map_ports: true
  - authentik_host_browser: https://auth.mydomain.com
  - object_naming_template: ak-outpost-%(name)s
  - authentik_host_insecure: false

Authentik Provider configuration

Name: app
Authorization flow: Authorize Application (default-provider-authorization-implicit-consent)
Forward auth (single application)
External host: https://app.mydomain.com
Token validity: hours=24

Authentik Application configuration

Name: app
Slug: app
Provider: app
Policy engine mode: ANY

With this configuration, going to https://app.mydomain.com returns:

{
	"Message": "no app for hostname",
	"Host": "auth.mydomain.com",
	"Detail": "Check the outpost settings and make sure 'auth.mydomain.com' is included."
}

@Jafner
Copy link

Jafner commented Feb 1, 2022

If I switch the values of AUTHENTIK_HOST and traefik.http.middlewares.authentik.forwardauth.address: from https://auth.mydomain.com to http://authentik-server:9000, I no longer hit that error, and instead get a broken version of the application's page at https://app.mydomain.com/akprox/start.

@Jafner
Copy link

Jafner commented Feb 1, 2022

After giving the outpost the higher priority in traefik everything works now. Thank you so much.

@winterolym Can you share what your config looks like now? Particularly the compose for Authentik
Do you have a dedicated container for ForwardAuth proxy, or are you using the main server with embedded proxy outpost?

@agrimpelhuber
Copy link
Author

@Jafner , I'll try to help you to clean this up a much as I can. Let's see how far we get. I'll start from the top:

Compose File

As far as I can tell, you are mixing up the Authentic Server and the Forward Proxy. Not a goo idea, no matter whether you want to use the embedded one, or a manual setup. The Forward Auth Proxy needs a separate container, separate image etc.

So IMHO, remove those lines:

      AUTHENTIK_HOST: https://auth.jafner.net
      #AUTHENTIK_HOST: http://authentik-server:9000
      AUTHENTIK_HOST_BROWSER: https://auth.jafner.net
[...]
      traefik.http.routers.authentik-auth.rule: Host(`app.mydomain.dev`) && PathPrefix(`/akprox/`)
      traefik.http.routers.authentik-auth.entrypoints: websecure

Next, fix your middleware. Don't use the FQDN, but the internal docker hostname on the common network to communicate.

Not
traefik.http.middlewares.authentik.forwardauth.address: https://auth.mydomain.com/akprox/auth/traefik

But something like
traefik.http.middlewares.authentik.forwardauth.address=http://ak-outpost-forward-auth:9000/akprox/auth/traefik

For an embedded proxy, the server name is generated from the naming scheme. "ak-outpost-" is the standard prefix, "forward-auth" is, in my example, generated from my Outpost's name "Forward Auth". Since you might have a problem (mis-)using the "authentik Embedded Outpost" (see below), that's something to consider once your proxy container is running, and has an internal hostname on the docker network.

.env file

Scrap the Dev-Server / -image lines, the config should work with the current version. Get rid of

AUTHENTIK_IMAGE=ghcr.io/goauthentik/dev-server
AUTHENTIK_TAG=gh-next
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-next

Application

Just a question: Without the middleware enabled, your application runs OK?

Authentik Application / Provider / Outpost

That looks a bit like a mess-up. Provider and application look OK for me, even though I have no experience with single application forward auth (yet).

My main point, however: Did you really modify the "authentik Embedded Outpost" that was already there?
In case you did: Don't! :-)
You should create a separate outpost for the forward auth. I suggest you revert the "authentik Embedded Outpost" to the default set-up with no application checked, and a configuration like:

log_level: info
authentik_host: http://localhost:9001
docker_network: null
container_image: null
docker_map_ports: true
kubernetes_replicas: 1
kubernetes_namespace: default
authentik_host_browser: ""
object_naming_template: ak-outpost-%(name)s
authentik_host_insecure: false
kubernetes_service_type: ClusterIP
kubernetes_image_pull_secrets: []
kubernetes_disabled_components:
  - deployment
  - secret
kubernetes_ingress_annotations: {}
kubernetes_ingress_secret_name: authentik-outpost-tls

And then build an extra proxy outpost, enable your application in its configuration, and tweak the rest of the parameters. When you save the configuration, Authentik should bring up a separate forward auth proxy container in docker.

I don't expect forward auth to be working at that time. I guess one of the mayor steps will be the configuration of the docker network, so Traefik, Authentik, the forward proxy and your application can communicate. But that's something for tomorrow, after you have cleaned up a bit.

@Jafner
Copy link

Jafner commented Feb 1, 2022

I won't be able to get back to my homelab until tomorrow, but I really appreciate the guidance. I'll be implementing your recommendations and reporting back

@sungyoonc
Copy link

@Jafner Sorry for the late reply just woke up. I'm using local docker intergration in outpost to make a dedicated docker container.

Docker Compose

My authentik container docker compose file is these labels added to the server container.

- "traefik.enable=true"
- "traefik.http.routers.authentik.entrypoints=http"
- "traefik.http.routers.authentik.priority=1"
- "traefik.http.routers.authentik.rule=Host(`authentik.domain.tld`) || Host(`sso.domain.tld`)"
- "traefik.http.routers.authentik.middlewares=redirect-https@file"
- "traefik.http.routers.authentik-secure.entrypoints=https"
- "traefik.http.routers.authentik-secure.priority=1"
- "traefik.http.routers.authentik-secure.rule=Host(`authentik.domain.tld`) || Host(`sso.domain.tld`)"
- "traefik.http.routers.authentik-secure.tls=true"
- "traefik.http.routers.authentik-secure.tls.certresolver=cloudflare"
- "traefik.http.routers.authentik-secure.tls.domains[0].main=domain.tld"
- "traefik.http.routers.authentik-secure.tls.domains[0].sans=*.domain.tld"
- "traefik.http.routers.authentik-secure.middlewares=secured@file"
- "traefik.http.routers.authentik-secure.service=authentik"
- "traefik.http.services.authentik.loadbalancer.server.port=9000"
- "traefik.docker.network=proxy"

I've set the priority to 1 so the automatically created outpost could have a higher priority at all times. (Becasue traefik calculates priority with rules length)

Provider

I'm using Forward auth (domain level)

Authentication URL: https://sso.domain.tld
Cookie domain: domain.tld

Outpost

I didn't change much in outpost. I created a new outpost with

Name: Traefik - Outpost
Type: Proxy
Application: domain.tld (https://sso.domain.tld)
log_level: info
docker_labels: null
authentik_host: https://sso.domain.tld
docker_network: proxy
container_image: beryju/authentik-proxy:latest
docker_map_ports: false
kubernetes_replicas: 1
kubernetes_namespace: default
authentik_host_browser: ""
object_naming_template: ak-outpost-%(name)s
authentik_host_insecure: false
kubernetes_service_type: ClusterIP
kubernetes_image_pull_secrets: []
kubernetes_disabled_components: []
kubernetes_ingress_annotations: {}
kubernetes_ingress_secret_name: authentik-outpost-tls

Changed configurations:
authentik_host: https://sso.domain.tld
docker_network: proxy Traefik communicates with other container in this network. You don't need to worry about this.
container_image: beryju/authentik-proxy:latest Because the default image isn't compatible with arm64
docker_map_ports: false Because I can access the outpost with http://ak-outpost-traefik-outpost:9000

Middleware

I'm using a config.yml.

http:
  middlewares:
    authentik:
      forwardAuth:
        address: http://ak-outpost-traefik-outpost:9000/akprox/auth/traefik
        trustForwardHeader: true
        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

@agrimpelhuber
Copy link
Author

agrimpelhuber commented Feb 2, 2022

@winterolym 👍 : Funny, it turns out that the source of your problem was exactly the same as mine - Authentik core server/host running under two subdomains, and the long rule messing up Traefik's priorities.

Host(`auth.mydomain.com`) && PathPrefix(`/akprox`) #Lower Priority
Host(`auth.mydomain.com`) || Host(`login.mydomain.com`) #Higher Priority

@BeryJu, as a suggestion, could the "normal" Authentik server, when generating the message right at the top of my inital post, identify itself? That way, we might have spotted the confusion between the two hosts earlier. I'm wondering why the core host answers requests to /akprox/start at all - backwards compatibility?

@sungyoonc
Copy link

I think the core-host.tld/akprox/start is linked to the embedded outpost. Also, I think you should go to the discussions tab for further discussion.

@agrimpelhuber
Copy link
Author

@winterolym, good point. Should have suggested it myself when I closed the issue and marked it solved. Sorry!
@Jafner, since it turned out that this wasn't a real issue, we should discuss your configuration issues in the discussions.

@zizounetgit
Copy link

Is that one of those who finally found a solution could update the project: https://github.com/goauthentik/testing-setups
with a full exemples
i am a litte lost about the outpost and dont understant id i need to use the embeded on or if i need to create a new one

@agrimpelhuber
Copy link
Author

@zizounetgit , I can only speak for my setup, but the example you linked (I refer specifically to the docker-compose file) explicitly pulls up the proxy as a separate docker container / service. That is not how my setup works: In my setup, I have only configured Authentik (with authentik, -worker, -redis and -db) in my docker-compose file. The whole runs behind a dockerized Traefik installation.

Then, when I configure the forward auth provider in Authentik's GUI, Authentik is intelligent enough (actually WOW!) to automatically (automagically) pull up a separate Forward Auth proxy container in docker, AND register it with Traefik. That's what this whole ticket here was about: The automatic setup didn't work properly, routes' priorities in Traefik got mixed up, but that should be fixed by now.

Actually: There seems to be an option where you configure the Forward Auth proxy manually. However, I wouldn't know how to keep Authentik from automatically creating its own proxy container automatically.

@steRnbear87
Copy link

@zizounetgit , I can only speak for my setup, but the example you linked (I refer specifically to the docker-compose file) explicitly pulls up the proxy as a separate docker container / service. That is not how my setup works: In my setup, I have only configured Authentik (with authentik, -worker, -redis and -db) in my docker-compose file. The whole runs behind a dockerized Traefik installation.

Then, when I configure the forward auth provider in Authentik's GUI, Authentik is intelligent enough (actually WOW!) to automatically (automagically) pull up a separate Forward Auth proxy container in docker, AND register it with Traefik. That's what this whole ticket here was about: The automatic setup didn't work properly, routes' priorities in Traefik got mixed up, but that should be fixed by now.

Actually: There seems to be an option where you configure the Forward Auth proxy manually. However, I wouldn't know how to keep Authentik from automatically creating its own proxy container automatically.

Can you walk me through your whole set up if you don't mind? Me and some friends are having issues setting up authentik(domain level forward auth) with traefik. Tried using the setups above to no luck.

@agrimpelhuber
Copy link
Author

agrimpelhuber commented May 5, 2022

Hi @steRnbear87 , sorry for the late reply, my notifications don't work reliably.

Before I go into too much detail, do you know these 2 sources?

This whole issue developed out of the fact that I configured my Forward Auth according to the documentation, but it didn't work as expected. From my view, the most important step was #2180 (comment) about the priorities.

Since then, my Forward Auth has been running flawlessly, so I expect my original configuration, plus #2180 (comment), minus the improvements Authentik may have received during the meantime, should do the trick.

If it doesn't and you get stuck, open a new "question" issue and mention me, before this one gets to clogged with off-topic stuff.

Cheers!

@evulhotdog
Copy link

I was able to find a solution to this, at least in kubernetes.

I had to modify the middleware url in the traefik config to point directly to the outpost service instead of the generic authentik one.

So the correct value was this for me: http://ak-outpost-authentik-embedded-outpost.default.svc.cluster.local:9000/outpost.goauthentik.io/auth/traefik

Check exactly what your service name is, as it might be different depending on what you named your outpost, what helm chart you're using, etc.

So my whole middleware config is:

---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: authentik
  namespace: default
spec:
  forwardAuth:
    address: http://ak-outpost-authentik-embedded-outpost.default.svc.cluster.local:9000/outpost.goauthentik.io/auth/traefik
    trustForwardHeader: true
    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

And my service being like so:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-radarr
  namespace: default
  annotations:
    ingress.kubernetes.io/ssl-redirect: "true"
    traefik.ingress.kubernetes.io/router.middlewares: default-redirect@kubernetescrd,default-authentik@kubernetescrd
spec:
  tls:
    - secretName: wildcard-domain-le-prod-tls
      hosts:
      - radarr2.domain.tld
  rules:
    - host: radarr2.domain.tld
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: radarr-svc
                port:
                  number: 80
---
apiVersion: v1
kind: Service
metadata:
  name: radarr-svc
  namespace: default
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 7878
  selector:
    app: radarr

@tedstriker
Copy link
Contributor

To prevent some of you from getting mad over configuring the forward auth, I'd like to share an insight with you.
If you run Traefik in networkmode: host, you can't access the outpost as advised via its internal name, because Traefik can't join any docker networks. So there's no internal name resolution and you must use the outposts external address. The resulting error is well known at this point.

{
	"Message": "no app for hostname",
	"Host": "auth.mydomain.com",
	"Detail": "Check the outpost settings and make sure 'auth.mydomain.com' is included."
}

The reason for it is, because Traefik doesn't trust itself regarding forwarded headers. But if you add the ip of the host (neither 127.0.0.1 nor it's internal docker ip) which runs Traefik, to Traefiks static config under trusted ips the error is gone and authentication/authorization works.

e.g.
Docker Host IP: 192.168.0.100

entryPoints:
  web:
    address: ":80"
    forwardedHeaders:
      trustedIPs:
        - "192.168.0.100"

@Mahadevaswamys1999
Copy link

to resolve the issue you need to add you need to add http://ip-address:9000/outpost.goauthentik.io/auth/traefik instead of http://authentik_server:9000/outpost.goauthentik.io/auth/traefik. the issue will be resolved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

9 participants