<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Web Hardening on brege.org</title>
    <link>https://brege.org/series/web-hardening/</link>
    <description>Recent content in Web Hardening on brege.org</description>
    <generator>Hugo</generator>
    <language>en</language>
    <copyright>Copyright (c) 2016-2026 Wyatt Brege</copyright>
    <lastBuildDate>Sun, 12 Apr 2026 21:44:40 -0400</lastBuildDate>
    <atom:link href="https://brege.org/series/web-hardening/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Updated Nginx configuration with Let&#39;s Encrypt headers</title>
      <link>https://brege.org/post/updated-nginx-conf-with-letsencrypt-headers/</link>
      <pubDate>Mon, 03 Apr 2017 15:06:38 -0700</pubDate>
      <guid>https://brege.org/post/updated-nginx-conf-with-letsencrypt-headers/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve added a new &lt;code&gt;security_headers.conf&lt;/code&gt; file in &lt;code&gt;/etc/nginx/&lt;/code&gt; to keep all the HTTPS headers in one place:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve added a new <code>security_headers.conf</code> file in <code>/etc/nginx/</code> to keep all the HTTPS headers in one place:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nginx" data-lang="nginx"><span class="line"><span class="cl">    <span class="k">ssl_session_timeout</span> <span class="s">1d</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">ssl_session_cache</span> <span class="s">shared:SSL:50m</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">ssl_session_tickets</span> <span class="no">off</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># intermediate configuration. tweak to your needs.
</span></span></span><span class="line"><span class="cl">    <span class="k">ssl_protocols</span> <span class="s">TLSv1</span> <span class="s">TLSv1.1</span> <span class="s">TLSv1.2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">ssl_ciphers</span> <span class="s">&#39;ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">ssl_prefer_server_ciphers</span> <span class="no">on</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># to score better grades on
</span></span></span><span class="line"><span class="cl">    <span class="c1">#  https://observatory.mozilla.org/analyze.html?host=brege.org
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">Strict-Transport-Security</span> <span class="s">&#34;max-age=15768000</span><span class="p">;</span> <span class="k">includeSubDomains</span><span class="p">;</span> <span class="k">preload&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">X-Frame-Options</span> <span class="s">&#34;SAMEORIGIN&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">X-Content-Type-Options</span> <span class="s">nosniff</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">X-XSS-Protection</span> <span class="s">&#34;1</span><span class="p">;</span> <span class="k">mode=block&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">X-Permitted-Cross-Domain-Policies</span> <span class="s">none</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">Content-Security-Policy</span> <span class="s">&#34;default-src</span> <span class="s">&#39;self&#39;</span><span class="p">;</span><span class="k">&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">Referrer-Policy</span> <span class="s">&#34;no-referrer,</span> <span class="s">strict-origin-when-cross-origin&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># OCSP Stapling ---
</span></span></span><span class="line"><span class="cl">    <span class="c1"># fetch OCSP records from URL in ssl_certificate and cache them
</span></span></span><span class="line"><span class="cl">    <span class="k">ssl_stapling</span> <span class="no">on</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">ssl_stapling_verify</span> <span class="no">on</span><span class="p">;</span>
</span></span></code></pre></div><p>We include the headers we obtained in the <a href="/post/getting-an-a-plus-on-mozilla-observatory/">last post</a> in here as well.  The main configuration file <code>/etc/nginx/brege.org</code> contains:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nginx" data-lang="nginx"><span class="line"><span class="cl"><span class="k">server</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kn">server_name</span> <span class="s">*.brege.org</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">return</span> <span class="s">http://brege.org/</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">server</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kn">listen</span> <span class="mi">80</span> <span class="s">default_server</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">listen</span> <span class="s">[::]:80</span> <span class="s">default_server</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">server_name</span>  <span class="s">brege.org</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># enforce https
</span></span></span><span class="line"><span class="cl">    <span class="kn">return</span> <span class="mi">301</span> <span class="s">https://</span><span class="nv">$host$request_uri</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">if</span> <span class="s">(</span><span class="nv">$scheme</span> <span class="s">!=</span> <span class="s">&#34;https&#34;)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kn">return</span> <span class="mi">301</span> <span class="s">https://</span><span class="nv">$host$request_uri</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="c1"># managed by Certbot
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">server</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kn">listen</span> <span class="mi">443</span> <span class="s">default</span> <span class="s">ssl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">listen</span> <span class="s">[::]:443</span> <span class="s">default</span> <span class="s">ssl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">root</span> <span class="s">/usr/share/nginx/brege.org</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">index</span> <span class="s">index.html</span> <span class="s">index.htm</span> <span class="s">index.php</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">server_name</span> <span class="s">brege.org</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">ssl_certificate</span> <span class="s">/etc/letsencrypt/live/brege.org/fullchain.pem</span><span class="p">;</span> <span class="c1"># managed by Certbot
</span></span></span><span class="line"><span class="cl">    <span class="kn">ssl_certificate_key</span> <span class="s">/etc/letsencrypt/live/brege.org/privkey.pem</span><span class="p">;</span> <span class="c1"># managed by Certbot
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">include</span> <span class="s">security_headers.conf</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">include</span> <span class="s">letsencrypt.conf</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">location</span> <span class="s">/</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># First attempt to serve request as file, then
</span></span></span><span class="line"><span class="cl">        <span class="c1"># as directory, then fall back to displaying a 404.
</span></span></span><span class="line"><span class="cl">        <span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri/</span> <span class="p">=</span><span class="mi">404</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">location</span> <span class="p">~</span> <span class="sr">^/(?:feed|feeds|rss)</span>  <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kn">return</span> <span class="mi">301</span> <span class="s">/index.xml</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Note that first server block does not work as expected.  On a separate instance, I tested this and confirmed that <a href="http://abc.mysite.org">http://abc.mysite.org</a> does get redirected to <a href="https://mysite.org">https://mysite.org</a>, but I think that since my site has been <a href="https://hstspreload.org/?domain=brege.org">HSTS Preloaded</a>, this doesn&rsquo;t allow <a href="http://abc.brege.org">http://abc.brege.org</a> to redirect to <a href="https://brege.org">https://brege.org</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Getting an A&#43; on Mozilla&#39;s HTTP Observatory</title>
      <link>https://brege.org/post/getting-an-a-plus-on-mozilla-observatory/</link>
      <pubDate>Mon, 09 Jan 2017 18:29:50 -0500</pubDate>
      <guid>https://brege.org/post/getting-an-a-plus-on-mozilla-observatory/</guid>
      <description>&lt;p&gt;After I learned about &lt;a href=&#34;https://github.com/mozilla/http-observatory&#34;&gt;Mozilla&amp;rsquo;s tool&lt;/a&gt; to test how secure your site is, I ran it on my site &lt;a href=&#34;https://observatory.mozilla.org/analyze.html?host=brege.org&#34;&gt;https://observatory.mozilla.org/analyze.html?host=brege.org&lt;/a&gt; and received an &amp;ldquo;&lt;strong&gt;F&lt;/strong&gt;&amp;rdquo;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>After I learned about <a href="https://github.com/mozilla/http-observatory">Mozilla&rsquo;s tool</a> to test how secure your site is, I ran it on my site <a href="https://observatory.mozilla.org/analyze.html?host=brege.org">https://observatory.mozilla.org/analyze.html?host=brege.org</a> and received an &ldquo;<strong>F</strong>&rdquo;.</p>
