authentik icon indicating copy to clipboard operation
authentik copied to clipboard

Traefik ForwardAuth Single-app redirect loop

Open rickyelopez opened this issue 3 years ago • 5 comments

Describe your question/ I'm trying to create an application/provider pair with a managed outpost to protect one of my applications. The application is hosted on mydomain.tld/app, and authentik is at auth.mydomain.tld.

Authentik Traefik labels:

      traefik.enable: true
      traefik.http.routers.authentik.rule: Host(`auth.mydomain.tld`)
      traefik.http.routers.authentik.entrypoints: web-secure
      traefik.http.routers.authentik.tls: true
      traefik.http.routers.authentik.tls.certresolver: tlschallenge
      traefik.http.routers.authentik.priority: 1
      traefik.http.services.authentik.loadbalancer.server.port: 9000
      traefik.http.services.authentik.loadbalancer.healthcheck.path: /-/health/live/

Traefik middleware for the managed outpost:

http:
  middlewares:
      gate-proxy:
        forwardAuth:
          address: "http://ak-outpost-proxy: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

My application has the following Traefik labels:

      traefik.enable: true
      traefik.http.routers.app.rule: Host(`mydomain.tld`) && PathPrefix(`/app`)
      traefik.http.routers.app.tls: true
      traefik.http.routers.app.entrypoints: web-secure
      traefik.http.routers.app.tls.certresolver: tlschallenge
      traefik.http.routers.app.middlewares: gate-proxy@file
      traefik.http.routers.app.priority: 10

Outpost settings that are not still the defaults:

docker_labels:
  traefik.http.routers.ak-outpost-proxy-router.priority: "50"
  traefik.http.routers.ak-outpost-proxy-router.entrypoints: web-secure
  traefik.http.routers.ak-outpost-proxy-router.tls.certresolver: tlschallenge
authentik_host: https://auth.mydomain.tld/
docker_network: traefik-servicenet

The single-application ForwardAuth has the external domain set as https://mydomain.tld/app, and the application as default settings with the slug app.

In a private window (i.e. not logged in) if I navigate to https://mydomain.tld/app I get redirected to the login page. After logging in, it just sits in a redirect loop on this page: image

Logs in the outpost container while this is happening constantly repeat the following lines:

{"app":"app","event":"Found app based direct host match","host":"mydomain.tld","level":"debug","logger":"authentik.outpost.proxyv2","timestamp":"2022-05-08T21:26:35Z"}
{"event":"passing to application mux","host":"mydomain.tld","level":"trace","logger":"authentik.outpost.proxyv2","timestamp":"2022-05-08T21:26:35Z"}
{"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":["en-US,en;q=0.9"],"Cookie":["authentik_proxy=<key here>"],"Sec-Fetch-Dest":["document"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-Site":["none"],"Sec-Fetch-User":["?1"],"Sec-Gpc":["1"],"Upgrade-Insecure-Requests":["1"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"],"X-Forwarded-For":["<my ip>"],"X-Forwarded-Host":["mydomain.tld"],"X-Forwarded-Method":["GET"],"X-Forwarded-Port":["443"],"X-Forwarded-Proto":["https"],"X-Forwarded-Server":["5c80213df6dc"],"X-Forwarded-Uri":["/app"],"X-Real-Ip":["<my ip>"]},"level":"trace","logger":"authentik.outpost.proxyv2.application","name":"app","timestamp":"2022-05-08T21:26:35Z"}
{"event":"traefik forwarded url","level":"trace","logger":"authentik.outpost.proxyv2.application","name":"app","timestamp":"2022-05-08T21:26:35Z","url":"https://mydomain.tld/app"}
{"event":"Redirecting to login","level":"debug","logger":"authentik.outpost.proxyv2.application","name":"app","timestamp":"2022-05-08T21:26:35Z","url":"https://mydomain.tld/outpost.goauthentik.io/start"}
{"event":"/outpost.goauthentik.io/auth/traefik","host":"mydomain.tld","level":"info","logger":"authentik.outpost.proxyv2.application","method":"GET","name":"app","remote":"172.22.0.20:33470","runtime":"1.521","scheme":"","size":89,"status":307,"timestamp":"2022-05-08T21:26:35Z","upstream":"","user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"}

I have read the other issues on GitHub with similar symptoms, but haven't had any luck trying any of those fixes. Any suggestions? Does this have something to do with the fact that I'm using a subdirectory for my app rather than a subdomain?

Version and Deployment (please complete the following information):

  • authentik version: 2022.4.1
  • Deployment: docker-compose

rickyelopez avatar May 08 '22 21:05 rickyelopez

