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β
| Microservizio | Traefik Rule (PathPrefix) | Middleware (StripPrefix) | App Root | Stato |
|---|---|---|---|---|
| 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β
| Servizio | Porta Interna | Middleware Comuni (Inclusi in tutti) | Middleware Specifici (Aggiuntivi) |
|---|---|---|---|
| auth | 8081 | strip, cors, security, block-internal | rate-limit@file, compress@file |
| devices | 8082 | strip, cors, security, block-internal | forward-auth@file |
| positions | 8090 | strip, cors, security, block-internal | forward-auth@file |
| billing | 8088 | strip, cors, security, block-internal | forward-auth@file, rate-limit@file, compress@file |
| sharing | 8085 | strip, cors, security, block-internal | forward-auth@file |
| commands | 8084 | strip, cors, security, block-internal | forward-auth@file |
| notifications | 8086 | strip, cors, security, block-internal | forward-auth@file |
| events | 8092 | strip, cors, security, block-internal | forward-auth@file |
| geofences | 8091 | strip, cors, security, block-internal | forward-auth@file |
| websocket | 8090 | strip, cors, security, block-internal | forward-auth@file |
| client-logs | 8087 | strip, cors, security, block-internal | forward-auth@file |
| simulator | 8000 | strip, cors, security, block-internal | forward-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.