<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Nginx - Balise - arleo.eu</title>
        <link>https://www.arleo.eu/tags/nginx/</link>
        <description>Nginx - Balise - arleo.eu</description>
        <generator>Hugo -- gohugo.io</generator><language>fr</language><lastBuildDate>Fri, 29 May 2026 20:30:00 &#43;0200</lastBuildDate><atom:link href="https://www.arleo.eu/tags/nginx/" rel="self" type="application/rss+xml" /><item>
    <title>SEO Hugo : 404 Googlebot, aliases noindex et normalisation des sitemaps</title>
    <link>https://www.arleo.eu/posts/debug-seo-404-broken-links/</link>
    <pubDate>Fri, 29 May 2026 20:30:00 &#43;0200</pubDate>
    <author>Jmr</author>
    <guid>https://www.arleo.eu/posts/debug-seo-404-broken-links/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/debug-seo-404-broken-links-featured.jpg" referrerpolicy="no-referrer">
            </div><h2 id="contexte">Contexte</h2>
<p>Google Search Console remontait quatre catégories de problèmes sur arleo.eu :</p>
<ul>
<li><strong>404 Googlebot</strong> : <code>/fr/tag/cloudflare</code>, <code>/en/tag/nginx</code>, <code>/fr/tag/javascript</code>… URLs avec préfixe <code>/fr/</code> ou singulier <code>/tag/</code> jamais servi par nginx</li>
<li><strong>16 pages &ldquo;Exclue par la balise noindex&rdquo;</strong> : toutes des pages de redirection générées par <code>aliases:</code> dans le frontmatter Hugo</li>
<li><strong>Balise robots</strong> : <code>noodp</code> hardcodée dans le thème LoveIt</li>
<li><strong>Sitemap FR/EN</strong> : 104 vs 105 URLs — un tag doublon FR et deux tags manquants</li>
</ul>
<hr>
<h2 id="acte-1--aliases-hugo--redirections-nginx-301">Acte 1 : aliases Hugo → redirections nginx 301</h2>
<h3 id="pourquoi-hugo-génère-des-pages-noindex">Pourquoi Hugo génère des pages noindex</h3>
<p>Hugo génère les entrées <code>aliases:</code> du frontmatter comme des fichiers HTML statiques :</p>]]></description>
</item>
<item>
    <title>CSP A&#43; sur Hugo &#43; Cloudflare : de hash-based à origin allowlist, monitoring auto et durcissement</title>
    <link>https://www.arleo.eu/posts/csp-a-plus-hugo-cloudflare-origin-allowlist/</link>
    <pubDate>Thu, 28 May 2026 23:40:12 &#43;0200</pubDate>
    <author>Jmr</author>
    <guid>https://www.arleo.eu/posts/csp-a-plus-hugo-cloudflare-origin-allowlist/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/csp-a-plus-hugo-cloudflare-origin-allowlist-featured.jpg" referrerpolicy="no-referrer">
            </div><h2 id="contexte">Contexte</h2>
<p>arleo.eu tourne sur Hugo (VM KVM) → OpenResty (NUC) → Cloudflare (CDN/WAF). Objectif : score <strong>A+ sur Mozilla Observatory</strong> avec une CSP stricte qui résiste aux injections côté edge.</p>
<p>Le parcours a traversé trois stratégies en quelques semaines — nonces, hashes, puis origin allowlist — avant d&rsquo;aboutir à une solution stable et automatisée.</p>
<hr>
<h2 id="acte-1--pourquoi-hash-based-a-échoué">Acte 1 : pourquoi hash-based a échoué</h2>
<p>L&rsquo;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&rsquo;approche impossible.</p>]]></description>
</item>
<item>
    <title>Postmortem — CrowdSec AppSec : faux positif heuristique sur Sonarr/Radarr</title>
    <link>https://www.arleo.eu/posts/postmortem-crowdsec-appsec-false-positive-sonarr/</link>
    <pubDate>Mon, 25 May 2026 20:51:17 &#43;0200</pubDate>
    <author>Jmr</author>
    <guid>https://www.arleo.eu/posts/postmortem-crowdsec-appsec-false-positive-sonarr/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/postmortem-crowdsec-appsec-false-positive-sonarr-featured.jpg" referrerpolicy="no-referrer">
            </div><h2 id="résumé">Résumé</h2>
