Home » Home Server » Google OAuth with Traefik – Secure SSO for Docker Services

Google OAuth with Traefik – Secure SSO for Docker Services

written by Seth October 31, 2019

Tired of all your docker services having their own authentication system? For those that don’t, do you hate Traefik’s basic auth? Then, read on to setup up Google OAuth with Traefik. Enjoy the convenience of secure single-sign-on for your Docker services.

I was so excited to find that thomseddon’s image, Traefik Forward Auth, could secure my Docker services. This image provides a lightweight forward authentication using Traefik Google OAuth2.

Why use Google OAuth for Docker Services?

Google OAuth2 enables you to use your Google account to sign in to your services. Using Google OAuth with Traefik will allow you to whitelist accounts, implement Google’s 2FA, as well as provide a Single Sign-On (SSO) to your services. This not only offers the convenience of not having sign-in frequently but also improves security.

For this reason, our smart home setup, which uses several docker services, recently enabled Google OAuth SSO for many of the services.

If you’re already running Docker based Media Server behind a Traefik reverse proxy, then this is a logical next step. Adding Google OAuth with Traefik for your Docker services will be an easy step.

Note that this guide is for Traefik v1.7.16. Traefik 2 is already out but Traefik 1 still works great. A Traefik 2 guide is being worked on.

How to check if my login credentials are already compromised?

With security and privacy in mind, our goal for this Docker Google OAuth guide is to limit access only to authorized users. Therefore, we need to start by looking at the quality of our credentials, and whether those credentials are already prone to attack.

Hackers will use the usernames and passwords from data breaches in their attacks, so I strongly recommend that you go to Have I Been Pwned and check both your emails and passwords. Have I Been Pwned has built a database of information that has been compromised during a data breach, and this site will compare your credentials to those in the database.

Now you may be asking – How do I know that I can trust this website with such sensitive info?!

The trick to comparing these values securely is that the data is stored as an SHA-1 hash, and an abbreviation of your data is checked against that list. Learn more by checking out this video for a great explanation and walk-through of how it all works.

Protecting Docker Services with Traefik’s Basic Auth

Adding the basic authentication that Traefik provides is the simplest way to protect your docker services.

In our previous guide we walked through how to use .htpasswd login credentials by adding the label:

- "traefik.frontend.auth.basic.users=${HTTP_USERNAME}:${HTTP_PASSWORD}"

For a single service, this can be useful, but I found it quickly became inconvenient and tedious once I had to sign-in to multiple services and for every browser session.

Recommended Guides:

After implementing Traefik forward authentication, I now only need to sign-in once, and by implementing Google OAuth with Traefik I can add 2-factor authentication (2FA), making this method much more secure and convenient than using basic auth.

Configure Google OAuth SSO for Docker

What is OAuth?

OAuth is an open standard for access delegation, commonly used as a way for Internet users to grant websites or applications access to their information on other websites but without giving them the passwords. This mechanism is used by companies such as Amazon, Google, Facebook, Microsoft, and Twitter to permit users to share information about their accounts with third-party applications or websites.” – Wikipedia

Before configuring Google OAuth for Docker using Traefik, how it all fits together.

How does Google OAuth with Traefik work?

Google OAuth with Traefik acts like a gatekeeper for your services, allowing or denying access after checking for an authorized cookie in your browser. To sum it up, the process goes something like this:

  1. A request is made for our Host ( e.g.: https://traefik.example.com)
  2. The request is routed by our DNS provider to our WAN IP, where ports 80 and 443 are forwarded to the Traefik container.
  3. Traefik sees the incoming request and recognizes that Forward Auth is defined in the labels for that Host, therefore the request is forwarded to the Traefik Forward Auth container.
  4. The container then checks to see if the browser already has an authorized cookie. If there’s no cookie, the request is sent to Google’s OAuth2 Authorization Server.
  5. After successfully logging in to Google, the request is sent to the redirect URI identified for the Web Application (https://oauth.example.com/_oauth).
  6. An authorized cookie is then saved in the browser, and the user is sent to the backend service.

The next time that this browser tries to access a service protected by OAuth, the cookie will be recognized and the user will be taken to their service, without being prompted to sign in!

Traefik Forward Auth with Google OAuth - Process Flow

Traefik Forward Auth with Google OAuth – Process Flow

This process happens very quickly, and once your browser receives the cookie you’ll forget you’ve even enabled Google OAuth with Traefik!

Note: The Traefik Forward Auth image uses OpenID Connect (OIDC), which is an authentication layer on top of the OAuth 2.0 protocol. This image currently supports Google as the OIDC provider, however it seems that OIDC Support for other providers is coming soon.

With the basics taken care of let’s move on to setting Google OAuth Traefik forward authentication for our Docker services.

How do I setup OAuth?

Setting up Google OAuth for Docker using Traefik, involves 3 steps: 1) create DNS records, 2) configure Google OAuth2 Service and 2) modify Docker compose files and adding the Traefik labels to activate forward authentication.

