Skip to content

traefik#

description:#

Traefik is an application for routing web traffic to applications. This is enabled by using labels on docker containers which define the rules to be applied. Traefik takes care of generating certificates via the Lets Encrypt service. (so easy) This ensures an HTTPS session is setup between the browser and the server ensuring traffic over the internet is encrypted.

traefik image

source and credits: docker image - traefik:v2.2 from Traefiklabs

usage#

Traefik runs in the background and continuously monitors the docker configuration for changes and applies these in real time. In addition to routes, Traefik allows middleware and services to be configured to manipulate traffic messages or routing. A dashboard is available on a local url: http://localhost:9090 or externally on https://traefik.example.com

I use Traefik in conjunction with Authelia which has been configured as a middleware for the authentication of requests. Authelia allows for a comprehensive and flexible configuration for any combination of Domain, User, Group, Network, Resource and for each, allows for the following authentication levels: Deny access, Bypass authentication, 1FA (single factor ie: password), 2FA (two factor authentication ie: token via email or mobile app. or a physical key like Yubikey).

I have implemented it to enforce single factor authentication for traffic originating within the home network, and 2FA for traffic coming from the internet.

Note: some applications (Traefik is one) make two types of requests. The first being the original request from the URL of the browser. The second are XHR calls from within the code that is running in the browser. The XHR calls don't generally handle a re-authentication (HTTP 302 and 401) request in an effective manner and give the impression the application has stopped responding. (ie: links don't work) Pressing F5 in the browser will refresh the entire web page (and trigger a new login authentication.)

In my configuration, I use 1FA for the dashboard URL in my home network and 2FA when accessed from the internet. For the XHR calls using the /api path, I use bypass in my home network and 2FA from the internet.

dependencies#

Routing web requests from the internet ports 80(http) and 443(https) to the Traefik container. This can be achieved by configuring a port forwarding rule in your internet router. Traefik then routes the requests using rules to the appropriate applications.

preparation: create a docker network web for routing traffic within docker between containers.

installation#

create a stack in Portainer with the following code. (note: this will create the necessary labels for Traefik to generate the ssl certificate and route to the web server.

 version: '2'

 services:

   traefik:  
     container_name: traefik2  
     image: traefik:v2.2  
     command:  
       - "--log.level=ERROR"  
       - "--accessLog=true"  
       - "--accessLog.filePath=/traefik.log"  
       - "--accessLog.bufferingSize=100"  
       - "--accessLog.filters.statusCodes=400-499"

       - "--api.insecure=false"  
       - "--providers.docker=true"  
       - "--providers.docker.exposedByDefault=false"  
       - "--entryPoints.web.address=:80"  
       - "--entryPoints.websecure.address=:443"  
       - "--entryPoints.traefik.address=:8080"  
       - "--certificatesResolvers.le.acme.email=[redacted]"  
       - "--certificatesResolvers.le.acme.storage=acme.json"  
       - "--certificatesResolvers.le.acme.tlsChallenge=true"  
       - "--certificatesResolvers.le.acme.httpChallenge=true"  
       - "--certificatesResolvers.le.acme.httpChallenge.entryPoint=web"  
       - "--metrics.prometheus=true"  
       - "--metrics.prometheus.entryPoint=metrics"  
       - "--entryPoints.metrics.address=:8082"  
   restart: unless-stopped  
   ports:  
       - 89:80  
       - 9443:443
       - 9090:8080
       - 9092:8082
   networks:
       - web
   volumes:
       - /var/run/docker.sock:/var/run/docker.sock:ro
       - /var/lib/docker/volumes/myconfigs/_data/traefik/traefik.log:/traefik.log
       - /var/lib/docker/volumes/myconfigs/_data/traefik/acme.json:/acme.json
   environment:
       - TZ=Australia/Melbourne
   labels:
       - traefik.enable=true

       # Redirect all HTTP to HTTPS permanently
       - traefik.http.routers.http_catchall.rule=HostRegexp(`{any:.+}`)
       - traefik.http.routers.http_catchall.entrypoints=web
       - traefik.http.routers.http_catchall.middlewares=https_redirect
       - traefik.http.middlewares.https_redirect.redirectscheme.scheme=https
       - traefik.http.middlewares.https_redirect.redirectscheme.permanent=true

       # Traffic dashboard (with Authelia login)  Browser link: <https://traefik.example.com/dashboard/> 
       - traefik.http.routers.traefik.rule=Host(`traefik.example.com`) && PathPrefix(`/dashboard/`)
       - traefik.http.routers.traefik.entrypoints=websecure
       - traefik.http.routers.traefik.tls=true
       - traefik.http.routers.traefik.tls.certresolver=le
       - traefik.http.routers.traefik.service=api@internal
       - traefik.http.routers.traefik.middlewares=authelia@docker

       # Dashboard /api path calls with Authelia login for public network an Authelia bypass for internal network. 
       - traefik.http.routers.traefikapi.rule=PathPrefix(`/api/`) && HeadersRegexp(`Referer`,`https://traefik.example.com/dashboard/`)  
       - traefik.http.routers.traefikapi.entrypoints=websecure  
       - traefik.http.routers.traefikapi.tls=true  
       - traefik.http.routers.traefikapi.tls.certresolver=le 
       - traefik.http.routers.traefikapi.service=api@internal
       - traefik.http.routers.traefikapi.middlewares=authelia@docker

 networks:  
    web:  
       external:  
         name: web