Secure Services with Traefik Google Oauth2
Secure services with Traefik Google OAuth2
Suyash Singh
Posted by Suyash Singh
on May 7, 2024
Photo by Franck on Unsplash

This guide will show you how to leverage Google OAuth2 to secure services running behind Traefik. This setup is perfect for self hosted services which needs a layer of security without much configuration.

Why OAuth2 and OpenID Connect?

When it comes to security, Oauth2 or OpenID Connect (OIDC) are far more superior than Basic Authentication for the following reasons:

  1. Enhanced Security: OAuth 2.0 provides a more secure way to authorize access to resources by allowing users to grant limited access to their resources without sharing their credentials directly. Instead of sharing usernames and passwords, OAuth 2.0 utilizes tokens that can be scoped and expire, reducing the risk associated with credentials being compromised.
  2. User Consent: OAuth 2.0 allows for user consent to be explicitly obtained before access is granted. Users can authorize specific applications to access their resources for a limited time and with limited scope. This gives users more control over their data and reduces the risk of unauthorized access.
  3. Scalability and Flexibility: OAuth 2.0 is designed to be more scalable and flexible compared to basic authentication. It supports a wide range of authentication scenarios, including web applications, mobile devices, and IoT devices. Additionally, OAuth 2.0 supports multiple authentication flows, such as authorization code flow, implicit flow, client credentials flow, and resource owner password credentials flow, allowing developers to choose the most appropriate flow for their use case.
  4. Third-party Integration: OAuth 2.0 enables seamless integration with third-party services and applications. By standardizing the process of authorization and token exchange, OAuth 2.0 facilitates interoperability between different systems and platforms. This makes it easier for developers to leverage external services and APIs while maintaining security and user privacy.

OIDC builds on OAuth2 and provides a way to retrieve user information from an identity provider (like Google) without exposing credentials. This enhances security and simplifies user management.

What is Traefik-forward-auth?

Traefik-forward-auth is a lightweight container image that integrates seamlessly with Traefik. It acts as a middleware, enabling you to secure your services using various authentication providers, including Google OAuth2.

Traefik excels at reverse proxying and load balancing, while Traefik-forward-auth adds the authentication layer. You can easily integrate both using Docker Compose and Traefik’s label-driven configuration.

Google OAuth2

Google OAuth2 is an authorization framework that allows applications to access user data on Google without requiring users to share their passwords with the application. This offers a secure and convenient login experience for users.

Securing Traefik Dashboard and Whoami Service

In this tutorial, we’ll secure two services:

1. Traefik Dashboard — traefik.yourdomain.in

This is the web interface for managing your Traefik instance. Securing it prevents unauthorized access to your Traefik configuration.

2. Custom Demo Service — whoami.yourdomain.in

This is a placeholder for any service you want to protect behind Traefik’s authentication layer. You can replace it with your actual service in the configuration.

Setting up Google OAuth2 Credentials

  1. Visit the Google Cloud Console.
  2. Create a new project or select an existing one.
  3. Enable the Google OAuth2 API for your project.
  4. Create OAuth credentials (client ID and secret) under “Credentials”. Choose “Web application” as the application type and set the authorized redirect URI to https://auth.yourdomain.in/_oauth (replace with your actual domain).

Creating Traefik-forward-auth Docker Container

 
version: '3.5'
 