<p>Le <strong>25 mai 2026 vers 22h02 (heure locale)</strong>, Sonarr et Radarr sont devenus totalement inaccessibles depuis l&rsquo;IP maison (<code>82.XX.XX.XX</code>), retournant <strong>403</strong> sur toutes les URLs y compris <code>/login</code>. Le service était pourtant opérationnel. Le diagnostic initial suspectait les récents déploiements du refactor <code>crowdsec-cf-sync</code> — la cause réelle est un <strong>faux positif heuristique CrowdSec AppSec</strong>.</p>
<hr>
<h2 id="timeline">Timeline</h2>
<table>
  <thead>
      <tr>
          <th>Heure (locale)</th>
          <th>Événement</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>~22h00</td>
          <td>Cookie de session Sonarr expiré côté navigateur</td>
      </tr>
      <tr>
          <td>22h02:31</td>
          <td>Le navigateur charge la bibliothèque Sonarr → tente de charger 20+ <code>/MediaCover/*.jpg</code> simultanément</td>
      </tr>
      <tr>
          <td>22h02:31</td>
          <td>Sonarr retourne 302 → <code>/login</code> pour chaque image (session invalide)</td>
      </tr>
      <tr>
          <td>22h02:34</td>
          <td>La connexion SignalR WebSocket s&rsquo;établit (101) via <code>access_token</code> dans l&rsquo;URL</td>
      </tr>
      <tr>
          <td>~22h05</td>
          <td>CrowdSec AppSec déclenche la règle heuristique <code>http-probing</code> : rafale de requêtes échouées depuis la même IP</td>
      </tr>
      <tr>
          <td>22h11:37</td>
          <td>Toutes les requêtes de <code>82.XX.XX.XX</code> retournent 403 — <code>cs_reason=heuristic</code> dans les logs nginx</td>
      </tr>
      <tr>
          <td>22h13:34</td>
          <td>Même <code>/login</code> bloqué — l&rsquo;IP ne peut plus s&rsquo;authentifier</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="cause-racine">Cause racine</h2>
<p>CrowdSec AppSec maintient un <strong>état heuristique en mémoire</strong>, distinct des décisions LAPI. Lorsque le navigateur tente de charger simultanément de nombreuses ressources et reçoit des 302/403 de l&rsquo;application upstream (Sonarr), AppSec interprète cette rafale d&rsquo;échecs comme du sondage agressif (<code>http-probing</code>) et bloque l&rsquo;IP source.</p>]]></description>
</item>
<item>
    <title>CrowdSec AppSec &#43; OpenResty : WAF moderne sans ModSecurity</title>
    <link>https://www.arleo.eu/posts/crowdsec-appsec-openresty/</link>
    <pubDate>Mon, 18 May 2026 00:07:11 &#43;0200</pubDate>
    <author>Jmr</author>
    <guid>https://www.arleo.eu/posts/crowdsec-appsec-openresty/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/crowdsec-appsec-openresty-featured.jpg" referrerpolicy="no-referrer">
            </div><p>Après des années avec ModSecurity + OWASP CRS sur nginx, j&rsquo;ai migré arleo.eu vers une stack plus moderne : <strong>CrowdSec AppSec sur OpenResty</strong>. 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é.</p>
<h2 id="pourquoi-abandonner-modsecurity-">Pourquoi abandonner ModSecurity ?</h2>
<p>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.</p>]]></description>
</item>
<item>
    <title>CSP Hash sur Hugo : migrer du nonce vers le hash pour préserver le cache CDN</title>
    <link>https://www.arleo.eu/posts/csp-hash-hugo/</link>
    <pubDate>Sat, 16 May 2026 00:00:00 &#43;0000</pubDate>
    <author>Jmr</author>
    <guid>https://www.arleo.eu/posts/csp-hash-hugo/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/csp-hash-hugo-featured.png" referrerpolicy="no-referrer">
            </div>Le nonce CSP et le cache CDN sont incompatibles par design. Sur un site Hugo statique, le hash SHA-256 est l&rsquo;approche native : il est calculé au build, reste stable entre les requêtes, et laisse Cloudflare cacher le HTML.]]></description>
</item>
<item>
    <title>Audit sécurité NUC : ModSecurity supprimé, 500 MB récupérés</title>
    <link>https://www.arleo.eu/posts/audit-securite-modsecurity-crowdsec/</link>
    <pubDate>Thu, 14 May 2026 05:31:23 &#43;0200</pubDate>
    <author>Jmr</author>
    <guid>https://www.arleo.eu/posts/audit-securite-modsecurity-crowdsec/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/audit-securite-modsecurity-featured.jpg" referrerpolicy="no-referrer">
            </div><h2 id="-en-bref">⚡ En bref</h2>
<p>Un audit de la stack sécurité du NUC révèle une <strong>double inspection WAF redondante</strong> : ModSecurity + OWASP CRS chargent 11 872 règles en mémoire malgré <code>SecRuleEngine Off</code>, en parallèle d&rsquo;un CrowdSec AppSec déjà actif et couvrant le même périmètre. Après suppression du module nginx ModSecurity et 5 autres correctifs ciblés, nginx passe de <strong>~520 MB à ~27 MB PSS</strong>. Sécurité identique, empreinte divisée par 20.</p>
<hr>
<h2 id="-architecture-avant-audit">🏗️ Architecture avant audit</h2>
<p>La stack sécurité reposait sur six couches empilées :</p>]]></description>
</item>
<item>
    <title>Hugo MCP Server : connecter Claude.ai à un site Hugo statique</title>
    <link>https://www.arleo.eu/posts/hugo-mcp-server/</link>
    <pubDate>Sun, 03 May 2026 19:00:00 &#43;0200</pubDate>
    <author>Jmr</author>
    <guid>https://www.arleo.eu/posts/hugo-mcp-server/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/hugo-mcp-server-featured.jpg" referrerpolicy="no-referrer">
            </div><h2 id="-en-bref">⚡ En bref</h2>
<p>Connecter Claude.ai à un site <strong>Hugo</strong> hébergé dans une VM KVM en 30 minutes : un serveur FastAPI expose 6 outils MCP (lire, créer, modifier, supprimer des pages, rebuilder le site) via JSON-RPC 2.0, un proxy OAuth réutilise l&rsquo;infrastructure existante, et chaque modification déclenche automatiquement un rebuild Hugo + une purge du cache Cloudflare.</p>
<p>Le code est disponible sur GitHub :</p>
<ul>
<li>🔌 Serveur MCP Hugo : <a href="https://github.com/jmrGrav/hugo-mcp" target="_blank" rel="noopener noreffer ">jmrGrav/hugo-mcp</a></li>
<li>🔐 Proxy OAuth : <a href="https://github.com/jmrGrav/mcp-oauth-proxy" target="_blank" rel="noopener noreffer ">jmrGrav/mcp-oauth-proxy</a></li>
</ul>
<h2 id="-pourquoi">🧠 Pourquoi</h2>
<p>Le protocole <a href="https://modelcontextprotocol.io/" target="_blank" rel="noopener noreffer ">MCP (Model Context Protocol)</a> d&rsquo;Anthropic permet à Claude.ai de se connecter à des sources de données externes via des outils standardisés. Contrairement à Grav CMS qui est dynamique (PHP), Hugo génère du HTML statique — ce qui rend la gestion de contenu via MCP encore plus puissante : chaque modification est compilée et déployée instantanément.</p>]]></description>
</item>
<item>
    <title>VM Media sur KVM : migrer Sonarr, Radarr et SABnzbd dans une VM isolée</title>
    <link>https://www.arleo.eu/posts/media-vm-migration/</link>
    <pubDate>Sun, 03 May 2026 18:00:00 &#43;0200</pubDate>
    <author>Jmr</author>
    <guid>https://www.arleo.eu/posts/media-vm-migration/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/media-vm-migration-featured.jpg" referrerpolicy="no-referrer">
            </div><h2 id="-en-bref">⚡ En bref</h2>
<p>Migrer son media stack (Sonarr, Radarr, SABnzbd) dans une VM KVM dédiée sur Ubuntu 24.04 : isolation sécurité, snapshots facilités, NFS QNAP monté dans la VM, reverse proxy nginx sur l&rsquo;hôte. La migration conserve intégralement les bases de données SQLite et la configuration existante.</p>
<p><strong>Stack cible :</strong></p>
<ul>
<li>🖥️ <strong>Hôte</strong> : NUC8i3BEH, Ubuntu Server, nginx reverse proxy, Plex (transcodage GPU)</li>
<li>📦 <strong>VM media-vm</strong> : Ubuntu 24.04, 2 vCPU, 8 Go RAM, 120 Go (X5 NVMe), NFS QNAP</li>
<li>🎬 <strong>Services migrés</strong> : Sonarr (port 8989), Radarr (port 7878), SABnzbd (port 6789)</li>
</ul>
<h2 id="-pourquoi-isoler-le-media-stack-dans-une-vm">🧠 Pourquoi isoler le media stack dans une VM</h2>
<p>Sonarr, Radarr et SABnzbd présentent une surface d&rsquo;attaque non négligeable : accès réseau vers des indexeurs externes, exécution de scripts post-download, accès au système de fichiers de la bibliothèque. Les confiner dans une VM apporte :</p>]]></description>
</item>
<item>
    <title>Hugo sur KVM : installer une VM Ubuntu pour site statique</title>
    <link>https://www.arleo.eu/posts/hugo-vm-installation/</link>
    <pubDate>Sun, 03 May 2026 09:00:00 &#43;0200</pubDate>
    <author>Jmr</author>
    <guid>https://www.arleo.eu/posts/hugo-vm-installation/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/hugo-vm-installation-featured.jpg" referrerpolicy="no-referrer">
            </div><h2 id="-en-bref">⚡ En bref</h2>
<p>Migration progressive de <strong>Grav CMS</strong> vers <strong>Hugo</strong> — un générateur de site statique. L&rsquo;objectif est d&rsquo;isoler Hugo dans une VM KVM dédiée sur le NUC8i3BEH, avec nginx sur le host en proxy inverse. Le site statique généré est servi par nginx dans la VM, sans PHP, sans base de données, sans surface d&rsquo;attaque applicative.</p>
<ul>
<li>🖥️ <strong>Host</strong> : NUC8i3BEH Ubuntu 24.04 — nginx proxy + KVM</li>
<li>🗄️ <strong>Disque VM</strong> : NVMe externe Samsung X5 (exFAT → image ext4 loop)</li>
<li>🌐 <strong>Accès</strong> : <a href="https://hugo-test.arleo.eu" target="_blank" rel="noopener noreffer ">hugo-test.arleo.eu</a></li>
<li>🎨 <strong>Thème</strong> : <a href="https://github.com/dillonzq/LoveIt" target="_blank" rel="noopener noreffer ">LoveIt</a></li>
</ul>
<h2 id="-pourquoi">🧠 Pourquoi</h2>
<p>Grav CMS est excellent mais repose sur PHP — une surface d&rsquo;attaque non négligeable. Hugo génère du HTML statique pur : zéro PHP, zéro base de données, zéro vulnérabilité applicative. Les performances sont aussi radicalement meilleures — le HTML est servi directement par nginx sans traitement dynamique.</p>]]></description>
</item>
<item>
    <title>De 46 hashes à zéro : migration CSP vers les nonces dynamiques</title>
    <link>https://www.arleo.eu/posts/csp-nonce/</link>
    <pubDate>Wed, 15 Apr 2026 13:22:00 &#43;0200</pubDate>
    <author>Jmr</author>
    <guid>https://www.arleo.eu/posts/csp-nonce/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/csp-nonce-featured.jpg" referrerpolicy="no-referrer">
            </div><h2 id="-en-bref">⚡ En bref</h2>
<p>La CSP initiale listait 46 hashes SHA-256 pour couvrir les scripts et styles inline — ingérable, fragile, et à la limite des 4 096 caractères de Cloudflare. Cette migration vers des <strong>nonces dynamiques</strong> réduit la CSP à ~600 caractères, supprime toute maintenance manuelle des hashes, et ajoute un reporting structuré des violations dans BetterStack.</p>
<p>Le plugin Grav utilisé est disponible sur GitHub :
🔌 Plugin : <a href="https://github.com/jmrGrav/csp-nonce" target="_blank" rel="noopener noreffer ">jmrGrav/grav-plugin-csp-nonce</a></p>]]></description>
</item>
</channel>
</rss>
