My solution to this was slightly different. I had to set dns_search: .
and that removes the search order entirely from resolv.conf inside the containers. Thanks for the write-up though!
I would like to share my experiences with setting up OAuth in case it helps others.
Firstly, thanks for a great website! I originally used instructions from here Ultimate Smart Home Media Server with Docker and Ubuntu 18.04 - Basic | SHB but there was no OAuth guide, so I found your site whilst searching for ways to implement OAuth for my Docker environment, and this seemed to be the answer I was looking for. I don’t have a Swarm yet, though that’s next on my to-do list.
I decided to use Google for OAuth, but came across a problem when configuring my second subdomain (which was srv1.example.com - the first, portainer.example.com worked great). The error message was “redirect_uri_mismatch”.
My interpretation of the instructions suggested that we needed to create multiple “OAuth 2.0 client IDs”, one for each subdomain. Each client ID had it’s own ID and secret key which I stored in separate .env files, e.g. portainer.env and srv1.env.
For each client ID on Google, I specified the following URL within the “Authorised redirect URIs” field:
https://portainer.example.com/oauth2/callback
, changing portainer to srv1 on the second client ID.
When I then visited srv1.example.com, clicked on the Google login button, it gave that redirect error message. It gave a URL to check the settings, but this took me to the portainer Client ID, which is why it complained the redirect URLs didn’t match.
Given that the author was using Github for OAuth, I thought I’d try that instead. Again, I set up multiple OAuth Apps
, but this time it worked! For some reason Github works with multiple subdomains, but Google doesn’t.
Not being one to give up, I spent a while reading up on various ways to make OAuth work with multiple subdomains. Whilst there was no direct example for a working solution, one comment somewhere suggested using multiple redirect URIs within a single Client ID on Google. Turns out this worked!
So, my solution is as follows (apologies if this is what the original intention was, I just misunderstood the instructions):
- Add each subdomain as a new
Authorised redirect URIs
entry within a single Client ID. Note thatAuthorised JavaScript origins
just has my own domain, e.g. https://example.com.
- Create a single
master.env
file with the Google ID and Secret key and use this in each proxy container - Here is my docker-compose.yml to show how I’ve linked it all together. Note that the
traefik.enable=true
andtraefik.backend=portainer_proxy
labels were missing in the examples on this site, which meant that traefik didn’t setup the redirect - probably due to not using swarm mode yet.
#Portainer - WebUI for Containers
portainer:
image: portainer/portainer
hostname: portainer
container_name: portainer
restart: always
command: -H unix:///var/run/docker.sock
ports:
- "9000:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${USERDIR}/docker/portainer/data:/data
- ${USERDIR}/docker/shared:/shared
environment:
- TZ=${TZ}
networks:
- internal
portainer_proxy:
image: a5huynh/oauth2_proxy
env_file: ${USERDIR}/docker/env/master.env
hostname: portainer_proxy
container_name: portainer_proxy
restart: always
networks:
- internal
- traefik_proxy
labels:
- traefik.enable=true
- traefik.backend=portainer_proxy
- traefik.frontend.rule=Host:portainer.${DOMAINNAME}
- traefik.docker.network=traefik_proxy
- traefik.port=4180
- traefik.frontend.headers.SSLRedirect=true
- traefik.frontend.headers.STSSeconds=315360000
- traefik.frontend.headers.browserXSSFilter=true
- traefik.frontend.headers.contentTypeNosniff=true
- traefik.frontend.headers.forceSTSHeader=true
- traefik.frontend.headers.SSLHost=${DOMAINNAME}
- traefik.frontend.headers.STSIncludeSubdomains=true
- traefik.frontend.headers.STSPreload=true
- traefik.frontend.headers.frameDeny=true
volumes:
- ${USERDIR}/docker/oauth_proxy/authenticated-emails.txt:/authenticated-emails.txt
command: |
-cookie-secure=false
-upstream=http://portainer:9000
-redirect-url=https://portainer.${DOMAINNAME}
-http-address=http://0.0.0.0:4180
-email-domain=${DOMAINNAME}
-provider=google
-authenticated-emails-file=/authenticated-emails.txt
networks:
traefik_proxy:
external:
name: traefik_proxy
default:
driver: bridge
internal:
# driver: overlay - this didn't work in my non-swarm docker setup
ipam:
config:
- subnet: 172.16.11.0/24
I do have another issue in that I can’t log into portainer when going via my external domain. Keeps saying invalid credentials, yet if I browse to my internal IP, it logs in fine. Something to do with the OAuth redirect as it was working fine before then…
This looks great, thank you! I’ll try it out
I had the same issue with portainer, I think it has to do with how it prompts for auth with an http 401…
D
Ah good to know it’s not just me with Portainer. I also have the same problem with Home Assistant - the new user authentication system with 0.77.3 just returns the login prompt after submitting my credentials. Using the legacy API login, it ends up just showing the HA logo with a spinning circle and a message saying loading data.
If I disable OAuth proxy on both HA and Portainer, they both log in with no issues. It’s really odd and frustrating as it’s preventing me using this much preferred OAuth login method.
I’ve not been able to find any other posts with the same issue so far as I think the combination of Oauth2, Let’s Encrypt with Traefik, and Docker, are few and far between so far.
I wondered if it’s specific to bitly’s oauth2_proxy project, or a5huynh’s Docker version of it (though there’s no mention of portainer in GitHub issues). I’m going to try another Docker image just in case, or perhaps build my own for now.
P.S. Interesting use of Grafana with HA - I’ll have to look into that!
Just to confirm it’s not the container - this one had the same issues. Docker Hub
So, it’s either an issue with bitly’s code, or its the way Portainer and HA implement user authentication…
Edit - I see now, its the way Portainer and HA implement user authentication, and it seems nothing can be done for now. No matter, I can still use OAuth for the rest of the containers, and just connect to the rest via my home VPN server.
With HomeAssistant, it’s due to the use of websockets, which oauth_proxy doesn’t support yet
D