services:
 
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
       proxy:
    ports:
      - 80:80
      - 443:443
    environment:
      - CF_API_EMAIL=[[email]]
      - CF_DNS_API_TOKEN=[[token]]
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /home/ubuntu/traefik/traefik.yml:/traefik.yml:ro
      - /home/ubuntu/traefik/acme.json:/acme.json
      - /home/ubuntu/traefik/config.yml:/config.yml:ro
      - /home/ubuntu/traefik/logs:/var/log/traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain.in`)"
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`traefik.yourdomain.in`)"
      - "traefik.http.routers.traefik-secure.middlewares=forward-auth"
      - "traefik.http.routers.traefik.middlewares=forward-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=cloudflare"
      - "traefik.http.routers.traefik-secure.tls.domains[0].main=yourdomain.in"
      - "traefik.http.routers.traefik-secure.tls.domains[0].sans=*.yourdomain.in"
      - "traefik.http.routers.traefik-secure.service=api@internal"
 
  traefik-forward-auth:
     image: thomseddon/traefik-forward-auth:2.1.0
     environment:
       - PROVIDERS_GOOGLE_CLIENT_ID=[[id]]
       - PROVIDERS_GOOGLE_CLIENT_SECRET=[[secret]]
       - SECRET=[[secret]]
       - WHITELIST=email_1@gmail.com
       - WHITELIST=email_2@gmail.com
       - WHITELIST=email_3@gmail.com
       - COOKIE_DOMAINS=yourdomain.in
       - AUTH_HOST=auth.yourdomain.in
       # For initial setup, feel free to remove it if not needed
       - LOG_LEVEL=debug
     networks:
       - proxy
     labels:
       - "traefik.enable=true"
       - "traefik.docker.network=proxy"
       - "traefik.http.routers.auth.rule=Host(`auth.yourdomain.in`)"
       - "traefik.http.routers.auth.entrypoints=https"
       - "traefik.http.routers.auth.tls=true"
       - "traefik.http.routers.auth.tls.domains[0].main=yourdomain.in"
       - "traefik.http.routers.auth.tls.domains[0].sans=*.yourdomain.in"
       - "traefik.http.routers.auth.tls.certresolver=main"
       - "traefik.http.routers.auth.service=auth@docker"
       - "traefik.http.routers.auth.middlewares=forward-auth"
       - "traefik.http.services.auth.loadbalancer.server.port=4181"
       - "traefik.http.middlewares.auth.forwardauth.trustForwardHeader=true"
       - "traefik.http.middlewares.auth.forwardauth.address=http://traefik-forward-auth:4181"
       - "traefik.http.middlewares.auth.forwardauth.authResponseHeaders=X-Forwarded-User"
       - "traefik.http.routers.forward-auth.middlewares=forward-auth"
       - "traefik.http.routers.forward-auth.rule=Host(`auth.yourdomain.in`)"
       - "traefik.http.services.forward-auth.loadbalancer.server.port=4181"
       - "traefik.http.middlewares.forward-auth.forwardauth.address=http://traefik-forward-auth:4181"
       - "traefik.http.middlewares.forward-auth.forwardauth.trustForwardHeader=true"
       - "traefik.http.middlewares.forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User"
 

Note: For the files mentioned under volumes of this spec file /home/ubuntu/traefik/traefik.yml:/traefik.yml:ro
/home/ubuntu/traefik/acme.json:/acme.json
/home/ubuntu/traefik/config.yml:/config.yml:ro
/home/ubuntu/traefik/logs:/var/log/traefik
Please, refer to this post.

The provided YAML snippet defines two services:

  1. traefik: This runs the official Traefik image, configured to use our Traefik configuration file (traefik.yml). Labels define how Traefik exposes services and uses TLS certificates from Cloudflare. To learn more about these follow this post.

  2. traefik-forward-auth: This runs the thomseddon/traefik-forward-auth image. Environment variables configure it to use your Google OAuth2 credentials, whitelist authorized users, set cookie domains, and define the authentication endpoint URL. Labels configure Traefik to expose the traefik-forward-auth service and integrate it with the forward-auth middleware.

Important Labels

  • traefik.http.routers.<router_name>.middlewares=forward-auth — This applies the forward-auth middleware to the specified router, enforcing Google OAuth2 authentication.
  • traefik.http.middlewares.forward-auth.forwardauth.address — This points the middleware to the traefik-forward-auth service for handling authentication.
  • traefik.http.middlewares.forward-auth.forwardauth.trustForwardHeader=true — This trusts headers like X-Forwarded-For for accurate user identification behind proxies.
  • traefik.http.middlewares.forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User — This instructs the middleware to extract the authenticated user’s information from the X-Forwarded-User header after successful authentication.

Conclusion

By following these steps, you can leverage Traefik-forward-auth and Google OAuth2 to secure your Traefik dashboard and other services running behind Traefik. Remember to replace placeholders like domain names, credentials, and email addresses with your specific values. This approach enhances security and provides a convenient login experience for authorized users.