Securitzant serveis amb traefik

Com ja vam fer en un article anterior, encriptarem el tràfic cap als nostres serveis. La diferència és que aquest cop, ho farem amb traefik, un reverse proxy i load balancer molt flexible pensat per funcionar amb Docker.

Mostrarem com gestionar el tràfic HTTP i HTTPS, emetre certificats TLS amb Let’s Encrypt i fer accessibles els nostres contenidors amb dominis personalitzats, a més d’explicar com funciona aquest proxy invers i les configuracions que pot tenir.

Aquesta guia està pensada per a usuaris de Linux amb coneixements bàsics de Docker que vulguin millorar la seguretat i l’automatització del seu servidor casolà o de producció.

Copiem el docker-compose de la web oficial:

docker-compose

  traefik:
    image: traefik:v3.5
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Creem la xarxa:

bash

$ docker network create proxy

I afegim modificacions al docker-compose.yaml, incloent també la nova xarxa creada.

docker

  traefik:
    image: traefik:v3.5
    container_name: traefik
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080" volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.yaml:/etc/traefik/traefik.yaml:ro
      - ./certs:/var/traefik/certs
    networks:
      - proxy
    restart: unless-stopped

networks:
  proxy:
    external: true

En aquest arxiu hem afegit el port 443 pel tràfic web xifrat (HTTPS), l’arxiu de configuració que ara crearem i un directori pels certificats TLS (que haurien de tenir permiosos 600). A més, hem afegit el contenidor a la xarxa “proxy” que hem creat abans i la hem afegit a l’arxiu.

A més, hem tret els commands, ja que són paràmetres de configuració que gestionarem des de l’arxiu de configuració del propi traefik.

Traefik té 2 tipus de configuració diferents:

  • Dynamic routing config

    Conté la configuració de routing, serveis, middleware i certificats. La rep dels proveïdors (docker en aquest cas) i es recarrega en calent. En aquest tutorial només veurem la part de routing, redireccionant adreces DNS a serveis.

  • Startup config o static config

    És la configuració de traefik que configurarem ara, i es pot definir amb una de les tres maneres:

    1. Arxiu de configuració

    2. Via CLI

    3. Amb variables d’entorn

En aquest tutorial farem la static config amb un arxiu de configuració:

Crearem l’arxiu de configuració traefik.yaml amb el següent contingut:

traefik

global:
  checkNewVersion: false
  sendAnonymousUsage: false

log:
  level: DEBUG

api:
  dashboard: true
  insecure: true

entryPoints:
  web:
    address: :80
  websecure:
    address: :443

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

Si estem en entorn de producció el millor seria securitzar la dashboard, en aquest tutorial la deixarem com a insecure.

Ara podem desplegar el contenidor i ja podrem entrar a la dashboard:

bash

$ docker compose up -d

I si anem al navegador i posem la IP amb el port 8080 podrem veure la dashboard:

Ara ja podem configurar els docker labels a les aplicacions per fer-les accessibles a traefik

Ara toca configurar el servei. En aquest cas he triat Jellyfin perquè és amb el que he fet la prova i, al utilitzar un port diferent que el 80 per defecte, podem veure que cal fer per això.

Per aquesta configuració (la dynamic config) hi ha varis paràmetres diferents per filtrar. En aquest cas utilitzarmem el paràmetre Host, on posarem el domini des del que volem accedir.

Agafarem la configuració de Jellyfin del docker-compose.yaml i hi afegirem un apartat labels amb el següent contingut:

docker

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.jellyfin.rule=Host('jellyfin-prova.bit4cora.com')"
  - "traefik.http.routers.jellyfin.entrypoints=web"

A més, haurem d’afegir el contenidor del servei a la xarxa que hem creat abans:

docker

networks:
  - proxy

Si ara anem a la dashboard de traefik, a l’apartat HTTP Routers ens apareixerà la redirecció:

I amb això, si posem el domini que hem especificat a hosts al navegador, ens haura d’aparèixer la interfície web de jellyfin via http, confirmant que funciona la configuració.

Ara que ja tenim el reverse proxy per respondre a un domini via http, podem ampliar la configuració per habilitar l’https.

Primer modificarem l’arxiu traefik.yaml, i li afegirem el següent:

traefik

certificatesResolvers:
  myresolver:
    acme:
      email: correu@exemple.com
      storage: /var/traefik/certs/acme.json
      httpChallenge:
        entryPoint: web

Això és la manera d’aconseguir el certificat. Es pot fer via dns challenge, amb una API token del proveïdor (com pot ser Cloudflare) o per http challenge, com és aquest cas. Requereix tenir el port 80 obert contra el servidor perquè es pugui fer la petició.

L’apartat storage és on es guardaran els certificats.

Ara passarem a la configuració del servei:

Al docker-compose.yaml, canviarem el label entrypoint=websecure (per habilitar el port 443) i afegirem tls.certresolver:

docker

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.jellyfin.rule=Host('jellyfin-prova.bit4cora.com')"
  - "traefik.http.routers.jellyfin.entrypoints=websecure"
  - "traefik.http.routers.jellyfin.tls.certresolver=myresolver"
  - "traefik.http.services.jellyfin.loadbalancer.server.port=8096"

I ara, farem:

bash

$ docker compose down jellyfin
$ docker compose up jellyfin -d
$ docker restart traefik

Per recarregar la configuració de jellyfin de l’arxiu docker-compose.yaml i la configuració de traefik del seu traefik.yaml.

I amb això, traefik hauria de demanar el certificat i, al intentar entrar via web al nostre domini hauriem de poder entrar per https i sense cap mena d’error de connexió no segura:

A més, si volem que traefik redirigeixi tot tràfic http a http, podem afegir a traefik.yaml, dins l’apartat d’entryPoints:

yaml

entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https

Amb aquesta configuració, Traefik ens permet gestionar de manera senzilla dominis i certificats per als nostres serveis Docker, eliminant la necessitat de configurar Nginx o Caddy manualment.

A més, amb una sola xarxa i un únic fitxer docker-compose.yml, podem desplegar serveis segurs, escalables i fàcilment gestionables.

I fins aquí el post d’avui. Si t’ha semblat útil pots deixar un comentari i compartir-lo. Ens veiem al següent!