Skip to main content

Traefik DevOps Guide: Infrastructure & Routing

Questa guida Γ¨ destinata al team DevOps per configurare e manutenere correttamente il Gateway Traefik dell'infrastruttura Visla.

Tabella di Routing e Sicurezza​

MicroservizioTraefik Rule (PathPrefix)Middleware (StripPrefix)App RootStato
auth/api/authβœ… /api/auth/STANDARD + RateLimit
billing/api/billingβœ… /api/billing/Double Security + RateLimit (Webhooks Public)
client-logs/api/client-logsβœ… /api/client-logs/Double Security
commands/api/commandsβœ… /api/commands/Double Security
devices/api/devicesβœ… /api/devices/Double Security
device-simulator/api/simulatorβœ… /api/simulator/Double Security
events/api/eventsβœ… /api/events/Double Security
geofences/api/geofencesβœ… /api/geofences/Double Security
notifications/api/notificationsβœ… /api/notifications/Double Security
positions/api/positionsβœ… /api/positions/Double Security
sharing/api/sharingβœ… /api/sharing/Double Security
websocket/api/websocketβœ… /api/websocket/Double Security

Legenda:

  • Double Security: Richiede validazione JWT sia a livello di Gateway (forward-auth) che all'interno del servizio.
  • RateLimit: Limitazione delle richieste per prevenire abusi (100 req/s).
  • Block Internal: Tutte le rotte /internal/* sono bloccate per le richieste esterne.

Configurazione Dinamica (dynamic.yml)​

Questa configurazione definisce i middleware riutilizzabili (@file).

http:
middlewares:
# 1. CORS Headers - Gestione sicurezza cross-origin
cors-headers:
headers:
accessControlAllowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"]
accessControlAllowHeaders: ["Content-Type", "Authorization", "X-Requested-With", "Accept", "Origin"]
accessControlAllowOriginList: ["https://app.vislagps.com"]
accessControlAllowCredentials: true
accessControlMaxAge: 100
addVaryHeader: true

# 2. Security Headers - Best practice per header di sicurezza
security-headers:
headers:
frameDeny: true
contentTypeNosniff: true
browserXssFilter: true

# 3. Block Internal - ⚠️ Protezione endpoint sensibili
block-internal:
replacePathRegex:
regex: "^.*/internal/.*$"
replacement: "/blocked-internal-access"

# 4. Forward Auth - Centralized Auth Validation (Double Security)
forward-auth:
forwardAuth:
address: "http://auth:8081/validate"
trustForwardHeader: true

# 5. Rate Limiting - Supporta 100 req/s con burst di 50
rate-limit:
rateLimit:
average: 100
burst: 50

# 6. GZip Compression
compress:
compress: {}

Listato Completo Label Microservizi​

Di seguito i blocchi di label pronti per il copia-incolla per ogni singolo servizio.

πŸ” Auth Service​

labels:
- "traefik.enable=true"
- "traefik.http.routers.auth.rule=PathPrefix(`/api/auth`)"
- "traefik.http.routers.auth.entrypoints=web"
- "traefik.http.services.auth.loadbalancer.server.port=8081"
- "traefik.http.routers.auth.middlewares=auth-strip,cors-headers@file,security-headers@file,block-internal@file,rate-limit@file,compress@file"
- "traefik.http.middlewares.auth-strip.stripprefix.prefixes=/api/auth"

πŸ’³ Billing​

labels:
- "traefik.enable=true"
- "traefik.http.routers.billing.rule=PathPrefix(`/api/billing`)"
- "traefik.http.routers.billing.middlewares=billing-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file,rate-limit@file,compress@file"
- "traefik.http.routers.billing-webhooks.rule=PathPrefix(`/api/billing/webhooks`)"
- "traefik.http.routers.billing-webhooks.middlewares=billing-strip,cors-headers@file,security-headers@file,rate-limit@file,compress@file"
- "traefik.http.routers.billing-webhooks.priority=2000"
- "traefik.http.middlewares.billing-strip.stripprefix.prefixes=/api/billing"
- "traefik.http.services.billing.loadbalancer.server.port=8088"

πŸ“± Client Logs​

labels:
- "traefik.enable=true"
- "traefik.http.routers.client-logs.rule=PathPrefix(`/api/client-logs`)"
- "traefik.http.routers.client-logs.entrypoints=web"
- "traefik.http.routers.client-logs.middlewares=client-logs-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file"
- "traefik.http.middlewares.client-logs-strip.stripprefix.prefixes=/api/client-logs"
- "traefik.http.services.client-logs.loadbalancer.server.port=8087"

πŸ•ΉοΈ Commands​

labels:
- "traefik.enable=true"
- "traefik.http.routers.commands.rule=PathPrefix(`/api/commands`)"
- "traefik.http.routers.commands.middlewares=commands-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file"
- "traefik.http.middlewares.commands-strip.stripprefix.prefixes=/api/commands"
- "traefik.http.services.commands.loadbalancer.server.port=8084"

πŸ›°οΈ Devices​

labels:
- "traefik.enable=true"
- "traefik.http.routers.devices.rule=PathPrefix(`/api/devices`)"
- "traefik.http.routers.devices.middlewares=devices-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file"
- "traefik.http.middlewares.devices-strip.stripprefix.prefixes=/api/devices"
- "traefik.http.services.devices.loadbalancer.server.port=8082"

πŸ§ͺ Device Simulator​

