La chaine de reverse proxy
Chaque requete entrante traverse 5 couches avant d atteindre l application. Chaque couche a un role precis et des contraintes de configuration qui doivent etre alignees.
sequenceDiagram
participant Client as Client Internet
participant HAP as HAProxy<br/>VyOS Podman
participant TFK as Traefik<br/>K3s Ingress
participant VRN as Varnish<br/>Cache HTTP
participant WAF as WAF nginx<br/>ModSecurity
participant WP as WordPress<br/>PHP-FPM
Client->>HAP: HTTPS (TLS 1.2/1.3)
Note over HAP: TLS termination<br/>SNI routing via crt-list
HAP->>TFK: HTTPS re-encrypted<br/>verify ca-file interne
Note over TFK: HTTPRoute matching<br/>CrowdSec IP check
TFK->>VRN: HTTP
Note over VRN: Cache lookup
alt HIT
VRN-->>TFK: Reponse depuis cache
else MISS
VRN->>WAF: Forward request
Note over WAF: ModSecurity CRS<br/>Inspection requete
WAF->>WP: proxy_pass
WP-->>WAF: Reponse
WAF-->>VRN: Reponse
end
VRN-->>TFK: Reponse
TFK-->>HAP: Reponse
HAP-->>Client: HTTPS
HAProxy : terminaison TLS et routage SNI
HAProxy tourne en container Podman sur VyOS dans un reseau dedie. C est le premier point de contact pour le trafic entrant depuis Internet.
crt-list et SNI
Le mecanisme crt-list selectionne le certificat en fonction du SNI (Server Name Indication) envoye par le client :
# Format : chemin_pem [options] domaine [domaine2...]
/etc/haproxy/WWW/blog.pem blog.exemple.fr www.exemple.fr
/etc/haproxy/WWW/app.pem app.exemple.fr
/etc/haproxy/WWW/home.pem home.exemple.fr
Chaque ligne associe un fichier PEM (certificat + cle privee concatenes) a un ou plusieurs domaines.
Frontend ACL pattern
frontend ft_https
bind *:443 ssl crt-list /etc/haproxy/WWW.crt_list alpn h2,http/1.1
mode http
# Normalisation du Host header
http-request set-var(txn.txnhost) hdr(host),lower,regsub(:[0-9]+$,"")
# Routage par domaine
acl host_blog var(txn.txnhost) -m str blog.exemple.fr
acl host_app var(txn.txnhost) -m str app.exemple.fr
use_backend bk_traefik if host_blog
use_backend bk_traefik if host_app
Le pattern var(txn.txnhost) normalise le header Host (minuscules, suppression du port) pour un matching fiable.
Re-encryption vers Traefik
backend bk_traefik
mode http
timeout connect 30s
timeout server 600s
timeout tunnel 3600s
server traefik1 10.0.2.101:30443 ssl
verify required
ca-file /etc/ssl/internal-ca.crt
sni str(traefik.internal)
Le trafic entre HAProxy et Traefik est re-chiffre avec verification du certificat interne. Le sni str(traefik.internal) envoie un SNI fixe a Traefik (le routage HTTP se fait sur le header Host, pas le SNI TLS).
Pourquoi re-chiffrer ? Meme sur un reseau interne, le trafic en clair peut etre intercepte si un container est compromis. La re-encryption avec CA interne garantit l authenticite de Traefik.
Traefik : ingress K3s et CrowdSec
Traefik est le controleur d ingress natif de K3s.
HTTPRoute (Gateway API)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: wordpress-route
spec:
hostnames:
- "blog.exemple.fr"
rules:
- backendRefs:
- name: varnish-service
port: 8080
filters:
- type: ExtensionRef
extensionRef:
kind: Middleware
name: crowdsec-bouncer
CrowdSec middleware
Le middleware CrowdSec verifie l IP source contre une base de reputation. Les IPs connues comme malveillantes sont bloquees avant meme d atteindre Varnish ou le WAF.
Timeouts critiques
Traefik a des timeouts par defaut de 60s (non documente dans la config K3s). Pour les uploads volumineux (photos Immich, medias WordPress), les timeouts doivent etre augmentes :
additionalArguments:
- "--entryPoints.websecure.transport.respondingTimeouts.readTimeout=600s"
- "--entryPoints.websecure.transport.respondingTimeouts.writeTimeout=600s"
Varnish : cache HTTP
Varnish se place entre Traefik et le WAF. Les pages deja en cache sont servies directement (HIT) sans toucher PHP/MySQL. Les requetes non-cachees (MISS) sont forwarded au WAF puis a WordPress.
Voir l article dedie : Varnish : cache et routage VCL
Alignement des timeouts
Tous les timeouts de la chaine doivent etre alignes. Un timeout plus court en amont coupe la connexion mid-upload et genere des erreurs 502/504.
| Couche | Parametre | Valeur |
|---|---|---|
| HAProxy frontend | timeout client | 600s |
| HAProxy backend | timeout server | 600s |
| HAProxy backend | timeout tunnel | 3600s (WebSocket) |
| Traefik | readTimeout | 600s |
| Traefik | writeTimeout | 600s |
| WAF nginx | proxy_read_timeout | 600s |
| WAF nginx | proxy_send_timeout | 600s |
| Backend nginx | proxy_read_timeout | 600s |
Mecanisme de panne : timeout court en amont, connexion coupee mid-upload, WAF recoit un body tronque, backend retourne 400 Bad Request, Traefik voit la coupure et renvoie 502.
Gotchas
PEM manquant dans la crt-list : HAProxy refuse categoriquement de demarrer si un fichier PEM reference dans la crt-list n existe pas. Impact : TOUS les sites down (pas seulement le nouveau domaine). C est pourquoi le certificat doit etre genere et verifie AVANT de modifier la crt-list.
WebSocket : les connexions upgradeees (Socket.IO, WebSocket) necessitent timeout tunnel 3600s dans HAProxy. Sans ca, les connexions longues sont coupees apres timeout server.
ConfigMap stale : les ConfigMaps montes avec subPath dans K3s sont figes au moment de la creation du pod. Modifier un ConfigMap ne met PAS a jour le fichier dans le pod -- un rollout restart est obligatoire.
Varnish probe : le probe backend doit utiliser /healthcheck (pas /). WordPress retourne 301 sur / ce qui fait echouer le probe et marque le backend comme sick.
Laisser un commentaire