<p>After some trial &amp; error and searching around, I came up with the following to be placed in my Nginx <code>server{...}</code> block:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nginx" data-lang="nginx"><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">Strict-Transport-Security</span> <span class="s">&#34;max-age=15768000</span><span class="p">;</span> <span class="k">includeSubDomains</span><span class="p">;</span> <span class="k">preload&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">X-Frame-Options</span> <span class="s">&#34;SAMEORIGIN&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">X-Content-Type-Options</span> <span class="s">nosniff</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">X-XSS-Protection</span> <span class="s">&#34;1</span><span class="p">;</span> <span class="k">mode=block&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">X-Permitted-Cross-Domain-Policies</span> <span class="s">none</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">add_header</span> <span class="s">Content-Security-Policy</span> <span class="s">&#34;default-src</span> <span class="s">&#39;self&#39;</span><span class="p">;</span><span class="k">&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p>Now I am receiving an &ldquo;<strong>A+</strong>&rdquo; from the observatory!</p>
<p>I also went to <a href="https://hstspreload.org/">Google&rsquo;s submission page</a> to have your site put on the <a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security">HSTS</a> preloaded list, so that all users of Google Chrome access your site through HTTPS by default.</p>]]></content:encoded>
    </item>
    <item>
      <title>Automatic renewal of Let&#39;s Encrypt Certificates</title>
      <link>https://brege.org/post/automatic-renewal-of-letsencrypt/</link>
      <pubDate>Tue, 11 Oct 2016 00:15:22 +0000</pubDate>
      <guid>https://brege.org/post/automatic-renewal-of-letsencrypt/</guid>
      <description>&lt;p&gt;Let&amp;rsquo;s Encrypt certificates need to be renewed every three months.
&lt;a href=&#34;https://wiki.archlinux.org/index.php/Let%E2%80%99s_Encrypt#Automatic_renewal&#34;&gt;The Arch Wiki&lt;/a&gt; has good documentation on automating the renewal process with systemd.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Let&rsquo;s Encrypt certificates need to be renewed every three months.
<a href="https://wiki.archlinux.org/index.php/Let%E2%80%99s_Encrypt#Automatic_renewal">The Arch Wiki</a> has good documentation on automating the renewal process with systemd.</p>
<ul>
<li>In <code>/etc/systemd/system/certbot.service</code>:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Let&#39;s Encrypt renewal</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">Type</span><span class="o">=</span><span class="s">oneshot</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/bin/certbot renew --quiet --agree-tos</span>
</span></span></code></pre></div><ul>
<li>In <code>/etc/systemd/system/certbot.timer</code>:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Daily renewal of Let&#39;s Encrypt&#39;s certificates</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Timer]</span>
</span></span><span class="line"><span class="cl"><span class="na">OnCalendar</span><span class="o">=</span><span class="s">daily</span>
</span></span><span class="line"><span class="cl"><span class="na">RandomizedDelaySec</span><span class="o">=</span><span class="s">1day</span>
</span></span><span class="line"><span class="cl"><span class="na">Persistent</span><span class="o">=</span><span class="s">true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">timers.target</span>
</span></span></code></pre></div><ul>
<li>Enable and start the timer:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> certbot.timer
</span></span><span class="line"><span class="cl">sudo systemctl start certbot.timer
</span></span></code></pre></div>]]></content:encoded>
    </item>
  </channel>
</rss>