So, first, we’ll need to configure the Google OAuth service. Let’s set up all of the prerequisites now:

Step 1: Create DNS Records

Start by creating a new CNAME DNS record for our OAuth service (Google will redirect to this address after authentication). For clarity, throughout this guide we’ll use the domain name “example.com”.

Set the DNS record as oauth.example.com. The pictures below a screenshot from Cloudflare. Depending on your DNS provider, things may look different for you but essentially have the same content.

Create DNS Records for Google OAuth2

Create DNS Records for Google OAuth2

Note that DNS records can take several ours to propagate and become active.

Step 2: Configure Google OAuth2 Service

With the DNS records created, let us move on the configuring Google OAuth.

Step 2a: Create a Google Project

We need to create a Google Project that will contain our Web App, Consent Screen, and Credentials. This process is very similar to what is described in our guide on setting up Google Assistant for Home Assistant.

Navigate to the Google Cloud Developers Console and make sure that you are signed into the correct Google account that you want to use (This will normally be your own e-mail address).

Note: Sign out of other active Google accounts to make sure that the correct account is used at each step.

If prompted, you’ll need to agree to the Google Cloud Platform Terms of Service in order to use their API:

Google Terms of Service

Google Terms of Service

It’s free to use Google’s OAuth service, so we can Dismiss the free trial for now. Click on Select a project and New project.

Create a new Project for OAuth

Create a new Project for OAuth

Enter a unique name to identify the project, such as “Traefik Authentication”. Click Create.

Google OAuth New Project Details

Google OAuth New Project Details

Step 2b: Create OAuth Credentials

Now that our project has been created, we need to create a client ID and client secret in order to authenticate with Google. Choose our Traefik Authentication project, and under the Navigation menu select APIs & Services > Credentials. Click on Create Credentials > OAuth client ID.

Navigate to Create OAuth Client ID

Navigate to Create OAuth Client ID

Step 2c: Configure the Consent Screen

Once you click OAuth Client ID, you will see the note to configure the consent screen as shown below. A configuring a consent screen is required before proceeding.

Configure Consent Screen for Google OAuth2

Configure Consent Screen for Google OAuth2

If you’re not automatically prompted, select the OAuth consent screen from the left panel.

Choose a name for your app, such as “Traefik Auth”, then under the Authorized domains section enter your domain, for instance, “example.com”. Make sure that you press Enter to add it, and then click Save.

Create OAuth Consent Screen

Create OAuth Consent Screen

After hitting Save, you will return back to creating an OAuth Client ID.

Step 2d: Create the OAuth client ID

Now select the Web Application type and enter a name for your web application, such as “Traefik”. In addition, you’ll need to enter your Authorized redirect URI as https://oauth.example.com/_oauth. Make sure that you press Enter to add it, and then click Save.

Note: You are only allowed to add redirect URIs that direct to your Authorized Domains. Return to the OAuth consent screen if you need to edit them.
Creating OAuth Client ID

Creating OAuth Client ID

The credentials for our SSO for Docker have been created! Copy and save the client ID and client secret; we’ll need to use them in the next step.

Google OAuth Client Credentials

Google OAuth Client Credentials

Step 3: Setup Traefik Forward Authentication

Now that the OAuth credentials have been configured, the last thing to do is set up the OAuth container. Sign-in to your local machine, or use one of the several awesome SSH clients to sign in remotely.

Recommended Guides:

Make sure to stop Traefik (if necessary), and edit your docker-compose file to add the Traefik labels and OAuth container.

Step 3a: Add Traefik OAuth Container

Open your docker-compose file that was created based on our previous Traefik tutorial and add the following to it.

