Contenu

Post-Mortem — Incident 522 / WAN Failover (8 avril 2026)

⚡ En bref

Date : 7-8 avril 2026 — Durée : ~3h (21:28 UTC → 22:31 UTC) — Sévérité : P1

arleo.eu a été injoignable pendant 3 heures. La cause n’était ni le serveur, ni nginx, ni CrowdSec — c’était une règle de port forwarding HTTPS attachée à WAN générique au lieu de WAN1 explicite sur le Netgear PR60X. Le renouvellement quotidien du bail DHCP du modem 4G (WAN2) a déclenché un rebalance NAT qui a cassé le routage vers le port 443.

🧠 Pourquoi

Le PR60X est configuré en double WAN (FTTH WAN1 + 4G WAN2 backup). À chaque transition d’état WAN, le routeur rebalance ses règles NAT. Une règle attachée à WAN générique ne se réattache pas systématiquement à WAN1 après le rebalance — résultat : les paquets entrants sur WAN1 ne sont plus routés vers le serveur.

Ce piège de configuration était latent depuis l’installation initiale du PR60X. Il ne s’est jamais déclenché avant car le timing du reboot quotidien WAN2 (23:17 heure locale, imposé par l’opérateur) n’était pas documenté. L’incident a également révélé que l’architecture réseau physique (Freebox bridge → PR60X double WAN → NUC) n’était pas documentée.

🔧 Ce qui a été fait

Architecture réseau (révélée par l’incident)

Internet
   ↓
[Freebox FTTH] (mode Bridge — pas de routage)
   ↓
[Netgear PR60X] (vrai routeur/firewall, double WAN)
   ├── WAN1 = FTTH Free → 82.xxx.xxx.xxx (primaire)
   └── WAN2 = 4G/LTE backup → 100.96.220.53 (secours, reboot quotidien 23:17)
   ↓
LAN 192.168.0.0/22
   ↓
[NUC8i3BEH] 192.168.1.26 → nginx + CrowdSec + Grav

Timeline (heure UTC)

Heure Événement
21:01–21:12 CrowdSec banne 97 IPs (95× http:scan, 2× http:exploit) — scan wave depuis subnets Microsoft Azure
21:21:28 Dernière sonde BetterStack /ping reçue par nginx (status 200)
21:22–21:23 Surge nginx : connexions actives 2 → 34, traffic 355 KB/s — pic mémoire CrowdSec à 1.4 GB
21:27:10 WAN2 disconnected sur PR60X (renouvellement bail 4G opérateur)
21:27:14 WAN2 reconnected — PR60X rebalance les règles NAT
21:28:15 Incident BetterStack déclenché — HTTP 522
21:30–22:00 Investigation initiale : faux-coupable AppSec CrowdSec (timeouts dans nginx error.log)
22:20–22:25 Découverte clé : tcpdump strict sur dst port 443 montre zéro paquet entrant
22:28 Identification timing : crash 522 corrèle exactement avec les events WAN2 PR60X à 21:27
22:30 Édition règle HTTPS sur PR60X → fixée explicitement sur WAN1
22:31 Service rétabli

Mécanisme exact de la panne

  1. WAN2 (modem 4G) reçoit son renouvellement de bail DHCP forcé par l’opérateur (~23:17 heure locale tous les jours)
  2. PR60X enregistre un événement WAN2 disconnected puis WAN2 reconnected quelques secondes plus tard
  3. À chaque transition d’état WAN, le PR60X rebalance ses règles NAT/port forwarding
  4. La règle HTTPS étant attachée à WAN générique (pas WAN1 explicite), elle ne se réattache pas systématiquement à WAN1 après le rebalance
  5. Résultat : les paquets entrants sur WAN1 ne sont plus routés vers 192.168.1.26:443
  6. Cloudflare envoie ses requêtes vers l’IP origine → timeout → HTTP 522

Le faux-coupable : CrowdSec AppSec

Pendant la première heure, les logs nginx montraient des erreurs AppSec CrowdSec très convaincantes :

[lua] crowdsec.lua:622: AppSecCheck(): Fallback because of err: timeout
[lua] crowdsec.lua:783: Allow(): [Crowdsec] denied '127.0.0.1' with 'ban' (by appsec)

Ces denials ne touchaient que les requêtes qui arrivaient à nginx — or aucune requête n’arrivait (port forwarding cassé). Le diagnostic décisif a été ce tcpdump strict :

sudo timeout 20 tcpdump -i eno1 -n "tcp dst port 443"

0 paquet entrant pendant 20 secondes de test depuis téléphone en 4G.

Fix appliqué

Fix principal — PR60X :

Champ Avant Après
Adresse IP WAN WAN (générique) WAN1 (explicite)
Port externe 443 443
Port interne 443 443
Adresse IP interne 192.168.1.26 192.168.1.26
Protocole TCP TCP

Fix bonus — CrowdSec hardening dans /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf :

- APPSEC_FAILURE_ACTION=passthrough  (commented)
+ APPSEC_FAILURE_ACTION=allow

- APPSEC_CONNECT_TIMEOUT=
- APPSEC_SEND_TIMEOUT=
- APPSEC_PROCESS_TIMEOUT=
+ APPSEC_CONNECT_TIMEOUT=500
+ APPSEC_SEND_TIMEOUT=500
+ APPSEC_PROCESS_TIMEOUT=2000

- ALWAYS_SEND_TO_APPSEC=true
+ ALWAYS_SEND_TO_APPSEC=false

Leçons apprises

  1. Les logs serveurs convaincants peuvent être un faux-coupable. Toujours valider depuis l’extérieur (tcpdump sur dst port) qu’on reçoit bien des paquets avant de plonger dans le débuggage applicatif.
  2. Les règles de redirection de port sur routeur double-WAN doivent toujours être attachées à un WAN explicite, jamais à un alias générique. Le rebalance NAT est un piège silencieux.
  3. Un événement quotidien planifié qui corrèle avec une panne intermittente est presque toujours la cause. Le timing 23:17 / 23:28 aurait dû être un signal plus précoce.
  4. Documenter l’architecture physique réseau est aussi important que de documenter la stack applicative.

Actions correctives

Court terme :

  • Fixer la règle HTTPS sur WAN1 explicite (fait pendant l’incident)
  • Hardening CrowdSec AppSec (fait pendant l’incident)
  • Vérifier toutes les autres règles de redirection PR60X et les fixer sur WAN1 explicite
  • Vérifier le mode WAN du PR60X : passer en Failover au lieu de Load Balancing

Moyen terme :

  • Ajouter un check BetterStack qui scrute directement 82.xxx.xxx.xxx:443 (sans passer par Cloudflare)
  • Mettre à jour /documentation avec une section “Architecture réseau physique”
  • Ajouter un monitoring des events WAN du PR60X (via SNMP ou Insight Cloud)

🏁 Conclusion

Cet incident de 3 heures avait une cause racine triviale — une case à cocher dans l’interface PR60X — mais elle était complètement masquée par des logs applicatifs trompeurs. BetterStack a détecté l’incident en moins de 2 minutes, la capture tcpdump a permis de trancher définitivement entre problème serveur et problème réseau. Aucune perte de données, aucun impact sur le contenu.

Pour aller plus loin :

  • 💡 Envisager un script de vérification horaire de la cohérence des règles de port forwarding PR60X pour détecter tout glissement de WAN1 vers WAN générique
  • 💡 Mettre en place un monitoring SNMP des events WAN du PR60X pour alerter sur les rebalances NAT avant qu’ils causent une panne