- Ajouter champ last_update dans le frontmatter de tous les fichiers de documentation - Dates extraites de l'historique git (en excluant le commit de modification des tags) - Résout le problème des dates incorrectes sur Cloudflare Pages (shallow clone) - Projets OpenClassrooms: 22 novembre 2025 - Homelab actuel: 25-30 novembre 2025 - OpenWRT et autres: 2-3 décembre 2025
16 KiB
| sidebar_position | tags | last_update | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 4 |
|
|
Traefik - Reverse Proxy moderne
Traefik est le reverse proxy au cœur de l'infrastructure Docker du homelab. Il gère le routage de toutes les requêtes HTTP/HTTPS vers les conteneurs appropriés, avec gestion automatique des certificats SSL et intégration de la sécurité via CrowdSec.
Architecture globale
L'infrastructure utilise deux instances Traefik distinctes, chacune sur sa propre interface réseau :
- traefik-public (192.168.1.2) : Services publics accessibles sur Internet (*.tellserv.fr)
- traefik-private (192.168.1.3) : Services locaux réservés au réseau interne (*.local.tellserv.fr)
Cette séparation permet :
- Isolation réseau : Les services privés ne sont jamais exposés publiquement
- Sécurité renforcée : Politiques de sécurité différenciées selon l'exposition
- Gestion simplifiée : Chaque instance a sa propre configuration et ses propres règles
Prérequis réseau
La VM hébergeant Traefik dispose de deux NICs (Network Interface Cards) :
- NIC 1 (192.168.1.2) : Interface publique pour traefik-public
- NIC 2 (192.168.1.3) : Interface locale pour traefik-private
Éléments communs aux deux instances
Image et version
Les deux instances utilisent l'image officielle Traefik v3 :
image: traefik:v3
Réseau Docker
Les deux instances se connectent au réseau Docker externe traefik_network qui permet la communication avec tous les conteneurs à proxifier :
networks:
- traefik_network
Ce réseau doit être créé au préalable avec :
docker network create traefik_network
Gestion des certificats SSL
Les deux instances utilisent Let's Encrypt avec le challenge DNS Cloudflare pour générer automatiquement des certificats SSL wildcard.
Avantages du challenge DNS :
- Certificats wildcard (*.tellserv.fr, *.local.tellserv.fr)
- Pas besoin d'exposition HTTP publique pour la validation
- Fonctionne même pour les services internes
Configuration commune :
environment:
- TZ=Europe/Paris
- CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
Le token API Cloudflare doit avoir les permissions :
- Zone / DNS / Edit
- Zone / Zone / Read
Provider Docker
Les deux instances utilisent le provider Docker pour la découverte automatique des services :
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
Traefik surveille les conteneurs et crée automatiquement les routes basées sur les labels Docker.
Configuration dynamique
Chaque instance charge des fichiers de configuration dynamique depuis un répertoire dédié :
volumes:
- ./dynamic-public:/etc/traefik/dynamic:ro # Pour traefik-public
- ./dynamic-private:/etc/traefik/dynamic:ro # Pour traefik-private
Ces fichiers permettent de définir des middlewares, des routers et des services sans redémarrer Traefik.
Dashboard Traefik
Les deux instances exposent leur dashboard via un sous-domaine dédié :
- traefik-public :
traefik-public.local.tellserv.fr - traefik-private :
traefik-private.local.tellserv.fr
Le dashboard permet de visualiser en temps réel :
- Les routers actifs et leurs règles
- Les services détectés
- Les middlewares appliqués
- L'état de santé des backends
Politique de redémarrage
restart: unless-stopped
Les conteneurs redémarrent automatiquement sauf s'ils ont été arrêtés manuellement.
Accès à l'hôte Docker
extra_hosts:
- "host.docker.internal:host-gateway"
Cette configuration permet aux conteneurs Traefik d'accéder à l'hôte Docker via le nom host.docker.internal, utile pour proxifier des services tournant directement sur l'hôte.
Instance traefik-public
Rôle et utilisation
L'instance traefik-public gère tous les services accessibles depuis Internet :
- Applications web publiques
- APIs exposées
- Services authentifiés mais accessibles de l'extérieur
Binding réseau
ports:
- "192.168.1.2:80:80"
- "192.168.1.2:443:443"
Traefik écoute uniquement sur l'IP 192.168.1.2, correspondant à la première NIC de la VM.
Entry points
Port 80 (HTTP) :
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
Redirection automatique de HTTP vers HTTPS pour toutes les requêtes.
Port 443 (HTTPS) :
websecure:
address: ":443"
http:
middlewares:
- crowdsec-bouncer@file
- secheaders@file
- ratelimit@file
transport:
respondingTimeouts:
idleTimeout: 300s
Trois middlewares appliqués par défaut sur tous les services publics :
- crowdsec-bouncer : Blocage des IPs malveillantes détectées par CrowdSec
- secheaders : Headers de sécurité HTTP (HSTS, CSP, etc.)
- ratelimit : Limitation du nombre de requêtes
Middlewares publics
Fichier : dynamic-public/middlewares.yml
ratelimit :
ratelimit:
rateLimit:
average: 100
burst: 50
period: 1s
Autorise en moyenne 100 requêtes/seconde avec des pics jusqu'à 50 requêtes supplémentaires.
secheaders :
secheaders:
headers:
stsSeconds: 31536000
forceSTSHeader: true
Force HSTS (HTTP Strict Transport Security) pendant 1 an, obligeant les navigateurs à toujours utiliser HTTPS.
evasive :
evasive:
rateLimit:
average: 3
burst: 5
period: 1s
Rate limiting strict pour les endpoints sensibles (3 req/s en moyenne, 5 en burst).
Intégration CrowdSec
CrowdSec est un système de détection et prévention d'intrusions communautaire. Traefik-public intègre le bouncer CrowdSec pour bloquer automatiquement les IPs malveillantes.
Middleware CrowdSec (appliqué sur websecure) :
middlewares:
- crowdsec-bouncer@file
Le bouncer interroge l'API CrowdSec locale pour vérifier si l'IP source est bannie. En cas de match, la requête est bloquée avec un code HTTP 403.
Certificats SSL
Stockage des certificats :
volumes:
- ./letsencrypt-public:/letsencrypt
Configuration ACME dans traefik-public.yml :
certificatesResolvers:
cloudflare:
acme:
email: your-email@example.com
storage: /letsencrypt/cloudflare_acme.json
keyType: EC256
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
Les certificats sont automatiquement renouvelés 30 jours avant expiration.
Logging
log:
level: DEBUG
filePath: "/var/log/traefik/traefik.log"
accessLog:
filePath: "/var/log/traefik/access.log"
format: json
Logs stockés dans /var/log/traefik/ sur l'hôte Docker :
- traefik.log : Logs système de Traefik (démarrage, erreurs, recharges)
- access.log : Logs d'accès au format JSON (requêtes HTTP)
Configuration provider Docker
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik_network
- exposedByDefault: false : Les conteneurs ne sont pas automatiquement exposés, il faut explicitement ajouter des labels Traefik
- network: traefik_network : Traefik utilisera ce réseau pour communiquer avec les conteneurs
Exemple de labels Docker
Pour exposer un service via traefik-public :
services:
myapp:
image: myapp:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`app.tellserv.fr`)"
- "traefik.http.routers.myapp.entrypoints=websecure"
- "traefik.http.routers.myapp.tls.certresolver=cloudflare"
- "traefik.http.services.myapp.loadbalancer.server.port=80"
networks:
- traefik_network
Instance traefik-private
Rôle et utilisation
L'instance traefik-private gère tous les services réservés au réseau local :
- Interfaces d'administration (Proxmox, Cockpit)
- Dashboards internes
- Services de monitoring
- Outils de développement
Binding réseau
ports:
- "192.168.1.3:80:80"
- "192.168.1.3:443:443"
Traefik écoute uniquement sur l'IP 192.168.1.3, correspondant à la seconde NIC de la VM.
Entry points
Port 80 (HTTP) :
weblocal:
address: ":80"
http:
redirections:
entryPoint:
to: local
scheme: https
Redirection automatique de HTTP vers HTTPS (entrypoint local).
Port 443 (HTTPS) :
local:
address: ":443"
http:
middlewares:
- localonly@file
Un seul middleware appliqué par défaut : localonly qui restreint l'accès aux IPs locales.
Middlewares privés
Fichier : dynamic-private/middlewares.yml
localonly :
localonly:
ipWhiteList:
sourceRange:
- "127.0.0.1/32"
- "192.168.1.0/24"
- "100.64.0.0/10"
- "172.18.0.0/16"
Liste blanche d'IPs autorisées :
- 127.0.0.1/32 : Localhost
- 192.168.1.0/24 : Réseau LAN principal
- 100.64.0.0/10 : Réseau Tailscale (VPN)
- 172.18.0.0/16 : Réseau Docker interne
Toute requête provenant d'une IP hors de ces plages est rejetée avec un code HTTP 403.
ratelimit, secheaders, evasive :
Identiques à traefik-public, disponibles pour être appliqués au besoin sur des services spécifiques.
Certificats SSL
Stockage des certificats :
volumes:
- ./letsencrypt-private:/letsencrypt
Configuration ACME dans traefik-private.yml :
certificatesResolvers:
cloudflare:
acme:
email: your-email@example.com
storage: /letsencrypt/cloudflare_acme.json
keyType: EC256
dnsChallenge:
provider: cloudflare
Bien que les services soient locaux, ils bénéficient de certificats SSL valides grâce au challenge DNS.
Logging
log:
level: DEBUG
filePath: "/var/log/traefik-local/traefik.log"
accessLog:
filePath: "/var/log/traefik-local/access.log"
format: json
Logs stockés dans /var/log/traefik-local/ sur l'hôte Docker.
Configuration provider Docker
Identique à traefik-public :
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik_network
Services exposés
Fichiers de configuration statiques dans dynamic-private/ :
cockpit.yml : Proxification de Cockpit (interface web d'administration système) proxmox.yml : Proxification de l'interface Proxmox
Ces fichiers définissent des routers et services pour des applications ne tournant pas dans Docker.
Exemple de labels Docker
Pour exposer un service via traefik-private :
services:
monitoring:
image: grafana/grafana:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.monitoring.rule=Host(`grafana.local.tellserv.fr`)"
- "traefik.http.routers.monitoring.entrypoints=local"
- "traefik.http.routers.monitoring.tls.certresolver=cloudflare"
- "traefik.http.services.monitoring.loadbalancer.server.port=3000"
networks:
- traefik_network
Sécurité et bonnes pratiques
Séparation public/privé
- Ne jamais exposer de services d'administration via traefik-public
- Toujours vérifier l'entrypoint utilisé dans les labels Docker
- Privilégier traefik-private pour tout ce qui n'a pas besoin d'être public
Middlewares de sécurité
- CrowdSec : Actif uniquement sur traefik-public, bloque les attaques automatisées
- localonly : Appliqué par défaut sur traefik-private
- ratelimit : Protection anti-DDoS basique
- secheaders : Renforcement de la sécurité côté navigateur
Gestion des certificats
- Rotation automatique : Let's Encrypt renouvelle les certificats tous les 90 jours
- Backup : Sauvegarder régulièrement les fichiers
cloudflare_acme.json - Monitoring : Vérifier les logs pour détecter les échecs de renouvellement
Logging et monitoring
- Logs accessibles : Montés en volumes sur l'hôte pour analyse
- Format JSON : Facilite le parsing et l'intégration avec des outils de monitoring
- Niveau DEBUG : Utile pour le troubleshooting, peut être réduit en production
Limites de cette configuration
Bien que fonctionnelle et sécurisée, cette architecture présente certaines limites à connaître :
Réseau Docker partagé
Problème : Les deux instances Traefik (public et private) utilisent le même réseau Docker (traefik_network). Cela signifie que tous les conteneurs connectés à ce réseau peuvent potentiellement communiquer entre eux, qu'ils soient exposés publiquement ou localement.
Impact :
- Un conteneur exposé via traefik-public peut techniquement accéder à un conteneur exposé via traefik-private
- Le cloisonnement réseau n'est pas complet, il repose uniquement sur les IP bindings (192.168.1.2 vs 192.168.1.3)
Amélioration possible :
- Créer deux réseaux Docker distincts :
traefik_public_networkettraefik_private_network - Connecter chaque instance Traefik uniquement à son réseau dédié
- Garantir une isolation réseau complète au niveau Docker
Absence de segmentation VLAN
Problème : Les deux NICs de la VM partagent le même réseau physique (192.168.1.0/24) sans segmentation VLAN.
Impact :
- Le NIC pour traefik-private (192.168.1.3) a techniquement accès à Internet via la passerelle réseau, alors qu'il n'en a pas besoin
- Pas de cloisonnement réseau au niveau L2/L3 entre les interfaces publique et privée
- En cas de compromission, un attaquant pourrait potentiellement pivoter entre les deux réseaux
Amélioration possible :
- VLAN public : Placer le NIC de traefik-public (192.168.1.2) dans un VLAN avec accès Internet
- VLAN privé : Placer le NIC de traefik-private (192.168.1.3) dans un VLAN isolé, sans accès Internet
- Configurer des règles de firewall strictes entre les VLANs
- Cette segmentation renforcerait considérablement le cloisonnement et limiterait la surface d'attaque
Accès au socket Docker
Problème : Les deux instances Traefik ont un accès direct et complet au socket Docker (/var/run/docker.sock). Le socket Docker est l'API d'administration de Docker, donnant un contrôle total sur l'hôte.
Impact sécurité :
- Un conteneur Traefik compromis pourrait contrôler tous les conteneurs de l'hôte
- Possibilité d'élévation de privilèges (lancer un conteneur en mode privileged, monter des volumes sensibles, etc.)
- Accès en lecture seule (
ro) limite les dégâts, mais permet toujours d'extraire des informations sensibles (variables d'environnement, secrets, etc.)
Amélioration possible :
- Utiliser un proxy au socket Docker comme Tecnativa/docker-socket-proxy
- Ce proxy permet de filtrer finement les opérations autorisées (ex: seulement lire les conteneurs et leurs labels)
- Réduire la surface d'attaque en limitant l'accès API aux endpoints strictement nécessaires à Traefik
Exemple de configuration :
docker-socket-proxy:
image: tecnativa/docker-socket-proxy
environment:
CONTAINERS: 1 # Autoriser lecture des conteneurs
NETWORKS: 1 # Autoriser lecture des réseaux
SERVICES: 0 # Interdire accès aux services Swarm
TASKS: 0 # Interdire accès aux tâches Swarm
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
Ces améliorations ne sont pas critiques pour un homelab, mais seraient fortement recommandées en environnement de production.