docker-traefik icon indicating copy to clipboard operation
docker-traefik copied to clipboard

Google Oauth invalid_client with Docker Secrets

Open jo-me opened this issue 5 years ago • 9 comments

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"

jo-me avatar Oct 12 '20 18:10 jo-me

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 :)

iamfinky avatar Oct 13 '20 13:10 iamfinky

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/

iamfinky avatar Oct 13 '20 14:10 iamfinky

This is one of the most commonly overlooked steps in docker secrets: https://www.smarthomebeginner.com/traefik-docker-security-best-practices/

SimpleHomelab avatar Oct 13 '20 14:10 SimpleHomelab

Well, that's what I tried, too...

But

  1. 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.

  2. 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 avatar Oct 13 '20 18:10 jo-me

@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.

SimpleHomelab avatar Oct 13 '20 19:10 SimpleHomelab

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 :)

iamfinky avatar Oct 13 '20 20:10 iamfinky

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.

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.

  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-auth
  1. 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.

rsrramirez avatar Oct 23 '20 17:10 rsrramirez

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?

bxlouis avatar Feb 08 '21 15:02 bxlouis

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_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.

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-auth
1. 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.

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?

Briare0s avatar Apr 12 '21 17:04 Briare0s