Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save copolycube/dc6a52812fea19361f5aa5b0f3d514dd to your computer and use it in GitHub Desktop.
Save copolycube/dc6a52812fea19361f5aa5b0f3d514dd to your computer and use it in GitHub Desktop.
traefik with oauth2

Todo :

  • find workaround for grafana auto admin role attribution from gitlab group membership
CERT_DOMAIN=domain.tld
SERVER_HOSTNAME=server.domain.tld
trustedIPs=<LB_IP1>,<LB_IP1>
# traefik pilot registration
traefik_pilot_token=<traefik_token>
# Hetzner API key for DNS and certs management
traefik_DNS_cert_Hetzner_API_Key=<hetzner_token>
# umami netdata room
NETDATA_CLAIM_TOKEN=<netdata_token>
NETDATA_CLAIM_ROOMS=<netdata_token_room>
# OAuth2
GITLAB_OAUTH_CLIENT_ID=<gitlab_auth_client_id>
GITLAB_OAUTH_CLIENT_SECRET=<gitlab_auth_secret_id>
# https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview/#generating-a-cookie-secret
# docker run -ti --rm python:3-alpine python -c 'import secrets,base64; print(base64.b64encode(base64.b64encode(secrets.token_bytes(16))));'
# dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_'; echo
OAUTH_SECRET="<cookie_+secret>"
# used for oauth2
DOMAIN=${SERVER_HOSTNAME}
OAUTH2_PROXY_VERSION=v7.2.1
OAUTH2_PROXY_CLIENT_ID=${GITLAB_OAUTH_CLIENT_ID}
OAUTH2_PROXY_CLIENT_SECRET=${GITLAB_OAUTH_CLIENT_SECRET}
OAUTH2_PROXY_COOKIE_SECRET="${OAUTH_SECRET}"
OAUTH2_PROXY_GITLAB_GROUP="group/subgroup"
version: '3.6'
networks:
docker-proxy-internal:
internal:
external:
name: traefik-proxy
volumes:
# Volumes for traefik certificates and logs
traefik-letsencrypt:
traefik-logs:
services:
# proxy to avoid direct connection to the docker socket.
proxy:
image: tecnativa/docker-socket-proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
privileged: true
networks:
- docker-proxy-internal
## Traefik concepts
# Providers : discover the services that live on your infrastructure (their IP, health, ...)
# Entrypoints : listen for incoming traffic (ports, ...)
# Routers : analyse the requests (host, path, headers, SSL, ...). A router is in charge of connecting incoming requests to the services that can handle them.
# Services : forward the request to your services (load balancing, ...). The Services are responsible for configuring how to reach the actual services that will eventually handle the incoming requests.
# Middlewares : may update the request or make decisions based on the request (authentication, rate limiting, headers, ...)
## Traefik : routing services from declared labels
# dashboard : https://traefik.HOST/
# prometheus : https://traefik-metrics.HOST/metrics
traefik:
image: traefik:latest
container_name: "traefik"
command:
- --log.level=DEBUG
- --api.dashboard=true
- --api.insecure=true
# Do not expose all Docker services by default
- --providers.docker=true
- --providers.docker.exposedbydefault=false
#- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- --providers.docker.endpoint=tcp://proxy:2375
- --providers.docker.network=traefik-proxy
# DNS Challenge (domain.tld and *.domain.tld DNS zones are defined there) : hetzner
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- --certificatesresolvers.myresolver.acme.email=postmaster@${SERVER_HOSTNAME}
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.myresolver.acme.dnschallenge=true
- --certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0
- --certificatesresolvers.myresolver.acme.dnschallenge.provider=hetzner
- --certificatesresolvers.myresolver.acme.dnschallenge.resolvers=helium.ns.hetzner.de,hydrogen.ns.hetzner.com,oxygen.ns.hetzner.com
# HTTPS : port 443, with letsencrypt certificates provided by myresolver
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls=true
- --entrypoints.websecure.http.tls.certResolver=myresolver
#- --entrypoints.websecure.http.tls.domains[0].main=${SERVER_HOSTNAME}
#- --entrypoints.websecure.http.tls.domains[0].sans=*.${SERVER_HOSTNAME}
- --entrypoints.websecure.http.tls.domains[0].main=${CERT_DOMAIN}
- --entrypoints.websecure.http.tls.domains[0].sans=*.${CERT_DOMAIN}
- --entrypoints.websecure.http.tls.domains[0].main=${SERVER_HOSTNAME}
- --entrypoints.websecure.http.tls.domains[1].sans=*.${SERVER_HOSTNAME}
# staging letsencrypt (no quotas, but self signed certificates), comment to move to prod
#- --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
#- "--providers.docker.defaultRule=Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
# Redirect HTTP (web) to HTTPS (websecure)
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
# Expose prometheus metrics on port 8082 (rerouted by labels)
- --metrics.prometheus=true
- '--metrics.prometheus.buckets=0.1,0.3,1.2,5.0'
- --metrics.prometheus.addrouterslabels=true
- --metrics.prometheus.addServicesLabels=true
- --metrics.prometheus.addEntryPointsLabels=true
- --entryPoints.metrics.address=:8082
- --metrics.prometheus.entryPoint=metrics
- --metrics.prometheus.manualrouting=true
- --accesslog=true
- --entryPoints.mainnet-mezos-lb.address=:39090
#- --entryPoints.mainnet-mezos-lb.proxyProtocol.insecure
- --entryPoints.mainnet-mezos-lb.proxyProtocol.trustedIPs=${trustedIPs}
- --entryPoints.mainnet-mezos-lb.http.tls=false
- --entryPoints.mainnet-graphic-proxy-lb.address=:49090
#- --entryPoints.mainnet-graphic-proxy.proxyProtocol.insecure
- --entryPoints.mainnet-graphic-proxy-lb.proxyProtocol.trustedIPs=${trustedIPs}
- --entryPoints.mainnet-graphic-proxy-lb.http.tls=false
# Writing Logs to a File
# - "--log.filePath=/logs/traefik.log"
# Writing Logs to a File, format = common or json
#- "--log.format=common"
# Acepted log levels = DEBUG, PANIC, FATAL, ERROR, WARN, and INFO
- "--log.level=DEBUG"
#- "--tracing=true"
- "--pilot.token=${traefik_pilot_token}"
environment:
- HETZNER_API_KEY=${traefik_DNS_cert_Hetzner_API_Key:-notset}
restart: always
ports:
- "80:80"
- "443:443"
- "39090:39090"
- "49090:49090"
#- "8080:8080" default for dashboard, routed to https with labels
#- "8082:8082" set for prometheus, rerouted to http with labels
volumes:
- traefik-letsencrypt:/letsencrypt
- traefik-logs:/logs
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- internal
- docker-proxy-internal
# deploy:
# placement:
# constraints:
# - node.role == manager
labels:
#"traefik.frontend.rule: HostRegexp(`{catchall:.*}`)"
traefik.enable: true
# prometheus exporter
traefik.http.routers.traefikmetrics.rule: Host(`traefik-metrics.${SERVER_HOSTNAME}`)
traefik.http.routers.traefikmetrics.entrypoints: websecure
traefik.http.routers.traefikmetrics.service: prometheus@internal
traefik.http.services.traefikmetrics.loadbalancer.server.port: 8082
traefik.http.routers.traefikmetrics.tls.certresolver: myresolver
# traefik dasboard
traefik.http.routers.api.rule: Host(`traefik.${SERVER_HOSTNAME}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
traefik.http.routers.api.entrypoints: websecure
traefik.http.routers.api.service: api@internal
traefik.http.services.api.loadbalancer.server.port: 8080
traefik.http.routers.api.tls.certresolver: myresolver
traefik.http.middlewares.default-compress.compress: 'true'
traefik.http.middlewares.default-http.redirectScheme.scheme: https
traefik.http.middlewares.default-http.redirectScheme.permanent: 'true'
traefik.http.middlewares.default-https.chain.middlewares: default-compress
whoami-monitoring:
image: "traefik/whoami"
container_name: "whoami-monitoring"
networks:
- internal
- docker-proxy-internal
labels:
traefik.enable: true
traefik.docker.network: traefik-proxy
traefik.http.routers.whoami-monitoring.rule: Host(`whoami22.${DOMAIN?err}`)
traefik.http.routers.whoami-monitoring.middlewares: oauth-signin,oauth-verify,default-https
traefik.http.routers.whoami-monitoring.entrypoints: websecure
traefik.http.services.whoami-monitoring.loadbalancer.server.port: 80
oauth2:
# image: quay.io/pusher/oauth2_proxy:${OAUTH2_PROXY_VERSION}
image: quay.io/oauth2-proxy/oauth2-proxy:${OAUTH2_PROXY_VERSION}
container_name: "oauth"
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--tries=1", "--spider", "http://oauth:4180/ping"]
interval: 30s
timeout: 10s
labels:
ai.ix.expose: 'true'
traefik.enable: 'true'
traefik.http.middlewares.oauth-verify.forwardAuth.address: http://oauth:4180/oauth2/auth
traefik.http.middlewares.oauth-verify.forwardAuth.trustForwardHeader: 'true'
traefik.http.middlewares.oauth-verify.forwardAuth.authResponseHeaders: X-Auth-Request-User,X-Auth-Request-Email,Set-Cookie,X-Auth-User,X-Secret
traefik.http.middlewares.oauth-signin.errors.service: oauth@docker
traefik.http.middlewares.oauth-signin.errors.status: '401'
traefik.http.middlewares.oauth-signin.errors.query: /oauth2/sign_in
traefik.http.routers.oauth.entrypoints: websecure
traefik.http.routers.oauth.rule: Host(`oauth.${DOMAIN?err}`) || PathPrefix(`/oauth2`)
traefik.http.routers.oauth.tls.certResolver: myresolver
traefik.http.routers.oauth.service: oauth@docker
traefik.http.services.oauth.loadbalancer.server.port: '4180'
environment:
# https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview/#environment-variables
OAUTH2_PROXY_PROVIDER: gitlab
OAUTH2_PROXY_GITLAB_GROUP: ${OAUTH2_PROXY_GITLAB_GROUP}
OAUTH2_PROXY_CLIENT_ID: ${OAUTH2_PROXY_CLIENT_ID?err}
OAUTH2_PROXY_CLIENT_SECRET: ${OAUTH2_PROXY_CLIENT_SECRET?err}
OAUTH2_PROXY_COOKIE_DOMAINS: ${DOMAIN?err}
OAUTH2_PROXY_COOKIE_REFRESH: '1h'
OAUTH2_PROXY_COOKIE_SECURE: 'false'
OAUTH2_PROXY_COOKIE_SECRET: ${OAUTH2_PROXY_COOKIE_SECRET?err}
OAUTH2_PROXY_EMAIL_DOMAINS: '*'
OAUTH2_PROXY_FOOTER: '-'
OAUTH2_PROXY_HTTP_ADDRESS: '0.0.0.0:4180'
OAUTH2_PROXY_PASS_BASIC_AUTH: 'false'
OAUTH2_PROXY_PASS_USER_HEADERS: 'true'
OAUTH2_PROXY_REVERSE_PROXY: 'true'
OAUTH2_PROXY_SET_AUTHORIZATION_HEADER: 'true'
OAUTH2_PROXY_SET_XAUTHREQUEST: 'true'
OAUTH2_PROXY_WHITELIST_DOMAIN: '.${DOMAIN?err}'
OAUTH2_PROXY_REDIRECT_URL: "https://oauth.${DOMAIN}/oauth2/callback"
networks:
- internal
- docker-proxy-internal
docker network create traefik-proxy
sudo docker-compose -f docker-compose.yml --env-file .env up -d
sudo docker-compose -f docker-compose.yml --env-file .env logs --tail=50 -tf oauth2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment