Google Oauth invalid_client with Docker Secrets
Hi,
I'm trying to get Google Oauth to work with the forward auth container.
I've tried (almost) exactly like in your repo, but there is an issue with the secrets specified.
They are not replaced during runtime leading to requests going out to google like this: (https://accounts.google.com/o/oauth2/auth?client_id=%2Frun%2Fsecrets%2Fgoogle_client_id&pr...
Secrets generally work for me, I've started to use them in other containers. When I look thomseddon's repo, I can see some issues with people asking about docker secret support: https://github.com/thomseddon/traefik-forward-auth/issues/167 THe answer is that it is not supported and config files should be used instead..
So, has this ever worked for you with docker secrets??
oauth:
container_name: traefik-google-oauth
image: thomseddon/traefik-forward-auth:latest
restart: unless-stopped
networks:
- traefik2
security_opt:
- no-new-privileges:true
environment:
- CLIENT_ID=/run/secrets/google_client_id
- CLIENT_SECRET=/run/secrets/google_client_secret
- SECRET=/run/secrets/google_oauth_secret
- COOKIE_DOMAIN=$DOMAINNAME
- INSECURE_COOKIE=false
- AUTH_HOST=oauth.$DOMAINNAME
- URL_PATH=/_oauth
- WHITELIST_FILE=/run/secrets/google_oauth_whitelist
- LOG_LEVEL=info
- LOG_FORMAT=text
- LIFETIME=2592000 # 30 days
- DEFAULT_ACTION=auth
- DEFAULT_PROVIDER=google
secrets:
- google_client_id
- google_client_secret
- google_oauth_secret
- google_oauth_whitelist
labels:
- "traefik.enable=true"
## HTTP Routers
- "traefik.http.routers.oauth-rtr.entrypoints=https"
- "traefik.http.routers.oauth-rtr.rule=Host(`oauth.$DOMAINNAME`)"
## Middlewares
- "traefik.http.routers.oauth-rtr.middlewares=chain-oauth@file"
## HTTP Services
- "traefik.http.routers.oauth-rtr.service=oauth-svc"
- "traefik.http.services.oauth-svc.loadbalancer.server.port=4181"
Just a quick note: I'm getting the same issue here with the traefik-oauth container, running with docker-compose 1.25.0.
If I find anything, I'll share it here :)
OK, so I found the answer. It turns out there's a standard way of providing environment variables as files. When we use docker secrets, the secrets are files exposed in memory, mounted at /run/secret/your_secret.
To make your container read these as files, you need only add the _FILE suffix to the env var, such:
environment: - CLIENT_ID=/run/secrets/google_client_id
becomes
environment: - CLIENT_ID_FILE=/run/secrets/google_client_id
Tada! \o/
This is one of the most commonly overlooked steps in docker secrets: https://www.smarthomebeginner.com/traefik-docker-security-best-practices/
Well, that's what I tried, too...
But
-
In this (htpcbeginner) repo those secrets are used with CLIENT_ID/CLIENT_SECRET not with _FILE suffix. See https://github.com/htpcBeginner/docker-traefik/blob/09fe127690eadadaddea49689714dac0ccb20ba0/docker-compose-t2.yml#L255 Thats why I tried that after CLIENT_ID_FILE and CLIENT_SECRET_FILE were not working for me. So the repo is probably incorrect in this regard.
-
In thomseddon / traefik-forward-auth repo, the CLIENT_ID/CLIENT_SECRET environment env variables are not listed as supported. It explicitly says "You must set the providers.google.client-id and providers.google.client-secret config options." Which would be via $PROVIDERS_GOOGLE_CLIENT_ID and $PROVIDERS_GOOGLE_CLIENT_SECRET env variables.
With either option I keep getting this in the logs:
time="2020-10-13T18:22:18Z" level=fatal msg="providers.google.client-id, providers.google.client-secret must be set"
@jo-me you are correct. I do not use OAuth. So I did not bother to check the code. I have fixed it now.
However, the way to get secrets working for oauth is different. See this https://github.com/thomseddon/traefik-forward-auth/issues/155#issuecomment-664630985
I have not implemented this yet.
Hey y'all. So, with a bit of jiggery-pokery and invoking the Dark Arts, I've managed to get my OAUTH working. The short, short version is that you can't (currently) use _FILE in environment variables with this upstream package.
Here's my working (yay!) config:
``
oauth:
container_name: oauth
image: thomseddon/traefik-forward-auth:latest
# image: thomseddon/traefik-forward-auth:2.1-arm # Use this image with Raspberry Pi
restart: unless-stopped
networks:
- t2_proxy
security_opt:
- no-new-privileges:true
# Allow apps to bypass OAuth. Radarr example below will bypass OAuth if API key is present in the request (eg. from NZB360 mobile app).
# While this is one way, the recommended way is to bypass authentication using Traefik labels shown in some of the apps later.
# command: --rule.radarr.action=allow --rule.radarr.rule="Headers(X-Api-Key, $RADARR_API_KEY)"
# command: --rule.sabnzbd.action=allow --rule.sabnzbd.rule="HeadersRegexp(X-Forwarded-Uri, $SABNZBD_API_KEY)"
environment:
- CLIENT_ID=$GOOGLE_CLIENT_ID
- CLIENT_SECRET=$GOOGLE_CLIENT_SECRET
- SECRET=$OAUTH_SECRET
- COOKIE_DOMAIN=mydomain.com
- INSECURE_COOKIE=false
- AUTH_HOST=oauth.mydomain.com
- URL_PATH=/_oauth
- WHITELIST=$OAUTH_WHITELIST
- LOG_LEVEL=warn
- LOG_FORMAT=text
- LIFETIME=2592000 # 30 days
- DEFAULT_ACTION=auth
- DEFAULT_PROVIDER=google
secrets:
- google_client_id
- google_client_secret
- oauth_secret
- my_email
labels:
- "traefik.enable=true"
## HTTP Routers
- "traefik.http.routers.oauth-rtr.entrypoints=https"
- "traefik.http.routers.oauth-rtr.rule=Host(oauth.$DOMAINNAME)"
## Middlewares
- "traefik.http.routers.oauth-rtr.middlewares=chain-oauth@file"
## HTTP Services
- "traefik.http.routers.oauth-rtr.service=oauth-svc"
- "traefik.http.services.oauth-svc.loadbalancer.server.port=4181"
`
I've seen an issue related to this in this repo, where they've said it works, but apparently not. I'm not a fan of using env for secrets, but I'm just glad I've got this working :)
Hi all,
This comment stated that secrets work, and after some trial and error I was able to figure it out.
- Create your configuration file (to be used in lieu of the standard secrets file). The configuration file can be a single file (I think I read it can be multiple but haven't tried that) with key value pairs. The key will be based on parameters listed here.
Let's assume we want to populate CLIENT_ID, CLIENT_SECRET, SECRET and WHITELIST. The configuration file would be as follows:
providers.google.client-id=replace_this_value_with_your_google_client_id
providers.google.client-secret=replace_this_value_with_your_google_client_secret
secret=replace_this_value_with_your_secret
whitelist=replace_this_value_with_allowed_email_01
whitelist=replace_this_value_with_allowed_email_02
You can have multiple whitelist emails defined in separate lines. I've tested to ensure this works. I haven't tried multiple emails in a comma delimited list in a single line, but honestly I like it in multiple lines so it's easy to add/remove.
Save this file into your secrets directory (assume it's set in $SECRETSDIR), let's call the file traefik-forward-auth.
- In your docker compose file, in the secrets section (outside of the services section), define where the file is to be retrieved from:
########################### SECRETS
secrets:
traefik-forward-auth:
file: $SECRETSDIR/traefik-forward-auth
- Further down in your docker compose file where you define the oauth service, add the secrets definition and environment setting as follows (I've excluded the rest of the config, just included the relevant lines):
# Google OAuth - Single Sign On using OAuth 2.0 for Traefik 2.2
oauth:
secrets:
- source: traefik-forward-auth
target: /config
environment:
- CONFIG=/config
Unlike the other secrets approach we may be used to (setting distinct secret values in the service's secret section and setting the service's environment values with _FILE=/run... etc), this only depends on the config above.
For the sake of consistency I don't like it, but being able to use a single file for secrets is easy from an editing standpoint.
Theoretically you put most of your config into this file (more than just secrets).
Hope this helps.
Thank you @rsrramirez for this explanation. I tested this and I confirm that it works!
Just a question though, how come this works without specifying "/run/secrets/traefik-forward-auth" at some point, like for other secrets?
Hi all,
This comment stated that secrets work, and after some trial and error I was able to figure it out.
1. Create your configuration file (to be used in lieu of the standard secrets file). The configuration file can be a single file (I think I read it can be multiple but haven't tried that) with key value pairs. The key will be based on parameters listed [here](https://github.com/thomseddon/traefik-forward-auth#overview).Let's assume we want to populate CLIENT_ID, CLIENT_SECRET, SECRET and WHITELIST. The configuration file would be as follows:
providers.google.client-id=replace_this_value_with_your_google_client_id providers.google.client-secret=replace_this_value_with_your_google_client_secret secret=replace_this_value_with_your_secret whitelist=replace_this_value_with_allowed_email_01 whitelist=replace_this_value_with_allowed_email_02You can have multiple whitelist emails defined in separate lines. I've tested to ensure this works. I haven't tried multiple emails in a comma delimited list in a single line, but honestly I like it in multiple lines so it's easy to add/remove.
Save this file into your secrets directory (assume it's set in $SECRETSDIR), let's call the file traefik-forward-auth.
1. In your docker compose file, in the secrets section (outside of the services section), define where the file is to be retrieved from:########################### SECRETS secrets: traefik-forward-auth: file: $SECRETSDIR/traefik-forward-auth1. Further down in your docker compose file where you define the oauth service, add the secrets definition and environment setting as follows (I've excluded the rest of the config, just included the relevant lines):# Google OAuth - Single Sign On using OAuth 2.0 for Traefik 2.2 oauth: secrets: - source: traefik-forward-auth target: /config environment: - CONFIG=/configUnlike the other secrets approach we may be used to (setting distinct secret values in the service's secret section and setting the service's environment values with _FILE=/run... etc), this only depends on the config above.
For the sake of consistency I don't like it, but being able to use a single file for secrets is easy from an editing standpoint.
Theoretically you put most of your config into this file (more than just secrets).
Hope this helps.
This worked for me too, thanks for explaining it like that.
@rsrramirez I want to try something similar in another container config, but that one already has /config defined in the volumes. Adding CONFIG=/config to the environment results in a 'duplicate mountpoint' error. Would you know any work arounds for this?