The Hotel Hero

Notes by a Sysadmin


Cluster | Philosophy | Stack

Traefik oauth

April 19, 2021 | Cluster

Make a traefik.yml in you project directory:

entryPoints:
  # http redirect to https
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  # https
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt# letsencrypt TLS
certificatesResolvers:
  letsencrypt:
    acme:
      email: yourmail@domain.com
      storage: /etc/traefik/acme/acme.json
      tlsChallenge: {}
      httpChallenge:
        entryPoint: web# listen docker
providers:
  docker:
    exposedByDefault: false
    network: traefik

Then make a directory called "acme": 

mkdir acme

Create the deployment file:

version: "3.8"

services:
  traefik:
    #container_name: traefik
    image: traefik
    restart: always
    stdin_open: true
    tty: true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.yml:/etc/traefik/traefik.yml
      - ./acme:/etc/traefik/acme
    ports:
      - "80:80"
      - "443:443"
  oauth:
    #container_name: oauth
    image: thomseddon/traefik-forward-auth
    restart: always
    stdin_open: true
    tty: true
    environment:
      PROVIDERS_GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
      PROVIDERS_GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
      SECRET: ${SECRET}
      COOKIE_DOMAIN: ${DOMAIN}
      AUTH_HOST: oauth.${DOMAIN}
    labels:
      traefik.http.middlewares.oauth.forwardauth.address: http://oauth:4181
      traefik.http.middlewares.oauth.forwardauth.authResponseHeaders: X-Forwarded-User
      traefik.http.middlewares.oauth.forwardauth.trustForwardHeader: "true"
      ## added by me
      #traefik.http.routers.forward-auth.service: forward-auth-svc
      ## end
      traefik.http.routers.oauth.middlewares: oauth
      traefik.enable: "true"
      traefik.http.routers.oauth.rule: Host(`oauth.${DOMAIN}`)
      traefik.http.routers.oauth.tls: "true"
      traefik.http.routers.oauth.tls.certresolver: letsencrypt
      traefik.http.services.oauth.loadbalancer.server.port: 4181

networks:
  default:
    name: traefik

Create the following environment variables:

DOMAIN=<YOUR-DOMAIN>
GOOGLE_CLIENT_ID=<YOUR-CLIENT-ID>
GOOGLE_CLIENT_SECRET=<YOUR-CLIENT-SECRET>
SECRET=<A-RANDOM-STRING-HERE>

These have to be created at ex. Google. When creating the oAuth client ID make sure that the auth redirect URI is https://oauth.your-domain.com/_oauth

After that you are ready to deploy:

docker stack deploy -c docker-compose.yml traefik

Sample app 1:

This is the least safe way to deploy on Traefik Swarm, I had a lot of issues using this template for single container deployments with multiple containers:

version: "3.8"

services:
  # a not exposed service
  #db:
  #  image: mongo  # a publicly exposed app, using https
  app:
    image: containous/whoami 
    networks:
      - default   # to reeach the db
      - traefik   # to be reached from traefik
    labels:
      # enable traefik and tls using letsencrypt
      traefik.enable: "true"
      traefik.http.routers.app.tls: "true"
      traefik.http.routers.app.tls.certresolver: letsencrypt      
      # serve it on https://app.your-domain.com
      traefik.http.routers.app.rule: Host(`app.2-exchange.com`)  
  # a protected admin panel, accessible using https
  admin:
    image: containous/whoami
    networks:
      - default   # to reeach the db
      - traefik   # to be reached from traefik
    labels:
      # enable traefik and tls using letsencrypt
      traefik.enable: "true"
      traefik.http.routers.admin.tls: "true"
      traefik.http.routers.admin.tls.certresolver: letsencrypt      
      # serve it on https://admin.your-domain.com
      traefik.http.routers.admin.rule: Host(`admin.2-exchange.com`)     
      # protect with oauth
      traefik.http.routers.admin.middlewares: oauth 

# make the traefik network available for these containers
networks:
  traefik:
    external: true

Sample 2:

This seems to be the right way in Swarm mode (the main difference is the label format and the exposed port to the container):

version: "3.8"

services:
  speech2:
    image: romainsah/deepspeech-server:latest 
    networks:
      - traefik
    volumes:
      - /home/user/swarm/traefik2/speech:/opt/deepspeech
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.speech2.tls=true"
      - "traefik.http.routers.speech2.tls.certresolver=letsencrypt"      
      - "traefik.http.routers.speech2.rule=Host(`speech2.2-exchange.com`)"
      - "traefik.http.routers.speech2.entrypoints=websecure"  
      - "traefik.http.services.app.loadbalancer.server.port=8080"

networks:
  traefik:
    external: true


About

I'm a Sysadmin, network manager and cyber security entusiast. The main purpose of this public "notebook" is for referencing repetitive tasks, but it might as well come in handy to others. Windows can not be supported! But all other OS compliant with the POSIX-standard can (with minor adjustments) apply the configs on the site. It is Mac OSX, RHEL and all the Fedora based distros and Debian based (several 100's of OS's), all the BSD distros, Solaris, AIX and HP-UX.

Links