## OAuth - Forward Authentication
  oauth:
    image: thomseddon/traefik-forward-auth
    container_name: oauth
    hostname: oauth
    restart: always
    networks:
      - default
      - traefik_proxy
    environment:
      PROVIDERS_GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
      PROVIDERS_GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
      SECRET: ${OAUTH_SECRET}
      COOKIE_DOMAIN: ${DOMAINNAME}
      INSECURE_COOKIE: "false"
      AUTH_HOST: oauth.${DOMAINNAME}
      URL_PATH: /_oauth
      WHITELIST: ${MY_EMAIL}
      LOG_LEVEL: info
      LIFETIME: 2592000 # 30 days
    labels:
      traefik.enable: "true"
      traefik.backend: oauth
      traefik.port: 4181
      traefik.frontend.rule: Host:oauth.${DOMAINNAME}
      traefik.frontend.headers.SSLHost: oauth.${DOMAINNAME}
      traefik.docker.network: traefik_proxy
      traefik.frontend.passHostHeader: "true"
      traefik.frontend.headers.SSLForceHost: "true"
      traefik.frontend.headers.customResponseHeaders: X-Robots-Tag:noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex
      traefik.frontend.headers.SSLRedirect: "true"
      traefik.frontend.headers.browserXSSFilter: "true"
      traefik.frontend.headers.contentTypeNosniff: "true"
      traefik.frontend.headers.forceSTSHeader: "true"
      traefik.frontend.headers.STSSeconds: 315360000
      traefik.frontend.headers.STSIncludeSubdomains: "true"
      traefik.frontend.headers.STSPreload: "true"
      traefik.frontend.headers.frameDeny: "true"
      traefik.frontend.auth.forward.address: "http://oauth:4181"
      traefik.frontend.auth.forward.authResponseHeaders: X-Forwarded-User
      traefik.frontend.auth.forward.trustForwardHeader: "true"
Note: The networks block should already be defined as described in our previous guide or else you will face errors. The networks traefik_proxy and default should be already defined in your docker-compose file.

Replace/Configure:

  • Enter the $GOOGLE_CLIENT_ID and $GOOGLE_CLIENT_SECRET we received in the previous step.
  • The $OAUTH_SECRET is used to sign the cookie and should be random. Generate a random secret with:
    openssl rand -hex 16
    

    Alternatively, you may use an online service like this one, to generate your random secret.

    Random OAuth Secret

  • WHITELIST any Google e-mail addresses, separated by commas, that you would like to allow access. Caution: If no e-mail addresses are whitelisted, anyone with a Google account can gain access!

