traefik-forward-auth
traefik-forward-auth copied to clipboard
Correct usage of whitelist in rule
Hi, I have a setup where users have to authenticate using their gitlab account. I use a group token so that all users from that group can login. Now I want to make a subpath accessible only for a single user of that group via a mail address. Following my understanding of the docs I added the following to the config:
rule.myrule.action = auth
rule.myrule.rule = Host(`example.org`) && PathPrefix(`/static/private`)
rule.myrule.whitelist = [email protected]
This should make the rule available only for the user [email protected]. However, when I try to access example.org/static/private/index.html I can login with a mail address [email protected] and I am still being forwarded successfully to the "private" page. So it seems I did the configuration wrong or the whitelist is not serving its purpose. The logs suggest that the rule is used successfully:
traefik-forward-auth | time="2021-05-26T19:03:42Z" level=debug msg="Authenticating request" cookies="[_forward_auth=DF-e5KkUC_****************-5g=|1622099022|]" handler=Auth host=example.org method=GET proto=https rule=myrule
source_ip=******* uri=/static/private/index.html
traefik-forward-auth | time="2021-05-26T19:03:42Z" level=debug msg="Allowing valid request" handler=Auth host=example.org method=GET proto=https rule=myrule source_ip=10.56.75.225 uri=/static/private/index.html
What is going wrong here?
EDIT
When looking at the requests in the logs I don't see any username or mail address. Shouldn't that be requested using the user endpoint? I have set
providers.generic-oauth.user-url = https://gitlab.example1.org/api/v4/users/
but I see no request happening with that url at all. Is the mail address supposed to be in the cookie above or where is the traefik-forward-auth supposed to get that address from? On gitlab site, my email address is public.
That's odd, can you post your full traefik-forward-auth config file and swarm/kubernetes config?
Sure, this is essentially my (anonymized) traefik-forward-auth config:
secret = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
providers.google.client-id = dummy
providers.google.client-secret = dummy
default-provider = generic-oauth
providers.generic-oauth.auth-url = https://gitlab.example.org/oauth/authorize
providers.generic-oauth.token-url = https://gitlab.example.org/oauth/token
providers.generic-oauth.user-url = https://gitlab.example.org/api/v4/users/
providers.generic-oauth.client-id = 0a359e03e0cc807beafxxxxxxxxxxxxxxxxx7d6d00306f8f687ec92165c9740c
providers.generic-oauth.client-secret = fc77e2041afefb6xxxxxxxxxxxxxxxxxx8c9f7ab450242da77ad217a5bdf9d63
insecure-cookie = false
cookie-domain = mysite.example.org
log-level = debug
rule.myrule.action = auth
rule.myrule.rule = Host(`mysite.example.org`) && PathPrefix(`/static/org/private`)
rule.myrule.whitelist = [email protected]
Everyone from the gitlab group should be able to access mysite.example.org but mysite.example.org/static/org/private subpaths sould be only available to me ([email protected]).
The corresponding minimal docker-compose file:
services:
reverse-proxy:
image: traefik:v2.4
container_name: "traefik"
command:
- "--api=true"
- "--api.dashboard=true"
- "--log.level=DEBUG"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=web"
- "--providers.file.directory=/etc/traefik/dynamic_conf"
- "--providers.file.watch=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.middlewares=traefik-forward-auth"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /etc/ssl/private/:/certs/:ro
- ./traefik_dyn.yml:/etc/traefik/dynamic_conf/conf.yml:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`mysite.example.org`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.tls=true"
networks:
- "web"
restart: unless-stopped
traefik-forward-auth:
image: thomseddon/traefik-forward-auth:2.2.0
container_name: "traefik-forward-auth"
secrets:
- credentials
environment:
CONFIG: /run/secrets/credentials
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik-forward-auth.rule=PathPrefix(`/_oauth`)"
- "traefik.http.routers.traefik-forward-auth.entrypoints=websecure"
- "traefik.http.routers.traefik-forward-auth.tls=true"
- "traefik.http.middlewares.traefik-forward-auth.forwardauth.address=http://traefik-forward-auth:4181"
- "traefik.http.middlewares.traefik-forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User"
- "traefik.http.services.traefik-forward-auth.loadbalancer.server.port=4181"
networks:
- "web"
restart: unless-stopped
nginx:
image: nginx:alpine
container_name: "nginx"
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx.rule=(Host(`mysite.example.org`) && Path(`/`)) || (Host(`mysite.example.org`) && PathPrefix(`/static`))"
- "traefik.http.routers.nginx.entrypoints=websecure"
- "traefik.http.routers.nginx.middlewares=add-context"
- "traefik.http.routers.nginx.tls=true"
- "traefik.port=80"
- "traefik.http.middlewares.add-context.redirectregex.regex=^https:\\/\\/([^\\/]+)\\/?$$"
- "traefik.http.middlewares.add-context.redirectregex.replacement=https://$$1/static/index.html"
# - "traefik.http.routers.nginx.middlewares=traefik-forward-auth"
volumes:
- "/srv/homer:/usr/share/nginx/html/"
- "/share/docs/:/usr/share/nginx/html/static/docs/"
- "/share/org/:/usr/share/nginx/html/static/org/private/"
networks:
- "web"
secrets:
credentials:
name: oauth2_crededentials
file: ./secrets/oauth.ini
networks:
web:
external: true
Thanks for your help!
I'm hitting the same thing right now with basically the same rule configuration. Whitelist is just being completely ignored.
I resolved this issue, I was using an "allow" rule with "whitelist" when I should have used "auth"
This is a documentation bug from the README:
# Allow [email protected] to `/janes-eyes-only`
rule.two.action = allow
rule.two.rule = Path(`/janes-eyes-only`)
rule.two.whitelist = [email protected]
Unfortunately I cannot find this to resolve the issue. In my config above (first post), I have the action set to auth correctly. I have the feeling that it doesn't get the mail information from the gitlab provider but I don't see why this would result in access.
Did you have time to look into this @thomseddon?