labels:
- "traefik.enable=true"
- "traefik.http.routers.simulator.rule=PathPrefix(`/api/test-devices`) || PathPrefix(`/api/simulator`)"
- "traefik.http.routers.simulator.entrypoints=web"
- "traefik.http.services.simulator.loadbalancer.server.port=8000"
- "traefik.http.routers.simulator.middlewares=simulator-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file"
- "traefik.http.middlewares.simulator-strip.stripprefix.prefixes=/api/test-devices,/api/simulator"

πŸ”” Events​

labels:
- "traefik.enable=true"
- "traefik.http.routers.events.rule=PathPrefix(`/api/events`)"
- "traefik.http.routers.events.middlewares=events-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file"
- "traefik.http.middlewares.events-strip.stripprefix.prefixes=/api/events"
- "traefik.http.services.events.loadbalancer.server.port=8092"

πŸ—ΊοΈ Geofences​

labels:
- "traefik.enable=true"
- "traefik.http.routers.geofences.rule=PathPrefix(`/api/geofences`)"
- "traefik.http.routers.geofences.middlewares=geofences-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file"
- "traefik.http.middlewares.geofences-strip.stripprefix.prefixes=/api/geofences"
- "traefik.http.services.geofences.loadbalancer.server.port=8091"

βœ‰οΈ Notifications​

labels:
- "traefik.enable=true"
- "traefik.http.routers.notifications.rule=PathPrefix(`/api/notifications`)"
- "traefik.http.routers.notifications.middlewares=notifications-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file"
- "traefik.http.middlewares.notifications-strip.stripprefix.prefixes=/api/notifications"
- "traefik.http.services.notifications.loadbalancer.server.port=8086"

πŸ“ Positions​

labels:
- "traefik.enable=true"
- "traefik.http.routers.positions.rule=PathPrefix(`/api/positions`)"
- "traefik.http.routers.positions.middlewares=positions-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file"
- "traefik.http.middlewares.positions-strip.stripprefix.prefixes=/api/positions"
- "traefik.http.services.positions.loadbalancer.server.port=8090"

🀝 Sharing​

labels:
- "traefik.enable=true"
- "traefik.http.routers.sharing.rule=PathPrefix(`/api/sharing`)"
- "traefik.http.routers.sharing.middlewares=sharing-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file"
- "traefik.http.middlewares.sharing-strip.stripprefix.prefixes=/api/sharing"
- "traefik.http.services.sharing.loadbalancer.server.port=8085"

πŸ”Œ WebSocket​

labels:
- "traefik.enable=true"
- "traefik.http.routers.websocket.rule=PathPrefix(`/api/websocket`)"
- "traefik.http.routers.websocket.entrypoints=web"
- "traefik.http.services.websocket.loadbalancer.server.port=8090"
- "traefik.http.routers.websocket.middlewares=websocket-strip,cors-headers@file,security-headers@file,block-internal@file,forward-auth@file"
- "traefik.http.middlewares.websocket-strip.stripprefix.prefixes=/api/websocket"

Riferimento Rapido Porte e Middleware​

ServizioPorta InternaMiddleware Comuni (Inclusi in tutti)Middleware Specifici (Aggiuntivi)
auth8081strip, cors, security, block-internalrate-limit@file, compress@file
devices8082strip, cors, security, block-internalforward-auth@file
positions8090strip, cors, security, block-internalforward-auth@file
billing8088strip, cors, security, block-internalforward-auth@file, rate-limit@file, compress@file
sharing8085strip, cors, security, block-internalforward-auth@file
commands8084strip, cors, security, block-internalforward-auth@file
notifications8086strip, cors, security, block-internalforward-auth@file
events8092strip, cors, security, block-internalforward-auth@file
geofences8091strip, cors, security, block-internalforward-auth@file
websocket8090strip, cors, security, block-internalforward-auth@file
client-logs8087strip, cors, security, block-internalforward-auth@file
simulator8000strip, cors, security, block-internalforward-auth@file

[!NOTE] I Middleware Comuni (abbreviati in tabella) corrispondono a: {service}-strip, cors-headers@file, security-headers@file, block-internal@file.


Guida ai Middleware e Label​

Label di Base​

  • traefik.enable=true: Fondamentale. Senza questo, Traefik ignora completamente il container.
  • entrypoints=web: Specifica il punto di ingresso HTTP (porta 80).
  • loadbalancer.server.port: Indica la porta interna su cui gira il microservizio.

PathPrefix & StripPrefix​

  • PathPrefix(/api/service): Dice a Traefik di instradare al microservizio tutte le chiamate che iniziano con quel prefisso.
  • StripPrefix: Rimuove il prefisso prima di passare la richiesta all'app. In questo modo l'app puΓ² rispondere su / invece di dover gestire /api/service/.

cors-headers@file​

Essenziale per le Web App. Definisce quali domini possono chiamare le API e quali header sono permessi.

security-headers@file​

Attiva protezioni standard del browser come X-Frame-Options: DENY (evita clickjacking) e X-Content-Type-Options: nosniff.

forward-auth@file​

Il cuore della Double Security. Prima di inoltrare la richiesta, Traefik chiama auth:8081/validate. Se il token non Γ¨ valido, Traefik blocca la richiesta con un 401Unauthorized senza disturbare il microservizio.

block-internal (REGEX)​

regex: "^.*/internal/.*$"
replacement: "/blocked-internal-access"

Spiegazione: Molti dei nostri microservizi hanno rotte /internal/ destinate solo alla comunicazione tra server. Questo middleware usa una regex che identifica qualsiasi stringa contenente /internal/ e sostituisce l'intero path con uno inesistente, impedendo l'accesso dall'esterno anche se la rotta esiste nel codice.

rate-limit@file​

Protegge le risorse critiche (login, pagamenti) da attacchi brute-force o script automatici, limitando il numero di richieste al secondo per IP.