Notice that the URL_PATH is the same path as the Authorized redirect URI (https://oauth.example.com/_oauth).

Stepb 3b: Adding Google OAuth for Docker Services

Alright, let’s test it out! With the OAuth container added to our stack, we can now add the Traefik labels to the rest of the services to enable Traefik forward authentication for them. As an example, let’s replace the basic authentication for Traefik dashboard, defined in our previous Traefik guide, with Google OAuth2.

To accomplish this, add the following 3 traefik labels to the services:

      traefik.frontend.auth.forward.address: "http://oauth:4181"
      traefik.frontend.auth.forward.authResponseHeaders: X-Forwarded-User
      traefik.frontend.auth.forward.trustForwardHeader: "true"

The entire docker-compose for Traefik should look something like this (basic authentication disabled by commenting out with a #):

## Traefik - Reverse Proxy
  traefik:
    image: traefik:v1.7.16
    container_name: traefik
    hostname: traefik
    restart: unless-stopped
    networks:
      - default
      - traefik_proxy
    ports:
      - "80:80"
      - "443:443"
      - "8145:8080"
    domainname: ${DOMAINNAME}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ${USERDIR}/docker/traefik:/etc/traefik
      - ${USERDIR}/docker/shared:/shared
    environment:
      CF_API_EMAIL: ${CLOUDFLARE_EMAIL}
      CF_API_KEY: ${CLOUDFLARE_API_KEY}
    labels:
      traefik.enable: "true"
      traefik.backend: traefik
      traefik.protocol: http
      traefik.port: 8080
      traefik.frontend.rule: Host:traefik.${DOMAINNAME}
      traefik.frontend.headers.SSLHost: traefik.${DOMAINNAME}
      traefik.docker.network: traefik_proxy
      traefik.frontend.passHostHeader: "true"
      traefik.frontend.headers.SSLForceHost: "true"
      traefik.frontend.headers.SSLRedirect: "true"
      traefik.frontend.headers.browserXSSFilter: "true"
      traefik.frontend.headers.contentTypeNosniff: "true"
      traefik.frontend.headers.forceSTSHeader: "true"
      traefik.frontend.headers.STSSeconds: 315360000
      traefik.frontend.headers.STSIncludeSubdomains: "true"
      traefik.frontend.headers.STSPreload: "true"
      traefik.frontend.headers.customResponseHeaders: X-Robots-Tag:noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex
      traefik.frontend.headers.frameDeny: "true"
      traefik.frontend.headers.customFrameOptionsValue: 'allow-from https:${DOMAINNAME}'
#      traefik.frontend.auth.basic.users: '${HTTP_USERNAME}:${HTTP_PASSWORD}'
      traefik.frontend.auth.forward.address: "http://oauth:4181"
      traefik.frontend.auth.forward.authResponseHeaders: X-Forwarded-User
      traefik.frontend.auth.forward.trustForwardHeader: "true"

Save the docker-compose files and update your stack using the docker-compose up -d command as described in our previous docker guide.

Now try to reach Traefik’s dashboard on a web browser. You should be directed to the Google sign-in page:

Google OAuth Sign-in Screen

Google OAuth Sign-in Screen

After signing in using your whitelisted e-mail, you should be sent to your Traefik dashboard. It’s as simple as that!

In other words, Google has given an authorized cookie for our $DOMAINNAME to our web browser. That web browser will remain authorized for any other service that uses the same $DOMAINNAME during the $LIFETIME of the cookie, or until we log out of the account.

Step 3d: Adding OAuth to Other Services

As described previously, you simply need to add the following three labels in order to add OAuth protection to other services:

      traefik.frontend.auth.forward.address: "http://oauth:4181"
      traefik.frontend.auth.forward.authResponseHeaders: X-Forwarded-User
      traefik.frontend.auth.forward.trustForwardHeader: "true"

The auth.forward.address label tells Traefik where to send the request. Here we are taking advantage of Docker’s internal networking, sending the request to our container named oauth at port 4181.

Step 4: Putting Non-Docker Apps behind OAuth

OAuth works great for all docker apps. What if you have some non-docker apps that are running on your docker host or any other system in your network for that matter (eg. PiHole, Webmin, Synology DSM, etc.)?

You can put non-docker apps behind Google OAuth2 as well. All you have to do is to create Traefik rules. You can see my example on GitHub.

So if you have configured Traefik to uses rules folder (in traefik.toml) then create a new file (eg. appname.toml) and add the following to it. Be sure to replace what needs to be replaced.

# Replace APPNAME, LAN-IP, PORT, example.com
[backends]
  [backends.backend-APPNAME]
    [backends.backend-APPNAME.servers]
      [backends.backend-APPNAME.servers.server-APPNAME-ext]
        url = "http://LAN-IP:PORT"
        weight = 0
[frontends]
  [frontends.frontend-APPNAME]
    backend = "backend-APPNAME"
    passHostHeader = true
    [frontends.frontend-APPNAME.routes]
          [frontends.frontend-APPNAME.routes.route-APPNAME-ext]
        rule = "Host:APPNAME.example.com"
    [frontends.frontend-APPNAME.headers]
      SSLRedirect = true
      SSLHost = "APPNAME.example.com"
      SSLForceHost = true
      STSSeconds = 315360000
      STSIncludeSubdomains = true
      STSPreload = true
      forceSTSHeader = true
      frameDeny = true
      contentTypeNosniff = true
      browserXSSFilter = true
      customFrameOptionsValue="allow-from https:example.com"
    [frontends.frontend-APPNAME.auth]
      headerField = "X-WebAuth-User"
      [frontends.frontend-APPNAME.auth.forward]
        address = "http://oauth:4181"
        trustForwardHeader = true
        authResponseHeaders = ["X-Forwarded-User"]

Now any time you access these apps, you should be presented with the Google login.

Limitations of Docker Google OAuth Setup

If everything was so great then why not add Google OAuth2 to all docker services? I’ve found that some services can’t redirect the user to the login screen (such as most mobile apps).

For example, I could not enable Traefik forward authentication using Google OAuth for services like sonarr, radarr, etc. This was not because these services are incompatible. This was because I was using NZB360 app to manage these apps from my smartphone. Traefik Google OAuth interfered with this app being able to connect to the services. In this situation, you can either not use OAuth or start using a browser instead of the smartphone app.

But this problem is not unique to just Google OAuth. You will face the same problem if you enable Traefi’s basic authentication for similar services (eg. Radarr, Sonarr, etc.). Just something to be aware of.

FAQs

What is the difference between OIDC and OAuth?

OIDC or OpenID Connect (OIDC) is a protocol for authentication. It is a set of specifications based on OAuth 2.0, which adds extra features. In essence, OIDC is the authentical protocol while OAuth is the set of specifications for resource access and sharing.

Final Thoughts

Implementing Google OAuth with Traefik forward authentication has been one of the easiest and most secure ways for me to protect my docker services. By whitelisting accounts and implementing Google’s 2FA, I have confidence that I will be the only one that’s able to access those services.

I wrote this article with Traefik v1 in mind. Traefik v2 is already out but Traefik v1 still works great and there are no known issues following this.

Having said that, we will be publishing an updated tutorial for Traefik v2. So stay tuned!

I hope you enjoyed learning about Google OAuth with Traefik for Docker services! If you have any questions feel free to leave a comment below.

IPVanish VPN Exclusive Offer - only $3.25/month:
VPN Guides
Windows, Android, Ubuntu
Kodi OpenVPN
OSMC on RPi
♦ Hide your browsing (no logs), Anonymize Streaming and Downloads
♦ Circumvent Geo/Country Restrictions and access worldwide content
♦ Works on Windows, Mac, Linux, Android, iOS, Router, and more
♦ Money back guarantee - Sign Up Now

Related Articles