<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Bash - Tag - arleo.eu</title><link>https://www.arleo.eu/en/tags/bash/</link><description>Bash - Tag - arleo.eu</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Thu, 28 May 2026 23:45:41 +0200</lastBuildDate><atom:link href="https://www.arleo.eu/en/tags/bash/" rel="self" type="application/rss+xml"/><item><title>CSP A+ on Hugo + Cloudflare: from hash-based to origin allowlist, auto-monitoring and hardening</title><link>https://www.arleo.eu/en/posts/csp-a-plus-hugo-cloudflare-origin-allowlist/</link><pubDate>Thu, 28 May 2026 23:45:41 +0200</pubDate><author>Jmr</author><guid>https://www.arleo.eu/en/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="context">Context</h2>
<p>arleo.eu runs on Hugo (KVM VM) → OpenResty (NUC) → Cloudflare (CDN/WAF). Goal: <strong>A+ score on Mozilla Observatory</strong> with a strict CSP that resists edge-side injections.</p>
<p>The journey went through three strategies over a few weeks — nonces, hashes, then origin allowlist — before landing on a stable, automated solution.</p>
<hr>
<h2 id="act-1-why-hash-based-failed">Act 1: why hash-based failed</h2>
<p>The initial idea seemed solid: Hugo Pipes externalizes all JS with SRI, we list the hashes in the CSP, clean result. In practice, two problems made the approach impossible.</p>]]></description></item><item><title>Post-mortem: mcp-installer regenerated tokens on every rerun</title><link>https://www.arleo.eu/en/posts/postmortem-mcp-installer-idempotence/</link><pubDate>Sat, 09 May 2026 13:05:11 +0200</pubDate><author>Jmr</author><guid>https://www.arleo.eu/en/posts/postmortem-mcp-installer-idempotence/</guid><description><![CDATA[<div class="featured-image">
                <img src="/images/postmortem-mcp-installer-idempotence-featured.jpg" referrerpolicy="no-referrer">
            </div><h2 id="the-bug">The bug</h2>
<p><code>mcp-installer</code> is a bash script I wrote to automate the installation of <code>mcp-oauth-proxy</code> (FastAPI + nginx + systemd) on a new host. Standard workflow: clone, run, done.</p>
<p>Except when re-running the script on an <strong>already installed</strong> host (e.g. to update the version), I discovered an idempotence bug: all secrets were regenerated.</p>
<div class="code-block code-line-numbers open" data-start="0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ sudo ./install.sh
</span></span><span class="line"><span class="cl"><span class="o">[</span>+<span class="o">]</span> Generating MCP_TOKEN...
</span></span><span class="line"><span class="cl"><span class="o">[</span>+<span class="o">]</span> Generating CLIENT_ID...
</span></span><span class="line"><span class="cl"><span class="o">[</span>+<span class="o">]</span> Generating CLIENT_SECRET...
</span></span><span class="line"><span class="cl"><span class="o">[</span>+<span class="o">]</span> Generating TOKEN_SECRET...
</span></span><span class="line"><span class="cl"><span class="o">[</span>+<span class="o">]</span> Writing /etc/mcp-oauth-proxy/.env...</span></span></code></pre></div></div>
<p>If you already have a <code>.env</code> with tokens in service, the installer <strong>overwrites</strong> them. All already-registered OAuth clients (Claude.ai in my case) end up with invalid credentials. Connection breaks.</p>
<h2 id="why-it-happened">Why it happened</h2>
<p>The script used this logic:</p>
<div class="code-block code-line-numbers" data-start="0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">MCP_TOKEN</span><span class="o">=</span><span class="k">$(</span>openssl rand -hex 32<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">CLIENT_ID</span><span class="o">=</span><span class="k">$(</span>openssl rand -hex 16<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">CLIENT_SECRET</span><span class="o">=</span><span class="k">$(</span>openssl rand -hex 32<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">TOKEN_SECRET</span><span class="o">=</span><span class="k">$(</span>openssl rand -hex 32<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">cat &gt; /etc/mcp-oauth-proxy/.env <span class="s">&lt;&lt;EOF
</span></span></span><span class="line"><span class="cl"><span class="s">MCP_TOKEN=$MCP_TOKEN
</span></span></span><span class="line"><span class="cl"><span class="s">CLIENT_ID=$CLIENT_ID
</span></span></span><span class="line"><span class="cl"><span class="s">CLIENT_SECRET=$CLIENT_SECRET
</span></span></span><span class="line"><span class="cl"><span class="s">TOKEN_SECRET=$TOKEN_SECRET
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span></span></span></code></pre></div></div>
<p>The &ldquo;generate then write&rdquo; pattern is correct for first install. But on rerun, it completely ignores the existing <code>.env</code>.</p>
<p>It&rsquo;s the classic mistake: the author (me) tested the script <strong>only on a fresh host</strong>. The &ldquo;reinstall on existing host&rdquo; mode was never tested.</p>
<h2 id="bug-reproduction">Bug reproduction</h2>
<div class="code-block code-line-numbers open" data-start="0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ sudo ./install.sh
</span></span><span class="line"><span class="cl"><span class="o">[</span>OK<span class="o">]</span> Installation <span class="nb">complete</span>
</span></span><span class="line"><span class="cl">$ cat /etc/mcp-oauth-proxy/.env <span class="p">|</span> head -1
</span></span><span class="line"><span class="cl"><span class="nv">MCP_TOKEN</span><span class="o">=</span>a7f3e9d2c4b8a1...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">$ sudo ./install.sh
</span></span><span class="line"><span class="cl"><span class="o">[</span>OK<span class="o">]</span> Installation <span class="nb">complete</span>
</span></span><span class="line"><span class="cl">$ cat /etc/mcp-oauth-proxy/.env <span class="p">|</span> head -1
</span></span><span class="line"><span class="cl"><span class="nv">MCP_TOKEN</span><span class="o">=</span>8c2f6a1b9e4d7c...   ← DIFFERENT</span></span></code></pre></div></div>
<p>Reproducible test in 30 seconds. Almost comical I didn&rsquo;t catch it sooner.</p>
<h2 id="the-lesson-idempotent-is-a-contract-not-a-hope">The lesson: &ldquo;idempotent&rdquo; is a contract, not a hope</h2>
<p>An installation script must be <strong>idempotent by default</strong>. Meaning: <code>./install.sh</code> once, twice, five times → system in the same stable state.</p>
<p>I had this contract <strong>in my head</strong>. I didn&rsquo;t have it <strong>in the code</strong>.</p>
<h2 id="the-fix-pre-flight-checks--explicit-force-flag">The fix: pre-flight checks + explicit force flag</h2>]]></description></item></channel></rss>