As a test, I spun up another app at app.mydomain.tld as well as a new Application/Provider pair in Authentik, and everything works flawlessly. So I'm guessing this does, in fact, have something to do with the fact that I'm trying to use subdirectories for my apps.

Any suggestions for how I could make this work with subdirectories?

rickyelopez avatar May 09 '22 21:05 rickyelopez

I have found a workaround that will solve for now. I have added related apps to a subdomain appgroup.mydomain.tld but kept their individual paths on that subdomain (i.e. appgroup.mydomain.tld/app). Then I set up an application/provider pair for the appgroup subdomain, and everything appears to work.

rickyelopez avatar May 09 '22 23:05 rickyelopez

I've got a similar issue, redirect loop on apps using traefik @docker configs. I have one app, Pihole that has it's traefik configuration in traefik's config.yml:

http:
  routers:
    pihole:
      rule: Host(`pihole.example.com`)
      entrypoints:
        - https
      middlewares:
        - proxy-outpost
      service:
        - pihole
  
  middlewares:
    ak-pihole:
      forwardauth:
        address: http://proxy-outpost: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

  services:
    pihole:
      loadBalancer:
          servers:
            - url: "http://localhost:8000"

Pi-hole works as expected with the custom proxy outpost proxy-outpost:

proxy-outpost:
    image: ghcr.io/goauthentik/proxy:2022.5.3
    container_name: proxy-outpost
    hostname: proxy-outpost
    restart: unless-stopped
    depends_on:
      - authentik
    environment:
      AUTHENTIK_HOST: http://authentik:9000
      AUTHENTIK_INSECURE: true
      AUTHENTIK_TOKEN: [REDACTED]
      AUTHENTIK_HOST_BROWSER: https://authentik.example.com
    networks:
      - traefik
    labels:
      traefik.enable: true
      traefik.http.routers.proxy-outpost.rule: Host(`pihole.example.com`, `whoami.example.com`) && PathPrefix(`/outpost.goauthentik.io/`)
      traefik.http.routers.proxy-outpost.entrypoints: https
      traefik.http.routers.proxy-outpost.service: proxy-outpost
      traefik.http.services.proxy-outpost.loadBalancer.server.port: 9000

As you can see above, the traefik config for the outpost is fine and is also configured to handle the whoami app:

version: "3.7"
services:
  whoami:
    image: "traefik/whoami"
    container_name: "whoami"
    labels:
      traefik.enable: true
      traefik.http.routers.whoami.rule: Host(`whoami.example.com`)
      traefik.http.routers.whoami.entrypoints: https
      traefik.http.routers.whoami.middlewares: proxy-outpost@file
    networks:
      - traefik

networks:
  traefik:
    external: true

This app causes the redirect loop.

As this is not quite the conclusion that @rickyelopez came to I'm inclined to believe his issue is either actually similar to this or the two issues have a common root cause

yottapanda avatar Jun 04 '22 16:06 yottapanda

I have found a workaround that will solve for now. I have added related apps to a subdomain appgroup.mydomain.tld but kept their individual paths on that subdomain (i.e. appgroup.mydomain.tld/app). Then I set up an application/provider pair for the appgroup subdomain, and everything appears to work.

But isn't that like using Domain level auth? I thought the whole point here was to use Single Application...

lazaroblanc avatar Aug 13 '22 03:08 lazaroblanc

But isn't that like using Domain level auth? I thought the whole point here was to use Single Application...

well yes, but I can still host multiple apps on that domain with different subdirectories. Honestly this worked out pretty nicely for me, but yeah it's not a solution, just a workaround.

rickyelopez avatar Aug 17 '22 06:08 rickyelopez

As I've just found out, if you've got providers set up using Single Application forwarding mode... Switch them to Domain Level in the UI, make sure the Cookie Domain is blank, and then switch them back to Single Application. Apparently even in Single Application mode, previous configurations can still break the cookies!

Celant avatar Dec 06 '22 10:12 Celant

I had the same problem, and indeed it has something to do with switching between "Single Application" and "Domain Level" like @Celant said.

I had a provider configured for "Domain Level", but switched it to "Single Application" afterwards. That somehow corrupted the Provider. I did some switching back and forth but no solution. I only got it working after completely deleting the corrupt Provider, and re-creating it with the same settings. Then everything worked as expected again.

So to recreate: Create a "Domain Level" Provider, and then switch it to "Single Application" afterwards. That should break the Provider and get it into the infinite redirect loop.

Saeverix avatar May 29 '23 21:05 Saeverix

Changing proxy provider modes shouldn't cause this issue anymore, if this behaviour pops up again, feel free to re-open the issue

BeryJu avatar Mar 28 '24 17:03 BeryJu