/images/avatar.png

Casser, réparer, apprendre.

Ce site tourne sur un NUC Intel hébergé à la maison, derrière une connexion fibre standard. Il sert avant tout de terrain d’expérimentation pour tester des configurations serveur, des scripts d’automatisation, et des outils de sécurité open source.

Pas un site professionnel — un homelab : on casse des choses, on les répare, on apprend.

Migration en cours
Le site migre progressivement de Grav CMS vers Hugo. Les anciennes URLs sont préservées, mais le rendu visuel évolue. Si vous voyez un bug, signalez-le.

🛠️ Stack technique

OutilRôleLien
🔒 CrowdSecIDS/IPS communautaire collaboratifDashboard
☁️ CloudflareCDN · WAF · DNS · DDoSDashboard
📊 BetterStackMonitoring · Alertes · LogsStatus page
🌐 HugoGénérateur de site statiquegohugo.io
🛡️ ModSecurityWAF local · OWASP CRS 4.xOWASP CRS
nginxReverse proxy · TLS 1.3nginx.org

🌟 À ne pas manquer

Trois articles qui résument l’esprit du homelab :

📚 La documentation complète est dans Documentation et les scripts d’automatisation dans Scripts.

🐛 Vous avez trouvé une faille ?

Si vous découvrez un bug, une mauvaise configuration ou une faille de sécurité sur ce serveur, merci de me le signaler. Ce homelab est public et j’apprends de mes erreurs.

📨 Signalement responsable : www.arleo.eu/security.txt

Toute contribution à l’amélioration de la sécurité est la bienvenue.

CSP A+ sur Hugo + Cloudflare : de hash-based à origin allowlist, monitoring auto et durcissement

Contexte

arleo.eu tourne sur Hugo (VM KVM) → OpenResty (NUC) → Cloudflare (CDN/WAF). Objectif : score A+ sur Mozilla Observatory avec une CSP stricte qui résiste aux injections côté edge.

Le parcours a traversé trois stratégies en quelques semaines — nonces, hashes, puis origin allowlist — avant d’aboutir à une solution stable et automatisée.


Acte 1 : pourquoi hash-based a échoué

L’idée de départ semblait solide : Hugo Pipes externalise tout le JS avec SRI, on liste les hashes dans la CSP, résultat propre. En pratique, deux problèmes ont rendu l’approche impossible.

Postmortem — CrowdSec AppSec : faux positif heuristique sur Sonarr/Radarr

Résumé

Le 25 mai 2026 vers 22h02 (heure locale), Sonarr et Radarr sont devenus totalement inaccessibles depuis l’IP maison (82.XX.XX.XX), retournant 403 sur toutes les URLs y compris /login. Le service était pourtant opérationnel. Le diagnostic initial suspectait les récents déploiements du refactor crowdsec-cf-sync — la cause réelle est un faux positif heuristique CrowdSec AppSec.


Timeline

Heure (locale)Événement
~22h00Cookie de session Sonarr expiré côté navigateur
22h02:31Le navigateur charge la bibliothèque Sonarr → tente de charger 20+ /MediaCover/*.jpg simultanément
22h02:31Sonarr retourne 302 → /login pour chaque image (session invalide)
22h02:34La connexion SignalR WebSocket s’établit (101) via access_token dans l’URL
~22h05CrowdSec AppSec déclenche la règle heuristique http-probing : rafale de requêtes échouées depuis la même IP
22h11:37Toutes les requêtes de 82.XX.XX.XX retournent 403 — cs_reason=heuristic dans les logs nginx
22h13:34Même /login bloqué — l’IP ne peut plus s’authentifier

Cause racine

CrowdSec AppSec maintient un état heuristique en mémoire, distinct des décisions LAPI. Lorsque le navigateur tente de charger simultanément de nombreuses ressources et reçoit des 302/403 de l’application upstream (Sonarr), AppSec interprète cette rafale d’échecs comme du sondage agressif (http-probing) et bloque l’IP source.

CrowdSec AppSec + OpenResty : WAF moderne sans ModSecurity

Après des années avec ModSecurity + OWASP CRS sur nginx, j’ai migré arleo.eu vers une stack plus moderne : CrowdSec AppSec sur OpenResty. Le résultat est une architecture WAF inline mieux intégrée, plus facile à maintenir, et plus cohérente avec le reste de la stack de sécurité.

Pourquoi abandonner ModSecurity ?

ModSecurity v2 est en fin de vie active. Le maintien des règles OWASP CRS sur nginx classique génère de la friction : faux positifs fréquents, logs difficiles à corréler avec CrowdSec, et une configuration dispersée entre plusieurs outils sans vision unifiée.

SRI sur Hugo : hashes automatiques, auto-update et alerting BetterStack

Pourquoi le SRI ?

Quand votre site charge des ressources depuis un CDN tiers — FontAwesome, Mermaid, Animate.css — vous faites confiance à un tiers sur lequel vous n’avez aucun contrôle. Si jsdelivr.net est compromis ou si une version « immuable » est mutée silencieusement, votre site peut devenir vecteur d’attaque.

Le Subresource Integrity (SRI) résout ça simplement : chaque balise <link> ou <script> porte un attribut integrity="sha256-…" que le navigateur vérifie avant d’exécuter la ressource. Si le hash ne correspond pas, le navigateur bloque le chargement.

Postmortem : TypeIt cassé par Mermaid dans le thème LoveIt

TL;DR

L’animation typewriter du thème LoveIt (TypeIt) ne fonctionnait plus sur la home après l’ajout de diagrammes Mermaid dans les posts. Cause : un sélecteur DOM #id-1 partagé entre les deux librairies. Quand Mermaid trouve un bloc orphelin dans un résumé de home, son initialisation crash, et la chaîne d’init JS s’arrête avant d’atteindre TypeIt. Fix : ajouter `

Hugo