<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Security on Such geek. Wow.</title><link>https://www.ericlight.com/tags/security.html</link><description>Recent content in Security on Such geek. Wow.</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 05 Jan 2022 00:00:00 +1300</lastBuildDate><atom:link href="https://www.ericlight.com/tags/security/index.xml" rel="self" type="application/rss+xml"/><item><title>Configuring a custom SSL certificate in Zentyal</title><link>https://www.ericlight.com/post/zentyal_ssl.html</link><pubDate>Sun, 25 Apr 2021 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/zentyal_ssl.html</guid><description>&lt;p&gt;Zuper-quick post for when this bites me again in the future!&lt;/p&gt;
&lt;p&gt;Tonight I upgraded from Zentyal 6.2 to Zentyal 7.0. Smooth as butter, everything went great.&lt;/p&gt;
&lt;p&gt;Until I logged in, and my shiny Actual Paid Money SSL certificate had vanished, replaced by a self-signed commoner&amp;rsquo;s certificate. Piffle.&lt;/p&gt;
&lt;p&gt;Instructions for installing a custom SSL certificate in Zentyal are actually kinda shaky, so here you go:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd /var/lib/zentyal/conf/ssl/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir old
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mv * old
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;nano ssl.key
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;nano ssl.cert
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cat ssl.cert ssl.key &amp;gt; ssl.pem
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chmod &lt;span style="color:#ae81ff"&gt;0400&lt;/span&gt; ssl*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s it! Your Private Key lives in &lt;code&gt;ssl.key&lt;/code&gt;, and your SSL certificate lives in &lt;code&gt;ssl.cert&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Reboot, and job done.&lt;/p&gt;</description></item><item><title>Blocking bad extensions and extortion with iRedMail</title><link>https://www.ericlight.com/post/iredmail.html</link><pubDate>Mon, 12 Apr 2021 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/iredmail.html</guid><description>&lt;p&gt;Turns out this is my third Amavis article. I guess it&amp;rsquo;s just one of those systems.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Heads up, if you&amp;rsquo;re trying to do this, make sure you also read &lt;a class="link" href="https://www.ericlight.com/post/amavis2.html" &gt;my other article&lt;/a&gt; about the &amp;ldquo;banned_files_lover&amp;rdquo; thing.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Today I&amp;rsquo;m on a mission to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Drop all incoming Office &amp;lsquo;97 files (they&amp;rsquo;re predominantly malicious these days)&lt;/li&gt;
&lt;li&gt;Drop all incoming Macro-enabled Office 2007+ files (there aren&amp;rsquo;t legitimate reasons to receive these &lt;em&gt;in my scenario&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Drop any emails containing a .onion address&lt;/li&gt;
&lt;li&gt;Drop any emails containing a bitcoin wallet&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="dropping-attachments"&gt;Dropping Attachments
&lt;/h2&gt;&lt;p&gt;The attachment block is easily handled by Amavis. In iRedMail on Debian, the configuration file is found at &lt;code&gt;/etc/amavis/conf.d/50-user&lt;/code&gt;. Open your config file, and scroll down to the section where the &lt;code&gt;$banned_filename_re&lt;/code&gt; variable is set. Insert the following line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; qr&amp;#39;.\.(doc|dot|docm|docb|xls|xlm|xlt|xlsm|xlsb|
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; xla|xlam|ppt|pps|pptm|potm|ppam|ppsm|sldm)$&amp;#39;i, # Office &amp;#39;97-2003 and Macro-enabled files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; qr&amp;#39;.\.(adn|accdb|accdr|accdt|accda|mdw|accde|mam|maq|mar|mat|
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; maf|laccdb|ade|adp|mdb|cdb|mda|mdn|mdt|mdf|mde|ldb)$&amp;#39;i, # Microsoft Access files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; qr&amp;#39;^\.pub$&amp;#39;, # Microsoft Publisher files
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That will block all core Office &amp;lsquo;97-2003 files, as well as all Macro-enabled Office 2007-365 files.&lt;/p&gt;
&lt;p&gt;By default, this will &lt;strong&gt;silently&lt;/strong&gt; reject mails containing these attachments. If you want senders to receive a bounce message, search for the &lt;code&gt;$final_banned_destiny&lt;/code&gt; variable and make sure it&amp;rsquo;s set to &lt;code&gt;D_BOUNCE&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="dropping-onion-and-btc"&gt;Dropping .onion and BTC
&lt;/h2&gt;&lt;p&gt;This part happens in Postfix, and it&amp;rsquo;s more-super-easy than the last bit. To configure Postfix&amp;rsquo;s body checks, edit &lt;code&gt;/etc/postfix/body_checks.pcre&lt;/code&gt;. I simply added the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/(\w+\.onion)/ REJECT This mail server does not accept references to .onion addresses (${1})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/(\b(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39})/ DISCARD Bitcoin wallet detected (${1})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I used the REJECT directive for testing, but to be honest I don&amp;rsquo;t want to send bounces back to these people, so I changed to DISCARD after it was working. You can see the difference above.&lt;/p&gt;
&lt;p&gt;The text after the REJECT directive is returned to the sender, and the text after the DISCARD directive is logged. The variable &lt;code&gt;${1}&lt;/code&gt; contains the detected string, and is appended to the response message.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the end! Safety. Yes.&lt;/p&gt;
&lt;h1 id="acknowledgements"&gt;Acknowledgements
&lt;/h1&gt;&lt;p&gt;Thanks to Brad and Hamish for this post - Brad for the regex, Hamish for the idea, and both of them for the review!&lt;/p&gt;</description></item><item><title>Using Caddy to enable MTA-STS</title><link>https://www.ericlight.com/post/caddy-mta-sts.html</link><pubDate>Tue, 19 Jan 2021 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/caddy-mta-sts.html</guid><description>&lt;p&gt;About 7 months ago, I left Nginx and &lt;a class="link" href="https://www.ericlight.com/post/caddy.html" &gt;moved to Caddy&lt;/a&gt;. I&amp;rsquo;ve found it super easy, and have now experienced using it as a reverse proxy, a static site server (this one!), as well as a hosting a &lt;a class="link" href="https://shrug.ericlight.com" target="_blank" rel="noopener"
 &gt;handy place&lt;/a&gt; for me to copy my favourite &lt;a class="link" href="http://kaomoji.ru" target="_blank" rel="noopener"
 &gt;Kaomoji&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update 2021-01-20&lt;/strong&gt;&lt;/em&gt;: I had a bug! By default, Caddy serves this without a Content-Type header. However, the &lt;a class="link" href="https://tools.ietf.org/html/rfc8461#section-3.2" target="_blank" rel="noopener"
 &gt;RFC&lt;/a&gt; specifies that the response should be explicitly &lt;code&gt;Content-Type &amp;quot;text/plain&amp;quot;&lt;/code&gt;. Thanks to &lt;a class="link" href="https://github.com/klausenbusk/" target="_blank" rel="noopener"
 &gt;klausenbusk&lt;/a&gt; for letting me know!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: the Caddyfile fragment to generate &lt;a class="link" href="https://shrug.ericlight.com" target="_blank" rel="noopener"
 &gt;https://shrug.ericlight.com&lt;/a&gt; looks like this:&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;shrug.ericlight.com { respond &amp;#34;&amp;lt;meta charset=&amp;#39;UTF-8&amp;#39;&amp;gt;¯\_(ツ)_/¯&amp;#34; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Anyway, once I&amp;rsquo;d used Caddy&amp;rsquo;s &lt;code&gt;respond&lt;/code&gt; directive, it was a simple step to take it forward and use it to serve my handy-dandy MTA-STS policy file!&lt;/p&gt;
&lt;p&gt;Simply add this new Server block to your Caddyfile:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mta-sts.ericlight.com {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;respond &amp;#34;version: STSv1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mode: testing
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mx: in1-smtp.messagingengine.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mx: in2-smtp.messagingengine.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;max_age: 86401&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;header Content-Type &amp;#34;text/plain; charset=utf-8&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This simple Server block will get you a shiny HTTPS certificate, redirect any HTTP visitors to HTTPS, and will provide enquirers with your MTA policy file. &lt;em&gt;(Obviously, replace my domain name and MX entries with your own.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Sharp observers will notice that the MTA-STS policy file should be hosted at &lt;code&gt;https://mta-sts.ericlight.com/.well-known/mta-sts.txt&lt;/code&gt;&amp;hellip; but that&amp;rsquo;s the elegance of the Respond directive in Caddy: &lt;em&gt;wherever&lt;/em&gt; you go at &lt;code&gt;mta-sts.ericlight.com&lt;/code&gt;, you get exactly that response!&lt;/p&gt;
&lt;p&gt;Example: &lt;a class="link" href="https://mta-sts.ericlight.com/my/hovercraft/is/full/of/eels.txt" target="_blank" rel="noopener"
 &gt;https://mta-sts.ericlight.com/my/hovercraft/is/full/of/eels.txt&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Okay, that was easy&amp;hellip; the next part is just creating your &lt;em&gt;&lt;strong&gt;three&lt;/strong&gt;&lt;/em&gt; DNS records:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Record #1:&lt;/strong&gt; An A record for &lt;code&gt;mta-sts.ericlight.com&lt;/code&gt;, pointing to your Caddy server.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Record #2:&lt;/strong&gt; A TXT record at &lt;code&gt;_mta-sts.ericlight.com&lt;/code&gt;, reading &lt;code&gt;v=STSv1; id=20210112&lt;/code&gt;. (Note the underscore! Also, the ID can be anything.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Record #3:&lt;/strong&gt; A TXT record at &lt;code&gt;_smtp._tls.ericlight.com&lt;/code&gt;, reading &lt;code&gt;v=TLSRPTv1; rua=mailto:tls-reports@targetdomain.com&lt;/code&gt;. (update that email address)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;hellip; There you go! Now you have a shiny new MTA-STS policy, and your Reporting email target (configured in DNS Record #3) will start reciving daily reports from sending mail servers, letting you know if your policy is working correctly.&lt;/p&gt;
&lt;p&gt;Eventually (once you&amp;rsquo;re sure it&amp;rsquo;s all configured properly), you should change your &lt;code&gt;testing&lt;/code&gt; policy to &lt;code&gt;enforce&lt;/code&gt;. When you do this, &lt;strong&gt;make sure you update the ID in your TXT Record!&lt;/strong&gt; This is how sending mail servers know that there has been a policy update.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;</description></item><item><title>Logging DNS queries, for both pfSense and Zentyal server</title><link>https://www.ericlight.com/post/zentyal_querylogging.html</link><pubDate>Sun, 06 Dec 2020 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/zentyal_querylogging.html</guid><description>&lt;p&gt;Logs of your client DNS queries can be a really good tool for incident response. I&amp;rsquo;ve finally got this implemented but it was much more of a struggle than I expected it to be, so here&amp;rsquo;s my story!&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve got a pfSense firewall running as a DNS fowarder, and a &lt;a class="link" href="https://www.zentyal.com" target="_blank" rel="noopener"
 &gt;Zentyal&lt;/a&gt; server running BIND9 as the authoritative local server. The firewall rules block all UDP/53, so all DNS queries go either directly to the firewall, or (more commonly) to the Zentyal server for resolution. This means we have two places that resolve DNS queries which we want to forward off to our syslog server.&lt;/p&gt;
&lt;h2 id="pfsense"&gt;pfSense
&lt;/h2&gt;&lt;p&gt;Unbound is a &lt;em&gt;super&lt;/em&gt; simple DNS forwarder, and the configuration is wonderfully straightforward. It did take me quite a while to figure it out, but in the end it was a simple oversight on my part.&lt;/p&gt;
&lt;p&gt;To get pfSense/Unbound to forward DNS queries to your syslog server, simply open the Services -&amp;gt; DNS Resolver page, click &amp;lsquo;Display Custom options&amp;rsquo;, and add these two lines:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::ini
server:
log-queries: yes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I spent hours fiddling before I realised I was missing the empty &amp;ldquo;server:&amp;rdquo; directive. -__-&lt;/p&gt;
&lt;p&gt;This will log all DNS queries that Unbound deals with. These logs go to the standard internal pfSense log; if you want them to be replicated off to an external syslog server, go Status -&amp;gt; System Logs -&amp;gt; Settings. Scroll down to the &amp;ldquo;Remote Log Servers&amp;rdquo; section and add your syslog server there. (I&amp;rsquo;m not covering syslog listener config in this particualar post!)&lt;/p&gt;
&lt;h2 id="zentyal"&gt;Zentyal
&lt;/h2&gt;&lt;p&gt;Yeah this one was harder to figure out. Because Zentyal overwrites the config at &lt;em&gt;every damn opportunity&lt;/em&gt;, you can&amp;rsquo;t just edit &lt;code&gt;/etc/bind/named.conf.options&lt;/code&gt;, like what you find in &lt;a class="link" href="https://www.thegeekdiary.com/how-to-enable-bind-query-logging-to-find-out-whos-querying-a-name-server/" target="_blank" rel="noopener"
 &gt;most articles&lt;/a&gt;&amp;hellip; it may work for a moment, but it&amp;rsquo;ll be overwritten.&lt;/p&gt;
&lt;p&gt;The real answer to editing Zentyal&amp;rsquo;s config files is outlined at &lt;a class="link" href="https://doc.zentyal.org/en/appendix-c.html#stubs" target="_blank" rel="noopener"
 &gt;https://doc.zentyal.org/en/appendix-c.html#stubs&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
cp /usr/share/zentyal/stubs/dns/named.conf.options.mas /etc/zentyal/stubs/dns/named.conf.options.mas
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once you&amp;rsquo;ve copied the stub into a place where it won&amp;rsquo;t be clobbered, edit it and zoom right down to the bottom line, which looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::ini
logging { category lame-servers { null; }; };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the line you need to replace. Now, you can go as ham as you want here. I&amp;rsquo;ve actually used the sample provided by ISC themselves, which you can find at &lt;a class="link" href="https://kb.isc.org/docs/aa-01526" target="_blank" rel="noopener"
 &gt;https://kb.isc.org/docs/aa-01526&lt;/a&gt;. However, that&amp;rsquo;s really robust and possibly more than you may need. A bare minimum would probably look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::ini
logging { 
 channel queries_log {
 syslog named;
 print-time yes;
 print-category yes;
 print-severity yes;
 severity info;
 };
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note - when I tried to use the ISC sample wholesale, I needed to change a couple small things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Changed all &lt;code&gt;/var/named/log&lt;/code&gt; output destinations to &lt;code&gt;/var/log/named&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The lines for &lt;code&gt;category zoneload&lt;/code&gt; and &lt;code&gt;category trust-anchor-telemetry&lt;/code&gt; need to be removed for Zentyal 6.2&amp;rsquo;s version of BIND9&lt;/li&gt;
&lt;li&gt;I needed to create &lt;code&gt;/var/log/named&lt;/code&gt;, and make sure it was writeable by the bind user&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I think that covers it, I hope this helps someone! I&amp;rsquo;ve actually even taken the time today to create a &lt;a class="link" href="https://github.com/zentyal/zentyal/pull/2005" target="_blank" rel="noopener"
 &gt;Pull Request&lt;/a&gt; in the Zentyal GitHub, we&amp;rsquo;ll see if it ends up getting merged!&lt;/p&gt;</description></item><item><title>iRedMail, SpamAssassin, and Lynis</title><link>https://www.ericlight.com/post/iredmail-lynis.html</link><pubDate>Mon, 02 Nov 2020 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/iredmail-lynis.html</guid><description>&lt;p&gt;I really like iRedMail, and I also really like Lynis.&lt;/p&gt;
&lt;p&gt;However, they don&amp;rsquo;t exactly like &lt;em&gt;each other&lt;/em&gt;&amp;hellip; or, more accurately, some of Lynis&amp;rsquo; recommendations can cause a couple iRedMail components to fail. Today we&amp;rsquo;re talking about SpamAsassin.&lt;/p&gt;
&lt;p&gt;One of the suggestions from Lynis is to turn off the &amp;rsquo;execute&amp;rsquo; bit on compilers for users who aren&amp;rsquo;t either the owner or in the owner group (the &amp;lsquo;other&amp;rsquo; execute bit). For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
root@server:/# chmod o-x /usr/bin/as
root@server:/# chmod o-x /usr/bin/gcc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Easy peasy! But once you do this, you might start getting the following in your daily iRedMail Cron reports:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::text
/etc/cron.daily/spamassassin:
/bin/sh: 1: x86_64-linux-gnu-gcc: Permission denied
make: *** [Makefile:346: body_0.o] Error 126
command 'make PREFIX=/tmp/.spamassassin23046Zmmrr9tmp/ignored INSTALLSITEARCH=/var/lib/spamassassin/compiled/5.028/3.004002 &amp;gt;&amp;gt;/tmp/.spamassassin23046Zmmrr9tmp/log' failed: exit 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are probably a bunch of ways to fix this. My way, I&amp;rsquo;m sure, is not the best way&amp;hellip; however it was quick and easy, and it worked.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
root@server:/# chgrp debian-spamd /usr/bin/as
root@server:/# chgrp debian-spamd /usr/bin/gcc
root@server:/# runuser -l debian-spamd -c sa-compile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Look ma, no more errors!&lt;/p&gt;
&lt;p&gt;This solution really &lt;em&gt;only&lt;/em&gt; works for me because debian-spamd is the only non-root user that calls these compilers. If I had another user which needed to call them, I&amp;rsquo;d have to come up with a better fix. But for a standalone iRedMail server, this does the trick!&lt;/p&gt;</description></item><item><title>Why are all Split-Tunnel VPN diagrams so ugly?</title><link>https://www.ericlight.com/post/split-tunnel-image.html</link><pubDate>Thu, 21 May 2020 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/split-tunnel-image.html</guid><description>&lt;img src="https://www.ericlight.com/post/split-tunnel-image/split_tunnel_yes.jpg" alt="Featured image of post Why are all Split-Tunnel VPN diagrams so ugly?" /&gt;&lt;p&gt;Right.&lt;/p&gt;
&lt;p&gt;Today I needed to find a diagram of the traffic flow for a split-tunnel VPN. Nothing fancy, just a real simple user-facing diagram to form part of an article.&lt;/p&gt;
&lt;p&gt;And friends, there was &lt;em&gt;nothing&lt;/em&gt;. Nothing at all. I found proper technical ones from &lt;a class="link" href="https://documentation.meraki.com/@api/deki/files/721/c6ddeaa8-5df4-4e5e-b542-c52766568816?revision=1" target="_blank" rel="noopener"
 &gt;Cisco Meraki&lt;/a&gt;; fancy Office365 ones, depicting an &lt;a class="link" href="https://docs.microsoft.com/en-us/office365/enterprise/media/vpn-split-tunneling/vpn-model-2.png" target="_blank" rel="noopener"
 &gt;ExpressRoute to O365&lt;/a&gt; and tunnelling everything &lt;em&gt;else&lt;/em&gt; through the VPN; and another Office365 tunnel with &lt;a class="link" href="https://docs.microsoft.com/en-us/office365/enterprise/media/vpn-split-tunneling/vpn-model-5.png" target="_blank" rel="noopener"
 &gt;ExpressRoute and a split-tunnel&lt;/a&gt; for the rest of the traffic.&lt;/p&gt;
&lt;p&gt;Pretty much the closest I came to my needs was this atrocity, via &lt;a class="link" href="http://blog.soundtraining.net/2013/03/how-to-configure-split-tunneling-on.html" target="_blank" rel="noopener"
 &gt;http://blog.soundtraining.net/2013/03/how-to-configure-split-tunneling-on.html&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="An accurate, but not aesthetic, diagram of how split tunnels work." class="gallery-image" data-flex-basis="158px" data-flex-grow="66" data-title-escaped="Although accurate and functional, this is not a pleasant sight." height="1600" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.ericlight.com/post/split-tunnel-image/split_tunnel_yes.jpg" srcset="https://www.ericlight.com/post/split-tunnel-image/split_tunnel_yes_hu_cb0dc953174bedbc.jpg 800w, https://www.ericlight.com/post/split-tunnel-image/split_tunnel_yes.jpg 1059w" title="Although accurate and functional, this is not a pleasant sight." width="1059"&gt;&lt;/p&gt;
&lt;p&gt;So I went over to &lt;a class="link" href="https://www.draw.io" target="_blank" rel="noopener"
 &gt;https://www.draw.io&lt;/a&gt; and whipped up something a bit prettier. This isn&amp;rsquo;t marvelous, but it&amp;rsquo;s way better than I could find anywhere else:&lt;/p&gt;
&lt;p&gt;&lt;img alt="A slightly more pleasant diagram of how split tunnels work." class="gallery-image" data-flex-basis="382px" data-flex-grow="159" height="301" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.ericlight.com/post/split-tunnel-image/split_tunnel_better.png" width="480"&gt;&lt;/p&gt;
&lt;p&gt;In retrospect, I could have done better - I really should have had the corporate tunnel going &lt;strong&gt;through&lt;/strong&gt; the cloud of the internet. However this works for ne.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d like to use this, feel free. You can even use &lt;a class="link" href="https://app.diagrams.net/?lightbox=1&amp;amp;highlight=0000ff&amp;amp;edit=_blank&amp;amp;layers=1&amp;amp;nav=1&amp;amp;title=VPN%20Split%20Tunnel%282%29.drawio#R7Vddb5swFP01PCbCfCV5XJKmU9VKrSp1W1%2BQAzdgxWBkTCD99TPFTiCwtZMSdZWqRMI%2B9%2Foa33Nscw17kVTXHGfxHQuBGpYZVoa9NCwLOZZl1H8z3DeIN7MbIOIkbCDzCDySF1AjNVqQEHKFNZBgjAqSdcGApSkEooNhzlnZddswGnaADEfQAx4DTPvoDxKKWKGe6xwN34FEsZ4aebPGkmDtrZaSxzhkZSusfWXYC86YaFpJtQBaZ6%2BbmNUfrIc345CK9wy4dZ9vls8%2F4e7p9uEO3QTldTQaKTZ2mBZqxeplxV6nIGMkFcCvdnKeOpvIsOeHtZiyE%2BI8hlB1YpFQ7SQ428KCUcYlkrJUBpxvCKUaMizbNeufxCleA71nORGEpdIWQD2pNOyACyIJuT1xWDMhWNJy%2BEZJVBsEyyTKCkFJKmfXuqgnwcrlEFyuI6uXmVRRrd8x22xIAOMQdvKRj0vGt7nAzYzzfsIVB%2FUbQHXKrNwTwBIQfC9dlNX2lBjUdrBnql8exaV3SNySlXbDSs7RIfKRcNlQnP8D%2F84F%2Bf%2BvKM2By6i5evobzJO%2BGlerqWOaPem2LWcQgTc9EcG0LwJkeX0VIHQpGUy%2BjoFBzQQFJ2I%2FpizY%2BiURsb%2BFva9hf%2F2arXNIwnVOz4VpTxL66GgrYuJcSBCzzy%2BIQeqHVfJeQQSUFWE%2Bzoo1JYH%2F2jsP%2F84MdfiXX079I2EyIABkowspQJ81n1kCF7xHRCFHU18uBDdszDnTXwrLEZqe6a5wJt2DwXH6d4U7G9DFpW4KhL5k8fGy8NDHyYK%2F4EfysCrTnefSp8p9iX%2FxkfW2KnTmNhSqb3VpJlMBaaiay4DiPCdBVxDSrssuNG36qkZ0x7b1t1wKzCMQb99wEHYKwH7G2xkdOIA1xoFKmnfdsnEozWqG%2B3qPtPa55XQJNb1uiJwVPAA1ql3lnQaadAPZ7kmgJjG9QK%2BsH5Y9JATZPRarjfux5revfgM%3D" target="_blank" rel="noopener"
 &gt;this fancy URL&lt;/a&gt; to open the drawing as an editable vector graphic at &lt;a class="link" href="https://www.draw.io" target="_blank" rel="noopener"
 &gt;Draw.io&lt;/a&gt; directly!&lt;/p&gt;</description></item><item><title>Using Fail2Ban to insta-block malicious hits</title><link>https://www.ericlight.com/post/caddy_fail2ban.html</link><pubDate>Tue, 07 Apr 2020 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/caddy_fail2ban.html</guid><description>&lt;p&gt;Okay so a few days ago I &lt;a class="link" href="https://www.ericlight.com/post/caddy.html" &gt;posted&lt;/a&gt; about adopting &lt;a class="link" href="https://www.caddyserver.com" target="_blank" rel="noopener"
 &gt;Caddy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Of course, anyone who hosts anything knows that accessible services on the internet will start getting hit by scanners within literal moments of being accessible. On the very first night of having my site live on the new VPS, Logwatch informed me of a bunch of attempts to access wp-admin.php. Sigh.&lt;/p&gt;
&lt;p&gt;Well, this entire site is built with my favourite static site generator &lt;a class="link" href="https://www.getpelican.com" target="_blank" rel="noopener"
 &gt;Pelican&lt;/a&gt;. That means I don&amp;rsquo;t have any PHP on my site whatsoever. Why not just&amp;hellip; block anyone that tries to open a PHP page at ericlight.com? &lt;a class="link" href="https://www.fail2ban.org" target="_blank" rel="noopener"
 &gt;Fail2Ban&lt;/a&gt; to the rescue.&lt;/p&gt;
&lt;p&gt;Two things we need: A Fail2Ban filter, and a Fail2Ban jail.&lt;/p&gt;
&lt;h2 id="the-filter"&gt;The Filter
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;nano /etc/fail2ban/filter.d/caddy-php.conf&lt;/code&gt; &lt;em&gt;(note, the name of this file must be the same as the identifier in your &lt;code&gt;jail.local&lt;/code&gt; file)&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;[Definition]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;failregex&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;^&amp;lt;HOST&amp;gt;.*\.php(\s|\?.*)HTTP.*$&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ignoreregex&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; that will catch anything in your logs such as:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;nn.nn.nn.nn - - [07/Apr/2020:23:20:39 +1200] &amp;#34;GET /wp-admin.php HTTP/2.0&amp;#34; 404 0
nn.nn.nn.nn - - [06/Apr/2020:10:12:24 +1200] &amp;#34;GET /index.php?s=index/%5Cthink%5Capp/invokefunction&amp;amp;function=call_user_func_array&amp;amp;vars%5B0%5D=phpinfo&amp;amp;vars%5B1%5D%5B%5D=1 HTTP/1.1&amp;#34; 404 0
nn.nn.nn.nn - - [06/Apr/2020:12:51:31 +1200] &amp;#34;GET /wp-login.php HTTP/1.1&amp;#34; 404 0
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="the-jail"&gt;The Jail
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;nano /etc/fail2ban/jail.local&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;[caddy-php]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;port&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;http,https&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;logpath&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/var/log/caddy/access.log&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;enabled&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;maxretry&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note I used &lt;code&gt;maxretry = 1&lt;/code&gt; there. This means if an IP triggers that filter &lt;em&gt;a single time&lt;/em&gt;, they&amp;rsquo;ll be blocked &lt;strong&gt;immediately&lt;/strong&gt;&amp;hellip; So you probably don&amp;rsquo;t want to do this just willy-nilly.&lt;/p&gt;
&lt;h2 id="the-result"&gt;The Result
&lt;/h2&gt;&lt;p&gt;With those two parts done (and the obligatory &lt;code&gt;service fail2ban reload&lt;/code&gt;, of course), you should find that your web server immediately bans any host that tries to load a .php file from your website!&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-log" data-lang="log"&gt;# tail -f /var/log/caddy/access.log /var/log/fail2ban.log
==&amp;gt; /var/log/caddy/access.log &amp;lt;==
1xx.1xx.1xx.11 - - [07/Apr/2020:23:25:55 +1200] &amp;#34;GET /arse.php HTTP/1.1&amp;#34; 404 0
1xx.1xx.1xx.6 - - [07/Apr/2020:23:25:57 +1200] &amp;#34;GET /arse.php?1234 HTTP/1.1&amp;#34; 404 0
1xx.2xx.6x.1xx - - [07/Apr/2020:23:26:03 +1200] &amp;#34;GET /blargh.php HTTP/2.0&amp;#34; 404 0

==&amp;gt; /var/log/fail2ban.log &amp;lt;==
2020-04-07 23:25:55,482 fail2ban.filter [452]: INFO [caddy-php] Found 1xx.1xx.1xx.11 - 2020-04-07 23:25:55
2020-04-07 23:25:55,551 fail2ban.actions [452]: NOTICE [caddy-php] Ban 1xx.1xx.1xx.11
2020-04-07 23:25:58,309 fail2ban.filter [452]: INFO [caddy-php] Found 1xx.1xx.1xx.6 - 2020-04-07 23:25:57
2020-04-07 23:25:58,782 fail2ban.actions [452]: NOTICE [caddy-php] Ban 1xx.1xx.1xx.6
2020-04-07 23:26:03,627 fail2ban.filter [452]: INFO [caddy-php] Found 1xx.2xx.6x.1xx - 2020-04-07 23:26:03
2020-04-07 23:26:04,010 fail2ban.actions [452]: NOTICE [caddy-php] Ban 1xx.2xx.6x.1xx
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Great success! You can use the &lt;code&gt;banTime&lt;/code&gt; directive to adjust how long these blocks should last for - I&amp;rsquo;ve got mine set up to block for an hour.&lt;/p&gt;
&lt;h2 id="edit-2020-04-10"&gt;Edit 2020-04-10:
&lt;/h2&gt;&lt;p&gt;Eh I realised that my RegEx missed these lovely things:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-log" data-lang="log"&gt;[ip redacted] - - [08/Apr/2020:16:14:10 +1200] &amp;#34;GET /wp-config.php.new HTTP/1.1&amp;#34; 404 0
[ip redacted] - - [08/Apr/2020:16:14:14 +1200] &amp;#34;GET /wp-config.php.old HTTP/1.1&amp;#34; 404 0
[ip redacted] - - [08/Apr/2020:16:14:17 +1200] &amp;#34;GET /wp-config.php.bak HTTP/1.1&amp;#34; 404 0
[ip redacted] - - [08/Apr/2020:16:14:19 +1200] &amp;#34;GET /wp-config.php.backup HTTP/1.1&amp;#34; 404 0
[ip redacted] - - [08/Apr/2020:16:14:22 +1200] &amp;#34;GET /wp-config.php.save HTTP/1.1&amp;#34; 404 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;hellip; so yeah I just changed it to drop anything with &lt;code&gt;.php&lt;/code&gt; in the URL. I&amp;rsquo;ll try to remember not to post any articles with .php in the URL lol.&lt;/p&gt;
&lt;h2 id="credits"&gt;Credits
&lt;/h2&gt;&lt;p&gt;Thanks to Phage and Xyphoid for the help in fine-tuning my rusty RegEx!&lt;/p&gt;</description></item><item><title>Moving to the Caddy web server</title><link>https://www.ericlight.com/post/caddy.html</link><pubDate>Sun, 05 Apr 2020 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/caddy.html</guid><description>&lt;p&gt;For the last couple of years I&amp;rsquo;ve been running this site, as well as my friend&amp;rsquo;s site (&lt;a class="link" href="https://www.undertheumbrella.co.nz" target="_blank" rel="noopener"
 &gt;Under The Umbrella&lt;/a&gt;) on &lt;a class="link" href="https://www.nginx.org" target="_blank" rel="noopener"
 &gt;Nginx&lt;/a&gt;. Recently my VPS host decided to do away with their cheapest tier, so instead of doubling my annual cost, I hopped onto &lt;a class="link" href="https://www.lowendbox.com" target="_blank" rel="noopener"
 &gt;https://www.lowendbox.com&lt;/a&gt; and found myself a replacement Cheaps McGee VPS to host this.&lt;/p&gt;
&lt;p&gt;Well, a major change like that is a great time to learn about something new, so I took the opportunity to get started with &lt;a class="link" href="https://www.caddyserver.com" target="_blank" rel="noopener"
 &gt;Caddy&lt;/a&gt;. If you don&amp;rsquo;t already know about Caddy, it&amp;rsquo;s a fast, simple, &lt;em&gt;clean&lt;/em&gt; web server. It&amp;rsquo;s written in Go, so it&amp;rsquo;s both fast and memory safe. And hey, it&amp;rsquo;s super simple.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not going to go into a whole lot of detail about setting up Caddy - there are enough tutorials out there already, and really I got all the info I needed from the website. But here are some particularly notable bits:&lt;/p&gt;
&lt;h1 id="the-caddyfile"&gt;The Caddyfile
&lt;/h1&gt;&lt;p&gt;This lives in &lt;code&gt;/etc/caddy/Caddyfile&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ericlight.com, www.ericlight.com {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;file_server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;root * /var/www/ericlight.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;import /etc/caddy/caddy_security.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;log {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;output file /var/log/caddy/access.log&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;format single_field common_log&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;undertheumbrella.co.nz, www.undertheumbrella.co.nz {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;file_server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;root * /var/www/undertheumbrella.co.nz&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;import /etc/caddy/caddy_security.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;log {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;output file /var/log/caddy/utu_access.log&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;format single_field common_log&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And, &lt;code&gt;/etc/caddy/caddy_security.conf&lt;/code&gt; contains:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;header {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Strict-Transport-Security &amp;#34;max-age&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;31536000; includeSubDomains; preload&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; X-Xss-Protection &amp;#34;1; mode=block&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; X-Content-Type-Options &amp;#34;nosniff&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; X-Frame-Options &amp;#34;DENY&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Content-Security-Policy &amp;#34;upgrade-insecure-requests&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Referrer-Policy &amp;#34;strict-origin-when-cross-origin&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Cache-Control &amp;#34;public, max-age=15, must-revalidate&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Feature-Policy &amp;#34;accelerometer &amp;#39;none&amp;#39;; ambient-light-sensor &amp;#39;none&amp;#39;; autoplay &amp;#39;self&amp;#39;; camera &amp;#39;none&amp;#39;; encrypted-media &amp;#39;none&amp;#39;; fullscreen &amp;#39;self&amp;#39;; geolocation &amp;#39;none&amp;#39;; gyroscope &amp;#39;none&amp;#39;; magnetometer &amp;#39;none&amp;#39;; microphone &amp;#39;none&amp;#39;; midi &amp;#39;none&amp;#39;; payment &amp;#39;none&amp;#39;; picture-in-picture *; speaker &amp;#39;none&amp;#39;; sync-xhr &amp;#39;none&amp;#39;; usb &amp;#39;none&amp;#39;; vr &amp;#39;none&amp;#39;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;** Update 2022-01-05:** Previously I&amp;rsquo;d used &lt;code&gt;header / {&lt;/code&gt; above; that should have been simply &lt;code&gt;header {&lt;/code&gt;. Thanks &lt;a class="link" href="https://twitter.com/JoHoffmann8" target="_blank" rel="noopener"
 &gt;@JoHoffmann8&lt;/a&gt; for pointing this out! It&amp;rsquo;s also worth mentioning that Caddy are deprecating the &lt;code&gt;common_log&lt;/code&gt; log format, which makes me sad in one way, but I do get it - the Caddy json log file format is far richer, but I liked the easily-ingested syslog format. ¯\_(ツ)_/¯&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Ok so here&amp;rsquo;s the thing. Caddy really seems to implement Python&amp;rsquo;s ethos of &amp;ldquo;Batteries Included&amp;rdquo;. The above contents are enough on their own to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Host two separate static websites&lt;/li&gt;
&lt;li&gt;Offer two subdomains for each of these websites&lt;/li&gt;
&lt;li&gt;Manage the entire certificate creation and renewal process from &lt;a class="link" href="https://www.letsencrypt.org" target="_blank" rel="noopener"
 &gt;Let&amp;rsquo;s Encrypt&lt;/a&gt; for two sites, plus subdomains.&lt;/li&gt;
&lt;li&gt;Get an A+ rating on both &lt;a class="link" href="https://www.ssllabs.com/ssltest/" target="_blank" rel="noopener"
 &gt;SSL Labs&lt;/a&gt; and &lt;a class="link" href="https://www.securityheaders.io" target="_blank" rel="noopener"
 &gt;SecurityHeaders.io&lt;/a&gt;(!!)&lt;/li&gt;
&lt;li&gt;And, of course, zoink all the logs into separate files under /var/log/caddy&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="creating-a-caddy-service-file"&gt;Creating a Caddy Service file
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;UPDATE 2020-05-07: With the release of Caddy 2.0, it appears a regular &lt;code&gt;dpkg -i caddy.deb&lt;/code&gt; will take care of creating the caddy.service file&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;If you&amp;rsquo;re running Debian, you&amp;rsquo;ll need to create yourself a service file for systemd, so you can get your server to launch Caddy on boot. I got mine from &lt;a class="link" href="https://github.com/caddyserver/dist/tree/master/init" target="_blank" rel="noopener"
 &gt;https://github.com/caddyserver/dist/tree/master/init&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/systemd/system/caddy.service&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# This service file requires the following:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 1) Group named caddy:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# $ groupadd --system caddy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2) User named caddy, with a writeable home folder:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# $ useradd --system \&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# --gid caddy \&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# --create-home \&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# --home-dir /var/lib/caddy \&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# --shell /usr/sbin/nologin \&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# --comment &amp;#34;Caddy web server&amp;#34; \&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# caddy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3) Caddyfile at /etc/caddy/Caddyfile that is&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# readable by the caddy user&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;Description&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;Caddy Web Server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;Documentation&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;https://caddyserver.com/docs/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;After&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;network.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;User&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;caddy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;Group&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;caddy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ExecStart&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/usr/bin/caddy run --config /etc/caddy/Caddyfile --environ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ExecReload&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/usr/bin/caddy reload --config /etc/caddy/Caddyfile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;TimeoutStopSec&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;5s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;LimitNOFILE&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;1048576&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;LimitNPROC&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;512&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;PrivateTmp&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ProtectSystem&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;full&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;AmbientCapabilities&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;CAP_NET_BIND_SERVICE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;WantedBy&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;multi-user.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="preventing-scans"&gt;Preventing scans
&lt;/h1&gt;&lt;p&gt;Everything above is already pretty secure - Caddy is really good at making security super easy. On top of that, Caddy is the only service hosted on this box, there&amp;rsquo;s no dynamic code (all raw HTML and CSS, thanks to &lt;a class="link" href="https://getpelican.com" target="_blank" rel="noopener"
 &gt;Pelican&lt;/a&gt;), and the only things listening to the internet are SSH and Caddy itself. But even then, I get tired of seeing hundreds of scan reports every day. &lt;a class="link" href="https://www.fail2ban.org/" target="_blank" rel="noopener"
 &gt;Fail2Ban&lt;/a&gt; to the rescue.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/fail2ban/filter.d/caddy-4xx.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Definition]
failregex = ^&amp;lt;HOST&amp;gt;.*&amp;#34;(GET|POST).*&amp;#34; (404|444|403|400) .*$
ignoreregex =
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;/etc/fail2ban/jail.local&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[caddy-4xx]
port = http,https
logpath = /var/log/caddy/access.log
 /var/log/caddy/utu_access.log
enabled = true
banTime = 3600
findTime = 600
maxretry = 5
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="fin"&gt;Fin!
&lt;/h1&gt;&lt;p&gt;And that&amp;rsquo;s all! I had another tweak or two to my Pelican Makefile, to point rsync to the right server, but overall that was an incredibly simple process. The Caddy team have done a spectacular job.&lt;/p&gt;</description></item><item><title>Fail2Ban+Nginx (blocking repeated 404's, etc)</title><link>https://www.ericlight.com/post/fail2ban-nginx.html</link><pubDate>Mon, 16 Mar 2020 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/fail2ban-nginx.html</guid><description>&lt;p&gt;After hosting a &lt;a class="link" href="https://www.iredmail.org" target="_blank" rel="noopener"
 &gt;mail server&lt;/a&gt; for a few years, I&amp;rsquo;ve gotten tired of seeing alllll the 404 attempts in my daily logwatch. Fail2Ban can help here really well, and it turns out to be really easy.&lt;/p&gt;
&lt;p&gt;Start with &lt;code&gt;nano /etc/fail2ban/filter.d/nginx-4xx.conf&lt;/code&gt; (I&amp;rsquo;m counting on your running Debian and having things in default locations here), and enter the following:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Definition]
failregex = ^&amp;lt;HOST&amp;gt;.*&amp;#34;(GET|POST).*&amp;#34; (404|444|403|400) .*$
ignoreregex =
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Note: Make sure you use a capital &amp;lsquo;D&amp;rsquo; in Definition there.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now, edit your /etc/fail2ban/jail.conf, and add these lines:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[nginx-4xx]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course, modify your maxretry as desired. Refresh your Fail2Ban rules with &lt;code&gt;service fail2ban restart&lt;/code&gt;, and it should now be on the lookout for repeated 4xx errors.&lt;/p&gt;
&lt;p&gt;You can confirm it&amp;rsquo;s working with: &lt;code&gt;fail2ban-client status nginx-4xx&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Status for the jail: nginx-4xx
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;|- Filter
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| |- Currently failed:	2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| |- Total failed:	9
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| `- File list:	/var/log/nginx/access.log
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;`- Actions
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; |- Currently banned:	2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; |- Total banned:	2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; `- Banned IP list: 123.232.123.101 123.232.123.102
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Success!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Worth mentioning&amp;hellip; for the first while I thought it wasn&amp;rsquo;t working, but I realised I was trying to trigger the rule from on the same LAN, and &amp;hellip;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[DEFAULT]
# time is in seconds. 3600 = 1 hour, 86400 = 24 hours (1 day)
findtime = 3600
bantime = 3600
maxretry = 5
ignoreip = 127.0.0.1 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;hellip; I was hitting it from within the ignoreip range. 😬&lt;/p&gt;
&lt;p&gt;And of course, I can&amp;rsquo;t finish off a blog without giving credit where it&amp;rsquo;s due. I got this all from GitHub user AysadKozanoglu, here: &lt;a class="link" href="https://gist.github.com/AysadKozanoglu/1335735272fb3b00a03bd3eea22af818" target="_blank" rel="noopener"
 &gt;https://gist.github.com/AysadKozanoglu/1335735272fb3b00a03bd3eea22af818&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Fortinet SSL VPN Certificate extensions</title><link>https://www.ericlight.com/post/fortinet-ssl.html</link><pubDate>Sun, 19 Jan 2020 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/fortinet-ssl.html</guid><description>&lt;p&gt;If you&amp;rsquo;re setting up a new SSL VPN with certificate authentication, and if you already have an internal PKI, you&amp;rsquo;re probably considering using your internal certification authority to create the SSL keys and certificates for your VPN clients. Awesome! This is a great and easy way to do this job.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s a dearth of information on the Interwebs regarding what Extended Key Usages you need to have enabled in your Certificate Template for these. There are a heap available, including Email Signing, Timestamping, Code Signing, IPSec SSL things (about 8 of these), and way more options.&lt;/p&gt;
&lt;p&gt;Well, your search can end now. There&amp;rsquo;s only one Extended Key Usage option required for SSL certificate authentication with the Fortinet FortiClient VPN:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Client Authentication&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s it. That&amp;rsquo;s the post.&lt;/p&gt;</description></item><item><title>Zentyal 6.0 to 6.1 upgrade getting stuck</title><link>https://www.ericlight.com/post/zentyal_dns.html</link><pubDate>Tue, 17 Dec 2019 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/zentyal_dns.html</guid><description>&lt;p&gt;So I faced a little challenge with a &lt;a class="link" href="https://www.zentyal.com" target="_blank" rel="noopener"
 &gt;Zentyal&lt;/a&gt; server the other day. I was upgrading from ye olde 6.0 to 6.1, when everything just stopped. I let it sit in the corner for about an hour or so, but it never picked up the thread. All the services were still live, so I logged in to have a look.&lt;/p&gt;
&lt;p&gt;(Note, my DNS server is named RIMU; yours may be something else!)&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;ps aux&lt;/code&gt;, I discovered this line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
sh -c /usr/bin/sudo -p sudo: /var/lib/zentyal/tmp/x2M7gkZVvm.cmd 2&amp;gt; /var/lib/zentyal/tmp/stderr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, I had a quick look at the contents of that stderr file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
# cat /var/lib/zentyal/tmp/stderr 
Password has expired
dns-RIMU@ad.ericlight.com's Password: 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And what does that temp .cmd file contain?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
# cat /var/lib/zentyal/tmp/x2M7gkZVvm.cmd 
kinit -k -t /var/lib/samba/private/dns.keytab dns-RIMU
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running that kinit command indeed prompts for a password reset, but the interesting thing is that samba-tool shows me this password shouldn&amp;rsquo;t expire:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
# pdbedit -u dns-RIMU -v | grep change
Password can change: Wed, 31 Oct 2018 21:47:30 NZDT
Password must change: never
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;hellip; &lt;em&gt;riiiiiiight&lt;/em&gt;, that&amp;rsquo;s a bit interesting. And yet I&amp;rsquo;m still being prompted to set a new password. I used samba-tool to remind samba that this password shouldn&amp;rsquo;t expire:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
# samba-tool user setexpiry dns-RIMU --noexpiry
Expiry for user 'dns-RIMU' disabled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now&amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
# pdbedit -u dns-RIMU -v | grep -i change
Password can change: Wed, 31 Oct 2018 21:47:30 NZDT
Password must change: Tue, 19 Jan 2038 16:14:07 NZDT
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I can run kinit against dns-RIMU perfectly fine, and indeed the Zentyal upgrade succeeded!&lt;/p&gt;</description></item><item><title>New things I didn't know about WireGuard</title><link>https://www.ericlight.com/post/wg3.html</link><pubDate>Thu, 27 Dec 2018 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/wg3.html</guid><description>&lt;p&gt;This is part of my &lt;a class="link" href="https://www.ericlight.com/post/wg0.html" &gt;brief&lt;/a&gt; &lt;a class="link" href="https://www.ericlight.com/post/wg1.html" &gt;series&lt;/a&gt; &lt;a class="link" href="https://www.ericlight.com/post/wg2.html" &gt;on&lt;/a&gt; &lt;a class="link" href="https://wireguard.com/" target="_blank" rel="noopener"
 &gt;WireGuard&lt;/a&gt;. I&amp;rsquo;m pretty enamoured with WireGuard and the way it works, and I&amp;rsquo;ve been using it pretty seamlessly for over a year now. I&amp;rsquo;ve learned a couple things that weren&amp;rsquo;t immediately obvious though, so I&amp;rsquo;m documenting them here.&lt;/p&gt;
&lt;h2 id="easy-provisioning"&gt;Easy Provisioning
&lt;/h2&gt;&lt;p&gt;Samuel Holland mentioned an interesting trinket, in his post at &lt;a class="link" href="https://lists.zx2c4.com/pipermail/WireGuard/2018-December/003703.html" target="_blank" rel="noopener"
 &gt;https://lists.zx2c4.com/pipermail/WireGuard/2018-December/003703.html&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;[&amp;hellip;] WireGuard will ignore a peer whose public key matches the interface&amp;rsquo;s private key. So you can distribute a single list of peers everywhere.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You can combine this with &lt;code&gt;wg addconf&lt;/code&gt; like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each peer has its own &lt;code&gt;/etc/WireGuard/wg0.conf&lt;/code&gt; file, which only contains it&amp;rsquo;s &lt;code&gt;[Interface]&lt;/code&gt; section&lt;/li&gt;
&lt;li&gt;Each peer also has a shared &lt;code&gt;/etc/WireGuard/peers.conf&lt;/code&gt; file, which contains all the peers&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;wg0.conf&lt;/code&gt; file also has a PostUp hook, calling &lt;code&gt;wg addconf /etc/WireGuard/peers.conf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;rsquo;s up to you to decide how you want to share the peers.conf, be it via a proper orchestration platform, something much more pedestrian like Dropbox, or something kinda wild like Ceph. I dunno, but it&amp;rsquo;s pretty great that you can just wildly fling a peer section around, without worrying whether it&amp;rsquo;s the same as the interface.&lt;/p&gt;
&lt;h2 id="setting-private-key-from-a-file"&gt;Setting Private Key from a file
&lt;/h2&gt;&lt;p&gt;Another piece of learning, courtesy of Samuel Holland, at &lt;a class="link" href="https://lists.zx2c4.com/pipermail/WireGuard/2018-December/003702.html" target="_blank" rel="noopener"
 &gt;https://lists.zx2c4.com/pipermail/WireGuard/2018-December/003702.html&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can read in a file as the Private Key by doing something like:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PostUp = wg set %i private-key /etc/WireGuard/wg0.key&lt;/code&gt;&lt;/p&gt;</description></item><item><title>When AppArmor eats your breakfast</title><link>https://www.ericlight.com/post/zentyal-apparmor.html</link><pubDate>Mon, 19 Mar 2018 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/zentyal-apparmor.html</guid><description>&lt;p&gt;I&amp;rsquo;ve knocked heads with AppArmor a few times now. To be quite honest with myself, I think it&amp;rsquo;s primarily because I install it, enable all the plugins, and then forget it&amp;rsquo;s there until there&amp;rsquo;s a problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;On a fully-updated Zentyal 5.0 system running DHCP, the AppArmor profile in /etc/apparmor.d/usr.sbin.dhcpd &lt;strong&gt;will prevent isc-dhcp-server from restarting itself after an upgrade&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;More search-type words: Zentyal dhcp server doesn&amp;rsquo;t start again after upgrade. isc-dhcp-server graceful shutdown, but no restart.&lt;/p&gt;
&lt;p&gt;This frustration-laden, Google-friendly equivalent of speaking slowly and clearly should illustrate how impossible it was for me to find guidance on this.&lt;/p&gt;
&lt;p&gt;To fix:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# aa-complain /etc/apparmor.d/usr.sbin.dhcpd 
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;p&gt;Okay, now that the TL;DR is finished, here&amp;rsquo;s the rest of the story:&lt;/p&gt;
&lt;p&gt;Unfortunately there&amp;rsquo;s &lt;strong&gt;always&lt;/strong&gt; a problem with AppArmor eventually.&lt;/p&gt;
&lt;p&gt;Even worse, &lt;em&gt;the problem is often silent&lt;/em&gt;. I&amp;rsquo;ll just find that, for example, NONE of my man pages work. Or logrotate will fail. For example, here&amp;rsquo;s what happens when you enable aa-enforce mode on your friendly resident user manual:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; $ man
 What manual page do you want?
 $ sudo aa-enforce /etc/apparmor.d/usr.bin.man
 Setting /etc/apparmor.d/usr.bin.man to enforce mode.
 $ man
 $man: can&amp;#39;t open the manpath configuration file /etc/manpath.config
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If I hadn&amp;rsquo;t enabled &lt;code&gt;aa-enforce&lt;/code&gt; immediately before that, what would &lt;em&gt;you&lt;/em&gt; have done? You would have gone ahead, made sure that manpath.config existed, made sure it wasn&amp;rsquo;t corrupted, maybe tried running &lt;code&gt;man&lt;/code&gt; as root&amp;hellip; maybe even copied a manpath.config file from a known-working computer. But, hidden within &lt;code&gt;dmesg&lt;/code&gt; is our old friend:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[149929.763064] type=1400 audit(1521449052.257:111): apparmor=&amp;quot;DENIED&amp;quot; operation=&amp;quot;open&amp;quot; profile=&amp;quot;/usr/bin/man&amp;quot; name=&amp;quot;/etc/manpath.config&amp;quot; pid=22633 comm=&amp;quot;man&amp;quot; requested_mask=&amp;quot;r&amp;quot; denied_mask=&amp;quot;r&amp;quot; fsuid=1000 ouid=0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And that example is actually better than it used to be - quite a few times in the past four years, I&amp;rsquo;ve received this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ man
$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;hellip; from a fully-updated Debian system.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;br/&gt;
&lt;em&gt;This makes me sad.&lt;/em&gt;
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Or, in one particular case, &lt;em&gt;ISC-DHCP-SERVER&lt;/em&gt; of all things will launch perfectly well, but will fail to restart after a package update, and the first thing I&amp;rsquo;ll notice is &amp;ldquo;o hai all the things is broken halp plz&amp;rdquo;. Something like that.&lt;/p&gt;
&lt;p&gt;When you&amp;rsquo;re troubleshooting DHCP, you&amp;rsquo;ll probably check systemctl, leases table, maybe /var/log &amp;hellip; But when you get around to checking &lt;code&gt;dmesg&lt;/code&gt;, you may notice the root of the problem:&lt;/p&gt;
&lt;p&gt;From dmesg -T:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Sat Mar 17 03:44:28 2016] audit_printk_skb: 18 callbacks suppressed
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Considering the update occurred at 03:44am, this is probably our problem. I can&amp;rsquo;t see &lt;em&gt;for sure&lt;/em&gt;, but I&amp;rsquo;m pretty certain those 18 suppressed callbacks are filled with &amp;ldquo;DENIED&amp;rdquo; log lines.&lt;/p&gt;
&lt;p&gt;The fix is simple:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# aa-complain /etc/apparmor.d/usr.sbin.dhcpd 
Setting /etc/apparmor.d/usr.sbin.dhcpd to complain mode.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And your isc-dhcp-server should now restart gracefully after it&amp;rsquo;s scheduled upgrades!&lt;/p&gt;</description></item><item><title>Making MindTouch's Dekiwiki work on Debian Stretch</title><link>https://www.ericlight.com/post/dekiwiki.html</link><pubDate>Sun, 17 Sep 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/dekiwiki.html</guid><description>&lt;p&gt;We had accumulated a certain amount of technical debt, due to a Wiki solution that was selected a few years ago: Dekiwiki, by MindTouch. Unfortunately a few months after implementation, MindTouch Core (which Dekiwiki builds on) was &lt;a class="link" href="https://mindtouch.com/resources/mindtouch-core-and-platform-this-is-the-end-beautiful-friend" target="_blank" rel="noopener"
 &gt;well-and-truly deprecated&lt;/a&gt; back in 2013.&lt;/p&gt;
&lt;p&gt;It all happened before my time, but it seems as if Dekiwiki came as a pre-built VMware Appliance, based on Debian Etch (&lt;a class="link" href="https://en.wikipedia.org/wiki/Debian_version_history#Debian_4.0_.28Etch.29" target="_blank" rel="noopener"
 &gt;Debian 4.0; released in 2007&lt;/a&gt;). After giving our Dekiwiki environment some serious side-eye for a while, I finally decided to get my hands dirty and try to upgrade it.&lt;/p&gt;
&lt;p&gt;Jedd, over at Jeddi.org, wrote &lt;a class="link" href="https://jeddi.org/b/resurrecting-mindtouch-dekiwiki.html#resurrecting-mindtouch-dekiwiki" target="_blank" rel="noopener"
 &gt;a really helpful post back in 2015&lt;/a&gt; about his experiences updating the ageing version of Debian that the VM is based on. The whole Dekiwiki image is held together by sticky-tape, but that post is really helpful in getting Etch upgraded to Wheezy.&lt;/p&gt;
&lt;p&gt;Here are a couple &lt;strong&gt;additional&lt;/strong&gt; things I&amp;rsquo;ve had to do (please, please look at Jedd&amp;rsquo;s post above - he covers a whole lot that I&amp;rsquo;m not covering here):&lt;/p&gt;
&lt;h2 id="upgrading-etch---lenny"&gt;Upgrading Etch -&amp;gt; Lenny:
&lt;/h2&gt;&lt;p&gt;Follow &lt;a class="link" href="https://jeddi.org/b/resurrecting-mindtouch-dekiwiki.html#resurrecting-mindtouch-dekiwiki" target="_blank" rel="noopener"
 &gt;the guide at Jeddi.org&lt;/a&gt; above to get to Lenny. I can&amp;rsquo;t remember much failing for that upgrade step, but I remember something happened.&lt;/p&gt;
&lt;h2 id="from-lenny---squeeze"&gt;From Lenny -&amp;gt; Squeeze:
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;DNS Breaks.&lt;/strong&gt; You&amp;rsquo;ll notice that SSH takes aaaages to log into, and other things will start being slow and complaining.&lt;/p&gt;
&lt;p&gt;Resolve this by editing the &amp;lsquo;hosts&amp;rsquo; line in /etc/nsswitch.conf:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;hosts: files dns&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Originally this reads &lt;code&gt;hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Note I&amp;rsquo;m not actually sure this happened between Lenny and Squeeze; it may have been from Squeeze to Wheezy. *shrug*&lt;/p&gt;
&lt;h2 id="from-squeeze---wheezy"&gt;From Squeeze -&amp;gt; Wheezy:
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;MySQL breaks.&lt;/strong&gt; When visiting the wiki, you&amp;rsquo;ll be informed that it couldn&amp;rsquo;t access the backend, and that the API might be warming up. However, you&amp;rsquo;ll notice that the MySQL service fails to start. When you run &amp;lsquo;mysqld&amp;rsquo; from command line, you&amp;rsquo;ll see it&amp;rsquo;s missing a folder.&lt;/p&gt;
&lt;p&gt;Resolve this by running &lt;code&gt;mkdir /var/lib/mysql-files ; chown mysql:mysql /var/lib/mysql-files&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="from-wheezy---jessie-upgrade-only"&gt;From Wheezy -&amp;gt; Jessie (upgrade-only):
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Apache breaks.&lt;/strong&gt; You&amp;rsquo;ll notice Apache starts serving just the contents of /var/www. This is because the Apache config file now looks for *.conf in /etc/apache2/sites-enabled; of course, the dekiwiki config file doesn&amp;rsquo;t have the .conf ending.&lt;/p&gt;
&lt;p&gt;Resolve this by running &lt;code&gt;mv /etc/apache2/sites-enabled/dekiwiki /etc/apache2/sites-enabled/dekiwiki.conf&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="from-wheezy---jessie-dist-upgrade"&gt;From Wheezy -&amp;gt; Jessie (dist-upgrade):
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Mono breaks.&lt;/strong&gt; If you upgrade mono, Dekiwiki will fall back into unlicensed mode. The licensing engine will no longer be able to interpret license files correctly. You&amp;rsquo;ll see the error &amp;ldquo;Server license validation failed. The license signature is not valid.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Resolve this by holding back the mono packages before you run a dist-upgrade:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;apt-mark hold libapache2-mod-mono libmono-2.0-1 libmono-2.0-dev libmono-accessibility2.0-cil libmono-accessibility4.0-cil libmono-bytefx0.7.6.2-cil libmono-c5-1.1-cil libmono-cairo2.0-cil libmono-cairo4.0-cil libmono-cecil-private-cil libmono-codecontracts4.0-cil libmono-compilerservices-symbolwriter4.0-cil libmono-corlib2.0-cil libmono-corlib4.0-cil libmono-cscompmgd8.0-cil libmono-csharp4.0-cil libmono-custommarshalers4.0-cil libmono-data-tds2.0-cil libmono-data-tds4.0-cil libmono-data2.0-cil libmono-db2-1.0-cil libmono-debugger-soft2.0-cil libmono-debugger-soft4.0-cil libmono-dev libmono-firebirdsql1.7-cil libmono-getoptions2.0-cil libmono-http4.0-cil libmono-i18n-cjk4.0-cil libmono-i18n-mideast4.0-cil libmono-i18n-other4.0-cil libmono-i18n-rare4.0-cil libmono-i18n-west2.0-cil libmono-i18n-west4.0-cil libmono-i18n2.0-cil libmono-i18n4.0-all libmono-i18n4.0-cil libmono-ldap2.0-cil libmono-ldap4.0-cil libmono-management2.0-cil libmono-management4.0-cil libmono-messaging-rabbitmq2.0-cil libmono-messaging-rabbitmq4.0-cil libmono-messaging2.0-cil libmono-messaging4.0-cil libmono-microsoft-build-engine4.0-cil libmono-microsoft-build-framework4.0-cil libmono-microsoft-build-tasks-v4.0-4.0-cil libmono-microsoft-build-utilities-v4.0-4.0-cil libmono-microsoft-build2.0-cil libmono-microsoft-csharp4.0-cil libmono-microsoft-visualc10.0-cil libmono-microsoft-web-infrastructure1.0-cil libmono-microsoft8.0-cil libmono-npgsql2.0-cil libmono-npgsql4.0-cil libmono-opensystem-c4.0-cil libmono-oracle2.0-cil libmono-oracle4.0-cil libmono-peapi2.0-cil libmono-peapi4.0-cil libmono-posix2.0-cil libmono-posix4.0-cil libmono-rabbitmq2.0-cil libmono-rabbitmq4.0-cil libmono-relaxng2.0-cil libmono-relaxng4.0-cil libmono-security2.0-cil libmono-security4.0-cil libmono-sharpzip2.6-cil libmono-sharpzip2.84-cil libmono-sharpzip4.84-cil libmono-simd2.0-cil libmono-simd4.0-cil libmono-sqlite2.0-cil libmono-sqlite4.0-cil libmono-system-componentmodel-composition4.0-cil libmono-system-componentmodel-dataannotations4.0-cil libmono-system-configuration-install4.0-cil libmono-system-configuration4.0-cil libmono-system-core4.0-cil libmono-system-data-datasetextensions4.0-cil libmono-system-data-linq2.0-cil libmono-system-data-linq4.0-cil libmono-system-data-services-client4.0-cil libmono-system-data-services4.0-cil libmono-system-data2.0-cil libmono-system-data4.0-cil libmono-system-design4.0-cil libmono-system-drawing-design4.0-cil libmono-system-drawing4.0-cil libmono-system-dynamic4.0-cil libmono-system-enterpriseservices4.0-cil libmono-system-identitymodel-selectors4.0-cil libmono-system-identitymodel4.0-cil libmono-system-ldap2.0-cil libmono-system-ldap4.0-cil libmono-system-management4.0-cil libmono-system-messaging2.0-cil libmono-system-messaging4.0-cil libmono-system-net4.0-cil libmono-system-numerics4.0-cil libmono-system-runtime-caching4.0-cil libmono-system-runtime-durableinstancing4.0-cil libmono-system-runtime-serialization-formatters-soap4.0-cil libmono-system-runtime-serialization4.0-cil libmono-system-runtime2.0-cil libmono-system-runtime4.0-cil libmono-system-security4.0-cil libmono-system-servicemodel-discovery4.0-cil libmono-system-servicemodel-routing4.0-cil libmono-system-servicemodel-web4.0-cil libmono-system-servicemodel4.0-cil libmono-system-serviceprocess4.0-cil libmono-system-transactions4.0-cil libmono-system-web-abstractions4.0-cil libmono-system-web-applicationservices4.0-cil libmono-system-web-dynamicdata4.0-cil libmono-system-web-extensions-design4.0-cil libmono-system-web-extensions4.0-cil libmono-system-web-mvc1.0-cil libmono-system-web-mvc2.0-cil libmono-system-web-routing4.0-cil libmono-system-web-services4.0-cil libmono-system-web2.0-cil libmono-system-web4.0-cil libmono-system-windows-forms-datavisualization4.0-cil libmono-system-windows-forms4.0-cil libmono-system-xaml4.0-cil libmono-system-xml-linq4.0-cil libmono-system-xml4.0-cil libmono-system2.0-cil libmono-system4.0-cil libmono-tasklets2.0-cil libmono-tasklets4.0-cil libmono-wcf3.0-cil libmono-web4.0-cil libmono-webbrowser2.0-cil libmono-webbrowser4.0-cil libmono-webmatrix-data4.0-cil libmono-windowsbase3.0-cil libmono-windowsbase4.0-cil libmono-winforms2.0-cil libmono0 libmono2.0-cil mono-2.0-devel mono-2.0-gac mono-4.0-gac mono-apache-server2 mono-common mono-csharp-shell mono-dmcs mono-gac mono-gmcs mono-mcs mono-runtime mono-utils mono-xbuild&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Some of these can certainly be unheld. I haven&amp;rsquo;t yet gone through and identified exactly which component is breaking on upgrade. If you put in the effort to determine the culprit, please let me know.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s all! You should now have Dekiwiki running on Debian Stretch! I&amp;rsquo;m planning to upgrade it to Debian Buster in the next week or two.&lt;/p&gt;</description></item><item><title>Respecting Amavis' "Banned Extensions" setting</title><link>https://www.ericlight.com/post/amavis2.html</link><pubDate>Sun, 13 Aug 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/amavis2.html</guid><description>&lt;p&gt;I&amp;rsquo;ve been dabbling a little bit with &lt;a class="link" href="http://www.iredmail.org" target="_blank" rel="noopener"
 &gt;iRedMail&lt;/a&gt;, mostly just to have a play with a mail server, but also to see what&amp;rsquo;s involved in mail security. iRedMail is a package that &lt;a class="link" href="http://www.iredmail.org/docs/used.components.html" target="_blank" rel="noopener"
 &gt;pulls together&lt;/a&gt; Postfix as an MTA, Dovecot as a POP3 &amp;amp; IMAP server, SOGo for ActiveSync, Roundcube for Webmail, SpamAssassin for spam protection, and ClamAV for virus scanning.&lt;/p&gt;
&lt;p&gt;Okay I have &lt;strong&gt;no idea&lt;/strong&gt; why I have to write this, but apparently it&amp;rsquo;s a thing.&lt;/p&gt;
&lt;p&gt;Amavis has a list of banned file extensions. In Debian, they live in &lt;code&gt;/etc/amavis/conf.d/20-debian_defaults&lt;/code&gt;, and &lt;code&gt;/etc/amavis/conf.d/50-user&lt;/code&gt;, and are set in the &lt;code&gt;$banned_filename_re&lt;/code&gt; variable. THIS MAKES PERFECT SENSE.&lt;/p&gt;
&lt;p&gt;But of course, there&amp;rsquo;s always something that doesn&amp;rsquo;t make sense, and that is the fact that there is a SQL backend (at least in the environment created by iRedMail), and settings in here take precedence over the Amavis config files somehow.&lt;/p&gt;
&lt;p&gt;And even more bizarrely, there exists in this SQL environment, a policy setting entitled &amp;ldquo;&lt;em&gt;&lt;strong&gt;banned_files_lover&lt;/strong&gt;&lt;/em&gt;&amp;rdquo;, which was set to &amp;ldquo;Y&amp;rdquo;. I shit you not. My only hope is that this only defaults to &amp;ldquo;Y&amp;rdquo; for postmaster.&lt;/p&gt;
&lt;p&gt;To fix this, you need to hop into the database, and update the appropriate column in the &lt;code&gt;policy&lt;/code&gt; table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mariadb
MariaDB [none]&amp;gt; \u amavis
MariaDB [amavisd]&amp;gt; update policy set banned_files_lover=&amp;quot;N&amp;quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now, Amavis will obey your file extension filters!&lt;/p&gt;
&lt;p&gt;Thankfully, I found this information at &lt;a class="link" href="http://www.iredmail.org/forum/topic13147-iredmail-support-amavisd-passed-but-setup-at-ddiscard.html" target="_blank" rel="noopener"
 &gt;http://www.iredmail.org/forum/topic13147-iredmail-support-amavisd-passed-but-setup-at-ddiscard.html&lt;/a&gt; &amp;ndash; I never would have found it otherwise!&lt;/p&gt;</description></item><item><title>Making Amavis work with ESET Antivirus</title><link>https://www.ericlight.com/post/amavis.html</link><pubDate>Sat, 12 Aug 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/amavis.html</guid><description>&lt;p&gt;I&amp;rsquo;ve been dabbling a little bit with &lt;a class="link" href="http://www.iredmail.org" target="_blank" rel="noopener"
 &gt;iRedMail&lt;/a&gt;, mostly just to have a play with a mail server, but also to see what&amp;rsquo;s involved in mail security. iRedMail is a package that &lt;a class="link" href="http://www.iredmail.org/docs/used.components.html" target="_blank" rel="noopener"
 &gt;pulls together&lt;/a&gt; Postfix as an MTA, Dovecot as a POP3 &amp;amp; IMAP server, SOGo for ActiveSync, Roundcube for Webmail, SpamAssassin for spam protection, and ClamAV for virus scanning.&lt;/p&gt;
&lt;p&gt;But of course, ClamAV has &lt;a class="link" href="https://www.av-test.org/en/news/news-single-view/linux-16-security-packages-against-windows-and-linux-malware-put-to-the-test/" target="_blank" rel="noopener"
 &gt;shown disappointing performance&lt;/a&gt;, and it would be really nice to use something more&amp;hellip; commercially suitable.&lt;/p&gt;
&lt;p&gt;To tie together mail receipt and scanning, iRedMail uses &lt;a class="link" href="https://www.ijs.si/software/amavisd/" target="_blank" rel="noopener"
 &gt;Amavis&lt;/a&gt; (strictly speaking, &amp;lsquo;amavisd-new&amp;rsquo;). Amavis uses ClamAV by default, but it comes with a bunch of &lt;a class="link" href="https://www.apt-browse.org/browse/ubuntu/trusty/main/all/amavisd-new/1:2.7.1-2ubuntu3/file/etc/amavis/conf.d/15-av_scanners" target="_blank" rel="noopener"
 &gt;configuration blocks&lt;/a&gt; to bring together other antivirus applications.&lt;/p&gt;
&lt;p&gt;But although amavisd-new is stable and still maintained, some parts of it are really old. In particular, many of these av-scanner config blocks are&amp;hellip; uhh&amp;hellip; &amp;ldquo;deprecated&amp;rdquo;. There&amp;rsquo;s one particular entry for ESET that is dated 2002 - things have changed a lot in the last fifteen years. *shudder*&lt;/p&gt;
&lt;p&gt;So, with the help of &lt;a class="link" href="https://www.akadia.com/download/documents/amavisd.conf.txt" target="_blank" rel="noopener"
 &gt;some documentation&lt;/a&gt;, I managed to piece together a code block that works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;['ESET File Security for Linux',
 ['/opt/eset/esets/sbin/esets_scan','esets_scan'],
 '--subdir --unsafe --unwanted --clean-mode=strict {}',
 [0,10,100],[1,50],
 qr/threat=&amp;quot;([^&amp;quot;]+)&amp;quot;/m
],
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That would be the end of the story, except I also had to hunt around to find out the right place to put my beautiful codeblock into. It turns out that Debian&amp;rsquo;s Amavis config structure is quite different to the CentOS config that is most-frequently mentioned in the iRedMail forums. I spent a lot of time playing with &lt;code&gt;/etc/amavis/conf.d/15-av_scanners&lt;/code&gt;, and nothing seemed to work. Eventually I found out that Debian features a &lt;code&gt;/etc/amavis/conf.d/50-users&lt;/code&gt; file that overwrites the settings from &lt;code&gt;15-av_scanners&lt;/code&gt;. Finally I had progress!&lt;/p&gt;
&lt;p&gt;Somewhere around line 154 in &lt;code&gt;/etc/amavis/conf.d/50-users&lt;/code&gt;, you&amp;rsquo;ll find an &lt;code&gt;@av_scanners&lt;/code&gt; codeblock. I deleted the ClamAV section in there, and replaced it with the ESET codeblock above. I left the ClamAV settings in the &lt;code&gt;@av_scanners_backup&lt;/code&gt; section, because Amavis will fall back to that if ESET fails.&lt;/p&gt;
&lt;p&gt;That seems to be all! At least, it works with the &lt;a class="link" href="http://www.eicar.org/" target="_blank" rel="noopener"
 &gt;EICAR anti-malware test file&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>RingZer0team CTF - Challenges 86, 87, and 88</title><link>https://www.ericlight.com/post/r0-86.html</link><pubDate>Thu, 13 Jul 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/r0-86.html</guid><description>&lt;p&gt;There are a bunch of fantastic Capture The Flag security challenges on &lt;a class="link" href="https://www.ringzer0team.com" target="_blank" rel="noopener"
 &gt;RingZer0Team.com&lt;/a&gt;. I&amp;rsquo;ve been working through some of these for a wee while now, and with the &lt;a class="link" href="https://www.cybersecuritychallenge.org.nz/" target="_blank" rel="noopener"
 &gt;New Zealand Cyber Security Challenge&lt;/a&gt; coming up again soon, I thought I&amp;rsquo;d get back into some of them.&lt;/p&gt;
&lt;p&gt;Challenge 86 (&amp;ldquo;1/3 Do not waste the environment&amp;rdquo;, under the Forsensic Challenges) is one of a series of challenges where you need to dig through some provided data to find the flag.&lt;/p&gt;
&lt;p&gt;I started by downloading the &amp;lsquo;forensic bundle&amp;rsquo;, which was just a large zip file. The first challenge was to figure out the contents of that zip file. The file name was just a jumble of characters, and there was no extension. Running &lt;code&gt;file&lt;/code&gt; on it just returned the file type &amp;ldquo;Data&amp;rdquo;&amp;hellip; not very enlightening, but &lt;code&gt;head&lt;/code&gt; uncovered the string &amp;ldquo;VBOX&amp;rdquo; in the file&amp;hellip; okay, it&amp;rsquo;s VirtualBox file.&lt;/p&gt;
&lt;p&gt;Because I didn&amp;rsquo;t have Virtualbox installed, I spent a bit of time digging through the actual Vbox file itself, trying to see if there&amp;rsquo;s a flag already in there. I used &lt;code&gt;strings | egrep -i flag-....&lt;/code&gt;, to try to find any flags embedded in the file itself. I didn&amp;rsquo;t find any flags, but I did discover that the computer name itself is &amp;ldquo;FLAG-PC&amp;rdquo;. Very clever. :-|&lt;/p&gt;
&lt;h3 id="update-many-hours-later"&gt;Update, many hours later:
&lt;/h3&gt;&lt;p&gt;Okay this totally cooked my bacon. After hours of playing with VirtualBox and playing with files, I finally gave up and Googled the name of the downloaded file.&lt;/p&gt;
&lt;p&gt;Turns out I was &lt;em&gt;REALLY&lt;/em&gt; close. The flag IS embedded in the actual file itself, but the format is different for the first time. The correct grep string would have been &lt;code&gt;egrep -i '.?f.?l.?a.?g.?-'&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Real frustrated by how close I was, I&amp;rsquo;ll have to expand my searches in the future. Hat-tip to &lt;a class="link" href="https://twitter.com/professormahi" target="_blank" rel="noopener"
 &gt;@professormahi&lt;/a&gt; and his &lt;a class="link" href="https://github.com/professormahi/CTF/tree/master/ringzer0team/Forensics/1-3%20Do%20not%20waste%20the%20enviroment" target="_blank" rel="noopener"
 &gt;GitHub&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;Once I understood that, I also discovered the flag for challenge 87 (&amp;ldquo;2/3 Did you see my desktop?&amp;rdquo;), in the same manner.&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t managed to get the flag for Challenge 88 (&amp;ldquo;3/3 Suspicious Account Password&amp;rdquo;) yet, but I do know what it is. I can see (by grepping for &amp;ldquo;Visited&amp;rdquo;) a bunch of visits to &lt;a class="link" href="http://www.forensicswiki.org/wiki/Tools:Memory_Imaging" target="_blank" rel="noopener"
 &gt;http://www.forensicswiki.org/wiki/Tools:Memory_Imaging&lt;/a&gt;&amp;hellip; this thing is a memory dump. That explains now why it doesn&amp;rsquo;t work as a VirtualBox disk.&lt;/p&gt;
&lt;p&gt;Next time I sit down here, I&amp;rsquo;ll find visit Forensics Wiki, and start digging through the memory dump for the passwords.&lt;/p&gt;
&lt;h3 id="update-two"&gt;Update two
&lt;/h3&gt;&lt;p&gt;I decided not to put this up as a separate post, because once I knew what I was looking at, it was pretty easy. Again though, I relied on @professormahi&amp;rsquo;s work - but now thanks to him I have a little bit of experience with &lt;a class="link" href="https://www.volatilityfoundation.org/" target="_blank" rel="noopener"
 &gt;Volatility&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;First, we get Volatility to scan the image and see what it&amp;rsquo;s dealing with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ volatility -f vm.vmdk imageinfo
Volatility Foundation Volatility Framework 2.6
INFO : volatility.debug : Determining profile based on KDBG search...
 Suggested Profile(s) : Win7SP1x86_23418, Win7SP0x86, Win7SP1x86
 AS Layer1 : IA32PagedMemory (Kernel AS)
 AS Layer2 : FileAddressSpace (/home/eric/Downloads/86/vm.vmdk)
 PAE type : No PAE
 DTB : 0x185000L
 KDBG : 0x82920be8L
 Number of Processors : 1
 Image Type (Service Pack) : 0
 KPCR for CPU 0 : 0x82921c00L
 KUSER_SHARED_DATA : 0xffdf0000L
 Image date and time : 2014-03-09 20:57:55 UTC+0000
 Image local date and time : 2014-03-09 13:57:55 -0700
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, knowing the profile that we need to use, we can use it to just&amp;hellip; dump the password table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ volatility -f vm.vmdk --profile Win7SP1x86 hashdump
Volatility Foundation Volatility Framework 2.6
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
flag:1000:aad3b435b51404eeaad3b435b51404ee:3008c87294511142799dca1191e69a0f:::
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then, we grab that NTLM hash and pop it into an online NTLM decryptor service, and we&amp;rsquo;re away!&lt;/p&gt;</description></item><item><title>Staying Secure in Business</title><link>https://www.ericlight.com/post/hygiene.html</link><pubDate>Wed, 28 Jun 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/hygiene.html</guid><description>&lt;p&gt;A friend asked a question today on Facebook. I started writing a reply, and it turned into a 700-word essay. Hate it when that happens&amp;hellip;&lt;/p&gt;
&lt;p&gt;The question was:&lt;/p&gt;
&lt;h4 id="heading"&gt;&lt;em&gt;&amp;ldquo;If large multi-international companies are getting hacked in Europe who have millions if not billions of $$ and capacity to protect their IT systems - how can small/micro businesses protect their IT platforms and systems?&amp;rdquo;&lt;/em&gt;
&lt;/h4&gt;&lt;p&gt;Firstly - nobody is safe from an APT (&amp;ldquo;Advanced Persistent Threat&amp;rdquo;). The recent &lt;a class="link" href="https://twitter.com/search?q=NotPetya" target="_blank" rel="noopener"
 &gt;NotPetya&lt;/a&gt; outbreak was an APT - malicious actors hacked a Ukrainian firm that produced accounting software, and &lt;a class="link" href="https://medium.com/@thegrugq/pnyetya-yet-another-ransomware-outbreak-59afd1ee89d4" target="_blank" rel="noopener"
 &gt;used their software&amp;rsquo;s update facility&lt;/a&gt; to literally deliver malicious code specifically to the users of this particular software package (&amp;ldquo;M.E. Doc&amp;rdquo;). Nothing&amp;rsquo;s keeping folks safe from that level of sophistication.&lt;/p&gt;
&lt;p&gt;However, the exploit by which NotPetya &lt;em&gt;spreads&lt;/em&gt; was &lt;a class="link" href="https://technet.microsoft.com/en-us/library/security/ms17-010.aspx" target="_blank" rel="noopener"
 &gt;actually patched by Microsoft&lt;/a&gt; in &lt;strong&gt;March&lt;/strong&gt;. If people had updated their internet-connected devices, this virus would have been limited to only users of M.E. Doc.&lt;/p&gt;
&lt;p&gt;Aside from that though, there&amp;rsquo;s actually a disappointingly simple answer to this. Security is actually relatively within reach, if we all follow these simple steps:&lt;/p&gt;
&lt;h3 id="1--update-everything-at-every-opportunity"&gt;1) Update. Everything. At every opportunity.
&lt;/h3&gt;&lt;p&gt;That includes Windows Updates, but also &lt;a class="link" href="http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=adobe&amp;#43;reader" target="_blank" rel="noopener"
 &gt;Adobe Reader&lt;/a&gt; (annoying!), &lt;a class="link" href="http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=java" target="_blank" rel="noopener"
 &gt;Java&lt;/a&gt; (double annoying!), &lt;a class="link" href="https://twitter.com/taviso/status/860679110728622080" target="_blank" rel="noopener"
 &gt;anti-virus engines&lt;/a&gt;, etc. This is absolutely the top priority, and the cybersecurity industry has been trotting this line out for years, but people just don&amp;rsquo;t. Because annoying.&lt;/p&gt;
&lt;p&gt;Real life incident: June 22, 2017 - Honda falls prey to the WannaCry worm, 37 days after release (four months after the patch was released), due to poor patching hygiene.&lt;/p&gt;
&lt;p&gt;See &lt;a class="link" href="http://thehackernews.com/2017/06/honda-wannacry-attack.html" target="_blank" rel="noopener"
 &gt;http://thehackernews.com/2017/06/honda-wannacry-attack.html&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="2--backup-everything-important"&gt;2) Backup everything important.
&lt;/h3&gt;&lt;p&gt;The more important it is, the more places you should keep it. You should have at least three copies of every important file. THIS IS ANNOYING, but if you don&amp;rsquo;t do it, data loss will hit you. Something like &lt;a class="link" href="https://www.crashplan.com" target="_blank" rel="noopener"
 &gt;Crashplan&lt;/a&gt; (a low-cost service that sends backups to the cloud), plus a regular (weekly?) copy to a read-only media (e.g. a DVD), should be enough for a small business.&lt;/p&gt;
&lt;p&gt;Real life incident: Feb 1, 2017 - GitLabs suffers a major outage after data was accidentally deleted, followed by a sequence of discoveries that none of their five layers of backup or replication techniques “are working reliably or set up in the first place”.&lt;/p&gt;
&lt;p&gt;See &lt;a class="link" href="https://techcrunch.com/2017/02/01/gitlab-suffers-major-backup-failure-after-data-deletion-incident/" target="_blank" rel="noopener"
 &gt;https://techcrunch.com/2017/02/01/gitlab-suffers-major-backup-failure-after-data-deletion-incident/&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="3--use-next-generation-anti-virus-software"&gt;3) Use next-generation anti-virus software.
&lt;/h3&gt;&lt;p&gt;Many of the AV products these days include very clever ways of analysing the behaviour of unknown software, and literally just rolling back all the changes if the AV decides it&amp;rsquo;s not trustworthy. &lt;a class="link" href="https://www.webroot.com" target="_blank" rel="noopener"
 &gt;Webroot&lt;/a&gt; is a good example of this, at a very affordable price.&lt;/p&gt;
&lt;p&gt;Real life incident: April 23, 2017 - the Adylkuzz virus started quietly spreading around the internet, and setting up Monero cryptocurrency mining operations on infected PC&amp;rsquo;s. Because the payload wasn&amp;rsquo;t destructive, it flew under the radar and was missed by many antiviruses for weeks.&lt;/p&gt;
&lt;p&gt;See &lt;a class="link" href="https://www.proofpoint.com/us/threat-insight/post/adylkuzz-cryptocurrency-mining-malware-spreading-for-weeks-via-eternalblue-doublepulsar" target="_blank" rel="noopener"
 &gt;https://www.proofpoint.com/us/threat-insight/post/adylkuzz-cryptocurrency-mining-malware-spreading-for-weeks-via-eternalblue-doublepulsar&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="4--be-alert-cautious-and-sufficiently-paranoid"&gt;4) Be alert, cautious, and sufficiently paranoid.
&lt;/h3&gt;&lt;p&gt;The last - and hardest - step is to maintain a healthy sense of distrust; sometimes referred to as &amp;ldquo;&lt;a class="link" href="https://pthree.org/2013/10/04/sufficient-paranoia/" target="_blank" rel="noopener"
 &gt;sufficient paranoia&lt;/a&gt;&amp;rdquo;. When you receive an email, ask yourself: is this email in-character for this person? Is the spelling what I&amp;rsquo;d expect? Is it appropriate? Is it asking me to take an action (even if that action is just opening a file)? If so, is it expected, or is it out of the blue? If it&amp;rsquo;s out of the blue, why? What&amp;rsquo;s the story behind that?&lt;/p&gt;
&lt;p&gt;Real life incident: Sept 30, 2011 - I received an email from a lady I&amp;rsquo;d once interviewed for a job. It was a distraught email saying she was stuck in Wales, had been mugged, lost all her money, and needed a brief loan until she got home. I wrote her an email (not a reply), telling her email had been hacked; lo and behold, I got a reply! &amp;ldquo;It&amp;rsquo;s me&amp;hellip; this is for real, i have checked with the consulate but there is nothing really working out, most important is i don&amp;rsquo;t have enough money on please, please i need you to loan me some, i can pay you back once i get home.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;I ended up finding her cellphone number and sending her a message - she was at home, safe and sound.&lt;/p&gt;
&lt;p&gt;See &lt;a class="link" href="https://blog.malwarebytes.com/cybercrime/2014/08/email-hijack-leads-to-i-was-robbed-send-me-money-scam/" target="_blank" rel="noopener"
 &gt;https://blog.malwarebytes.com/cybercrime/2014/08/email-hijack-leads-to-i-was-robbed-send-me-money-scam/&lt;/a&gt; &amp;ndash; this was exactly the wording I received.&lt;/p&gt;
&lt;h3 id="geez-that-was-a-long-facebook-post-eric"&gt;Geez, that was a long Facebook post Eric.
&lt;/h3&gt;&lt;p&gt;It really was, and a few minutes afterwards, this tweet came to my attention:&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://twitter.com/josephfcox/status/879982828418719744" target="_blank" rel="noopener"
 &gt;https://twitter.com/josephfcox/status/879982828418719744&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s fun to laugh, but it&amp;rsquo;s a good reminder that there&amp;rsquo;s always going to be a weakness. You need to structure your business disaster recovery in a way that you can quickly and efficiently deal with a complete wipe-out like this.&lt;/p&gt;
&lt;h3 id="and-were-done"&gt;And we&amp;rsquo;re done.
&lt;/h3&gt;&lt;p&gt;So, to summarise this essay, you need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Always install updates&lt;/li&gt;
&lt;li&gt;Always take backups&lt;/li&gt;
&lt;li&gt;Use AV software with full journaling and rollback capabilities&lt;/li&gt;
&lt;li&gt;Practice sufficient paranoia&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With these four steps, you will be as safe as the biggest corporate. (roughly speaking)&lt;/p&gt;</description></item><item><title>RingZer0team CTF - Challenge 44</title><link>https://www.ericlight.com/post/r0-44.html</link><pubDate>Sat, 24 Jun 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/r0-44.html</guid><description>&lt;p&gt;There are a bunch of fantastic Capture The Flag security challenges on &lt;a class="link" href="https://www.ringzer0team.com" target="_blank" rel="noopener"
 &gt;RingZer0Team.com&lt;/a&gt;. I&amp;rsquo;ve been working through some of these for a wee while now, and with the &lt;a class="link" href="https://www.cybersecuritychallenge.org.nz/" target="_blank" rel="noopener"
 &gt;New Zealand Cyber Security Challenge&lt;/a&gt; coming up again soon, I thought I&amp;rsquo;d get back into some of them.&lt;/p&gt;
&lt;p&gt;Challenge 56 (&amp;ldquo;Hey Chuck where is the flag?&amp;rdquo;, under the Forensic Challenges) started by only offering a .pcap file. I downloaded Wireshark and had a quick dig. The packet capture consisted of a brief browse of a &amp;ldquo;Chuck Norris Facts&amp;rdquo; website.&lt;/p&gt;
&lt;p&gt;After quickly flicking through the pcap itself looking for low-hanging fruit, I used File -&amp;gt; Export Objects -&amp;gt; HTTP. This takes all the HTTP traffic, recombines the packets into files, and saves them.&lt;/p&gt;
&lt;p&gt;Once I&amp;rsquo;d done that, I opened up the files and had a quick flick through. I checked the images for metadata etc but didn&amp;rsquo;t find anything. However I did fine a picture of Chuck Norris, appearing to urge the reader to keep searching files &amp;ndash; in French.&lt;/p&gt;
&lt;p&gt;When I didn&amp;rsquo;t find anything super-obvious in the image contents, I hopped into Bash and just ran &lt;code&gt;grep -i flag *&lt;/code&gt;. It quickly returned the flag, stored in a php file!&lt;/p&gt;
&lt;p&gt;Nice and easy hunt, great way to finish the day.&lt;/p&gt;</description></item><item><title>RingZer0team CTF - Challenge 65</title><link>https://www.ericlight.com/post/r0-65.html</link><pubDate>Sat, 24 Jun 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/r0-65.html</guid><description>&lt;p&gt;This is a continuation of my series on &lt;a class="link" href="https://www.ringzer0team.com" target="_blank" rel="noopener"
 &gt;RingZer0Team.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Challenge 65 (&amp;ldquo;Hide my ass in my home&amp;rdquo;, under the Forensic challenges) is a nice quick little forensic challenge. You get to download a .tar file, and do a bit of digging to uncover the flag.&lt;/p&gt;
&lt;p&gt;This was a nice easy few minutes. After downloading the archive, I discovered a few files inside - including a &lt;em&gt;particularly groovy&lt;/em&gt; electronica swing track, which I&amp;rsquo;m listening to again right now. Yeaaaaahhhhh.&lt;/p&gt;
&lt;p&gt;Apart from a groovy mp3, the archive contains some dot-files such as .bash_history, a .jpg picture, an index.html, and some other bits.&lt;/p&gt;
&lt;p&gt;I found the Flag in one of the dot-files; specifically, it was inside a Vim swap file that seemed to be leftover from a power failure or similar.&lt;/p&gt;</description></item><item><title>WireGuard - Part Three (Troubleshooting)</title><link>https://www.ericlight.com/post/wg2.html</link><pubDate>Mon, 12 Jun 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/wg2.html</guid><description>&lt;p&gt;This is part of my &lt;a class="link" href="https://www.ericlight.com/post/wg0.html" &gt;brief&lt;/a&gt; &lt;a class="link" href="https://www.ericlight.com/post/wg1.html" &gt;series&lt;/a&gt; on &lt;a class="link" href="https://wireguard.com/" target="_blank" rel="noopener"
 &gt;WireGuard&lt;/a&gt;. I&amp;rsquo;m pretty enamoured with WireGuard and the way it works, but there were a couple slightly curly bits that I needed to get my head around. This troubleshooting guide is a rough dump of the issues I had, and how I fixed them.&lt;/p&gt;
&lt;h2 id="gotten-stuck"&gt;Gotten Stuck?
&lt;/h2&gt;&lt;p&gt;At this stage, there are actually a few ways that this can go wrong, even though we haven&amp;rsquo;t done much. Think through all the bits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installed WireGuard at both ends&lt;/li&gt;
&lt;li&gt;Set up your NAT rule on the remote side&lt;/li&gt;
&lt;li&gt;Created a private and public key on each side&lt;/li&gt;
&lt;li&gt;Put each public key in the opposite side&amp;rsquo;s [Peer] config&lt;/li&gt;
&lt;li&gt;Put a suitable IP address on each side&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting
&lt;/h2&gt;&lt;p&gt;There are, actually, a myriad of ways this can fail:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Broken routing on the client PC&lt;/li&gt;
&lt;li&gt;Broken NAT on the remote router&lt;/li&gt;
&lt;li&gt;Broken routing on the remote PC&lt;/li&gt;
&lt;li&gt;Broken wg0 configuration on one side&lt;/li&gt;
&lt;li&gt;Lack of TCP forwarding on the remote computer&lt;/li&gt;
&lt;li&gt;Lack of Proxy ARP on the remote computer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you can&amp;rsquo;t ping the remote server yet, don&amp;rsquo;t panic. Run tcpdump to find out what you&amp;rsquo;re missing.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On the remote server: &lt;code&gt;tcpdump -i wg0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;On your local machine: &lt;code&gt;ping -c1 10.20.40.1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That will tell you whether your packets are reaching the remote server, or if they&amp;rsquo;re not getting through the tunnel.&lt;/p&gt;
&lt;p&gt;If they&amp;rsquo;re not making it through the tunnel at all, you&amp;rsquo;ll probably be seeing error messages in the ping. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PING 10.20.10.1 (10.20.10.1) 56(84) bytes of data.
From 10.20.40.2 icmp_seq=1 Destination Host Unreachable
ping: sendmsg: Required key not available
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;rsquo;s the error message I got when I set AllowedIPs too strictly. Because I was trying to ping something that was &lt;strong&gt;routable&lt;/strong&gt;, but wasn&amp;rsquo;t within the AllowedIPs range, there was no applicable key for the packet.&lt;/p&gt;
&lt;h2 id="thanks"&gt;Thanks
&lt;/h2&gt;&lt;p&gt;Huge gratitude to &lt;a class="link" href="https://www.zx2c4.com/" target="_blank" rel="noopener"
 &gt;Jason Donenfeld&lt;/a&gt; (aka zx2c4) for spending his time not only reading this post, but also for sending me some fantastic feedback! I&amp;rsquo;d made some bungles in my original post on this topic, and he vastly helped my understanding.&lt;/p&gt;
&lt;p&gt;Also, huge gratitude to another Jason (&lt;a class="link" href="https://keybase.io/rendition" target="_blank" rel="noopener"
 &gt;@rendition&lt;/a&gt;) who has helped me develop from a junior network admin into a &amp;hellip; &amp;lsquo;moderate&amp;rsquo; network admin. I&amp;rsquo;ve learned more in the last year than I ever thought possible. He&amp;rsquo;s taught me nearly everything I know about managed networking, reviewed this post for me, and is actually the guy who introduced me to WireGuard originally!&lt;/p&gt;</description></item><item><title>WireGuard - Part Two (VPN routing)</title><link>https://www.ericlight.com/post/wg1.html</link><pubDate>Sun, 11 Jun 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/wg1.html</guid><description>&lt;p&gt;This is a continuation of my brief series on the new &lt;a class="link" href="https://wireguard.com/" target="_blank" rel="noopener"
 &gt;WireGuard&lt;/a&gt; VPN. &lt;a class="link" href="https://www.ericlight.com/post/wg0.html" &gt;Part One&lt;/a&gt; was about the simple building-blocks to get WireGuard working between two endpoints. Now that we&amp;rsquo;ve got a couple machines able to ping each other by IP address, we can carry on a bit deeper into the inter-LAN routing stuff.&lt;/p&gt;
&lt;p&gt;Extending on from the IP addresses in Part One, instead of JUST connecting to the remote machine, I want to actually have access to everything &lt;em&gt;on the whole 10.20.0.0/16 network&lt;/em&gt;; even the non-WireGuard devices. I want it to be like I&amp;rsquo;m there on-site. The idea here is roughly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Remote machine:&lt;/strong&gt; wg0: 10.20.40.1 (behind public IP 163.172.161.0)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local machine:&lt;/strong&gt; wg0: 10.20.40.2 (with eth0 on 192.168.88.207)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Machines on remote LAN:&lt;/strong&gt; 10.20.0.0/16&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remote LAN Watchguard range:&lt;/strong&gt; 10.20.40.0/16 &amp;ndash; note this is within the remote 10.20.0.0/16 range&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From my local machine, with minimal interaction, I want to be able to ping something like 10.20.&lt;strong&gt;10.30&lt;/strong&gt;, and get a response.&lt;/p&gt;
&lt;p&gt;Happily, now that the two endpoints are talking with each other, there&amp;rsquo;s really not much that has to happen to get things working the way I want.&lt;/p&gt;
&lt;h2 id="remote-config"&gt;Remote Config
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Many Linux distros disable IPv4 packet forwarding by default. But in this case, we very much want this enabled. Edit your &lt;code&gt;/etc/sysctl.conf&lt;/code&gt; file, and look for the line: &lt;code&gt;net.ipv4.ip_forward&lt;/code&gt;, and set the value to 1. You may need to add this line manually, or uncomment it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You&amp;rsquo;ll also need to enable ProxyARP. This is another kernel setting that&amp;rsquo;s usually disabled, so edit &lt;code&gt;/etc/sysctl.conf&lt;/code&gt;, and add the following line: &lt;code&gt;net.ipv4.conf.all.proxy_arp = 1&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reload your kernel settings. A reboot will do the trick, or you could just run &lt;code&gt;sudo sysctl -p /etc/sysctl.conf&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="starting-wireguard-on-boot"&gt;Starting WireGuard on Boot
&lt;/h2&gt;&lt;p&gt;There are a variety options to do this, and if you&amp;rsquo;re a seasoned sysadmin you probably already have a favourite way.&lt;/p&gt;
&lt;p&gt;One option is to add &lt;code&gt;post-up wg-quick up wg0&lt;/code&gt; to the tail of your eth0 block (or appropriate interface) in /etc/network/interfaces.&lt;/p&gt;
&lt;p&gt;A second option (for systemd users) is to simply run &lt;code&gt;systemctl enable wg-quick@wg0&lt;/code&gt;. This will tell systemd to bring the wg0 interface up once a network connection is established.&lt;/p&gt;
&lt;p&gt;I only do this on the remote machine, because I don&amp;rsquo;t want my local machine to be forever spinning up it&amp;rsquo;s WireGuard connection; however I always want the remote machine listening for my packets. That said, there&amp;rsquo;s probably no reason to avoid this; I just haven&amp;rsquo;t done it yet.&lt;/p&gt;
&lt;h2 id="local-config"&gt;Local Config
&lt;/h2&gt;&lt;p&gt;Here&amp;rsquo;s the really cool bit. Since your remote machine is now set up to perform IPv4 forwaring and ProxyARP, the only thing you need to change on the local side is a single number. Or rather, a couple numbers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In your &lt;code&gt;/etc/WireGuard/wg0.conf&lt;/code&gt; file, just expand the network range of your interface to include the entire remote LAN:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; [Interface]
 ...
 Address = 10.20.40.2/16

 [Peer]
 ...
 AllowedIPs = 10.20.0.0/16
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now reload your WireGuard config, either by rebooting, or running &lt;code&gt;sudo wg-quick down wg0 &amp;amp;&amp;amp; sudo wg-quick up wg0&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s all! When you make the above changes, wg-quick will modify your routing table so that &lt;strong&gt;any IP within 10.20.x.y&lt;/strong&gt; will be sent over the wg0 interface. The remote host will dutifully forward the packet out into the rest of the network, and ProxyARP will take care of the rest:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ping -c1 10.20.10.31
PING 10.20.10.31 (10.20.10.31) 56(84) bytes of data.
64 bytes from 10.20.10.31: icmp_seq=1 ttl=63 time=91.8 ms
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting
&lt;/h2&gt;&lt;p&gt;Okay so by now there&amp;rsquo;s a really good chance that you&amp;rsquo;ve bumped into trouble. I&amp;rsquo;ve started on a basic &lt;a class="link" href="https://www.ericlight.com/post/wg2.html" &gt;WireGuard troubleshooting guide&lt;/a&gt;, but it only covers the issues that I bumped into. If you&amp;rsquo;re still stuck after reading through that, ask a question on the WireGuard Mailing List, or reach out via IRC (#WireGuard on Freenode) - this is all on &lt;a class="link" href="https://www.wireguard.com/#contact-the-team" target="_blank" rel="noopener"
 &gt;the WireGuard website&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="wrap-up"&gt;Wrap-up
&lt;/h2&gt;&lt;p&gt;That should be all! When you reboot the remote server (I specify reboot, because you want to test that your solution can survive an outage at the remote site), you should be able to ping other things in the remote LAN without any additional interaction. I still manually run &lt;code&gt;wg-quick up wg0&lt;/code&gt; on my local laptop, because I don&amp;rsquo;t want to be connected remotely &lt;em&gt;all&lt;/em&gt; the time.&lt;/p&gt;
&lt;h2 id="thanks"&gt;Thanks
&lt;/h2&gt;&lt;p&gt;Huge gratitude to &lt;a class="link" href="https://www.zx2c4.com/" target="_blank" rel="noopener"
 &gt;Jason Donenfeld&lt;/a&gt; (aka zx2c4) for spending his time not only reading this post, but also for sending me some fantastic feedback! I&amp;rsquo;d made some bungles in my original post on this topic, and he vastly helped my understanding.&lt;/p&gt;
&lt;p&gt;If you do end up using WireGuard, &lt;em&gt;go forth and &lt;a class="link" href="https://www.wireguard.com/#donations" target="_blank" rel="noopener"
 &gt;donate&lt;/a&gt;&lt;/em&gt;! Seriously, &lt;strong&gt;at very least&lt;/strong&gt;, send Jason the cost of a local cup of coffee or a beer for his efforts.&lt;/p&gt;
&lt;p&gt;Also, huge gratitude to another Jason (&lt;a class="link" href="https://keybase.io/rendition" target="_blank" rel="noopener"
 &gt;@rendition&lt;/a&gt;) who has helped me develop from a junior network admin into a &amp;hellip; &amp;lsquo;moderate&amp;rsquo; network admin. I&amp;rsquo;ve learned more in the last year than I ever thought possible. He&amp;rsquo;s taught me nearly everything I know about managed networking, reviewed this post for me, and is actually the guy who introduced me to WireGuard originally!&lt;/p&gt;</description></item><item><title>WireGuard - Part One (Installation)</title><link>https://www.ericlight.com/post/wg0.html</link><pubDate>Sat, 03 Jun 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/wg0.html</guid><description>&lt;p&gt;&lt;a class="link" href="https://wireguard.com/" target="_blank" rel="noopener"
 &gt;WireGuard&lt;/a&gt; is the most excellent VPN stack around. It&amp;rsquo;s &lt;em&gt;really&lt;/em&gt; fast, the concept of Cryptokey Routing is awesome, and I love the speed and simplicity benefits that come from opionionated cryptography. The protocol is so simple - expressed in a mere 4k lines of code - that it&amp;rsquo;s auditable by anyone.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With my initial naive approach, I found myself using HTTPS, over ports forwarded over SSH tunnels, connected over WireGuard. Although it was straightforward to get WireGuard working between two endpoints, I ended up in nested-crypto hell.&lt;/p&gt;
&lt;p&gt;So, this brief series is about making WireGuard work as a VPN onto a different site. We&amp;rsquo;ll start by making it work between two endpoints, and &lt;a class="link" href="https://www.ericlight.com/post/wg1.html" &gt;we&amp;rsquo;ll go forward from there&lt;/a&gt;. My end goal is to have access to all the resources on a remote site, just by running &lt;code&gt;wg-quick up wg0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The endpoints I&amp;rsquo;m going to set up are at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Remote machine:&lt;/strong&gt; wg0: 10.20.40.1 (behind public IP 163.172.161.0)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local machine:&lt;/strong&gt; wg0: 10.20.40.2&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="nat-setup"&gt;NAT Setup
&lt;/h2&gt;&lt;p&gt;Chances are, your remote endpoint is behind a firewall of some sort. Pick a high port, and configure your firewall to forward UDP packets on that port through to your remote WireGuard endpoint. You don&amp;rsquo;t need to do this on your local side, because reply traffic from the remote side will generally be handled by the stateful session part of your firewall.&lt;/p&gt;
&lt;p&gt;Many routers and firewalls offer port address translation (also known as PAT) as part of port forwarding or NAT. This is when a packet hits the firewall on (say) port 57432, and the firewall puts it on the LAN to port 22, for example. You don&amp;rsquo;t want this. I think it&amp;rsquo;s possible with WireGuard, but it adds complexity without benefit.&lt;/p&gt;
&lt;h2 id="config---remote-site"&gt;Config - Remote Site
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="link" href="https://www.wireguard.com/install/" target="_blank" rel="noopener"
 &gt;Install WireGuard&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Generate your keys. The following will create a public key and a stub config in /etc/WireGuard/:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; cd /etc/WireGuard
 umask 077
 printf &amp;quot;[Interface]\nPrivateKey = &amp;quot; &amp;gt; wg0.conf
 wg genkey | tee -a wg0.conf | wg pubkey &amp;gt; publickey
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit your config to match:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; [Interface]
 PrivateKey = WhAt3v3R= (this is the private key generated on this machine)
 ListenPort = 12345 (this is the UDP port you've forwarded from your firewall)
 Address = 10.20.40.1/24 (this will be the IP given to the wg0 interface)

 [Peer]
 PublicKey = (leave this blank for now; you'll paste in your local public key here soon)
 AllowedIPs = 10.20.40.0/24 (this is the range of WireGuard IP addresses that this Peer's key can be used from)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;That should be all you need to configure on the remote side for now. Save your wg0.conf file, and bring the interface up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; wg-quick up wg0
 ping -c1 10.20.40.1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You should see a bunch of actions performed by wg-quick, and a reply packet from your ping. Now onto the local side.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="config---local-machine"&gt;Config - Local Machine
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Install WireGuard and generate your keys, as per the first two steps above.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit your configuration again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; [Interface]
 PrivateKey = WhAt3v3R+PaRt-tw0= (this is the private key generated on this machine)
 ListenPort = 12345 (this is the UDP port again; I don't think they have to be the same)
 Address = 10.20.40.2/24 (note - different IP address, but in the same range)

 [Peer]
 PublicKey = ?????????? (copy the public key from the REMOTE server here)
 Endpoint = 163.172.161.0:12345 (enter the PUBLIC IP address of the remote site, plus the forwarded port)
 AllowedIPs = 10.20.40.0/24 (specifying that packets using this key must come from within 10.20.40.x)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now that you&amp;rsquo;ve got a local public key, take a second to paste it into the Peer public key section on the remote server.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once you&amp;rsquo;re finished you should be able to bring the interface up and ping it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; wg-quick up wg0
 ping -c1 10.20.40.2
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;hellip; and you should even be able to ping the remote server as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; ping -c1 10.20.40.1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gotten-stuck"&gt;Gotten Stuck?
&lt;/h2&gt;&lt;p&gt;At this stage, there are actually a few ways that this can go wrong, even though we haven&amp;rsquo;t done much. Here&amp;rsquo;s a quick summary of everything we&amp;rsquo;ve done:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installed WireGuard at both ends&lt;/li&gt;
&lt;li&gt;Set up your NAT rule on the remote side&lt;/li&gt;
&lt;li&gt;Created a private and public key on each side&lt;/li&gt;
&lt;li&gt;Put each public key in the opposite side&amp;rsquo;s [Peer] config&lt;/li&gt;
&lt;li&gt;Put a suitable IP address on each side&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;rsquo;ve nailed each of those and you&amp;rsquo;re still having trouble, you can have a quick look at the brief Troubleshooting guide I&amp;rsquo;ve put together as &lt;a class="link" href="https://www.ericlight.com/post/wg2.html" &gt;Part Three&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="onto-part-two"&gt;Onto Part Two
&lt;/h2&gt;&lt;p&gt;That should be all you need to get WireGuard working between two machines on two different sites. So far we haven&amp;rsquo;t done anything either interesting or uncommon - this is all the basic stuff you&amp;rsquo;ll find on the &lt;a class="link" href="https://www.wireguard.com/quickstart/" target="_blank" rel="noopener"
 &gt;WireGuard Quick Start&lt;/a&gt; page, although expressed slightly differently. &lt;a class="link" href="https://www.ericlight.com/post/wg1.html" &gt;The next article&lt;/a&gt; will be a bit more about intra-site routing.&lt;/p&gt;
&lt;h2 id="thanks"&gt;Thanks
&lt;/h2&gt;&lt;p&gt;Huge gratitude to &lt;a class="link" href="https://www.zx2c4.com/" target="_blank" rel="noopener"
 &gt;Jason Donenfeld&lt;/a&gt; (aka zx2c4) for spending his time not only reading this post, but also for sending me some fantastic feedback! I&amp;rsquo;d made some bungles in my original post on this topic, and he vastly helped my understanding.&lt;/p&gt;
&lt;p&gt;If you do end up using WireGuard, &lt;em&gt;go forth and &lt;a class="link" href="https://www.wireguard.com/#donations" target="_blank" rel="noopener"
 &gt;donate&lt;/a&gt;&lt;/em&gt;! Seriously, &lt;strong&gt;at very least&lt;/strong&gt;, send Jason the cost of a local cup of coffee or a beer for his efforts.&lt;/p&gt;
&lt;p&gt;Also, huge gratitude to another Jason (&lt;a class="link" href="https://keybase.io/rendition" target="_blank" rel="noopener"
 &gt;@rendition&lt;/a&gt;) who has helped me develop from a junior network admin into a &amp;hellip; &amp;lsquo;moderate&amp;rsquo; network admin. I&amp;rsquo;ve learned more in the last year than I ever thought possible. He&amp;rsquo;s taught me nearly everything I know about managed networking, reviewed this post for me, and is actually the guy who introduced me to WireGuard originally!&lt;/p&gt;</description></item><item><title>RingZer0team CTF - Linux Sysadmin challenges</title><link>https://www.ericlight.com/post/r0-sysadmin.html</link><pubDate>Sun, 28 May 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/r0-sysadmin.html</guid><description>&lt;p&gt;There are a bunch of fantastic Capture The Flag security challenges on &lt;a class="link" href="https://www.ringzer0team.com" target="_blank" rel="noopener"
 &gt;RingZer0Team.com&lt;/a&gt;. I&amp;rsquo;ve been working through some of these for a wee while now, and with the &lt;a class="link" href="https://www.cybersecuritychallenge.org.nz/" target="_blank" rel="noopener"
 &gt;New Zealand Cyber Security Challenge&lt;/a&gt; coming up again soon, I thought I&amp;rsquo;d get back into some of them.&lt;/p&gt;
&lt;p&gt;The Sysadmin Linux series of challenges is where you&amp;rsquo;re trying to breach the security of a Linux system. I actually finished most of these last year, but I wanted to finish my last two. Of course, to get to the last two stages, you need to use the flags from the &lt;em&gt;previous&lt;/em&gt; stages. So I&amp;rsquo;m revisiting them.&lt;/p&gt;
&lt;h2 id="level-1---morpheus---trinity"&gt;Level 1 - Morpheus -&amp;gt; Trinity
&lt;/h2&gt;&lt;p&gt;We start by SSH&amp;rsquo;ing into a particular user account on the ringzer0team server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;You have mail.
Last login: Thu Apr 27 02:52:40 2017 from &amp;lt;somewhere&amp;gt;
morpheus@forensics:~$ 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s only one file in the home folder, and I can&amp;rsquo;t read it. There&amp;rsquo;s a /home/trinity folder with full read access, but also nothing legible.&lt;/p&gt;
&lt;p&gt;The flag for level 1 is found by running ps aux, which reveals what appears to be Trinity&amp;rsquo;s password:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root 3241 0.0 0.0 4188 572 ? S Jan14 1:44 /bin/sh /root/backup.sh -u trinity -p Flag-&amp;lt;redacted&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="level-2---morpheus---architect"&gt;Level 2 - Morpheus -&amp;gt; Architect
&lt;/h2&gt;&lt;p&gt;Aha, and the flag for level two is in /etc/fstab, which contains what appears to be The Architect&amp;rsquo;s password, in base64:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0
/dev/fd0 /media/floppy0 auto rw,user,noauto 0 0
#//TheMAtrix/phone /media/Matrix cifs username=architect,password=$(base64 -d &amp;quot;&amp;lt;redacted&amp;gt;&amp;quot;),iocharset=utf8,sec=ntlm 0 0
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="level-3---the-architect"&gt;Level 3 - The Architect
&lt;/h2&gt;&lt;p&gt;Level 3 requires you to log on as architect, using the password we discovered earlier. The only clue is &amp;ldquo;dig for password&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;This bit got a bit harder. There are a couple possible hints in architect&amp;rsquo;s mail file, including a bunch of attempts to mount a cifs volume, and reference to a file in /backup/.&lt;/p&gt;
&lt;p&gt;Digging through the files in /backup left me at a loss. There are references to /tmp/Gathering.py, but that&amp;rsquo;s a challenge for later (cypher&amp;rsquo;s challenge). After some digging I located /var/tmp/.swl, which contained some MySQL credentials!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; show tables;
+----------------+
| Tables_in_arch |
+----------------+
| arch |
| flag |
+----------------+
2 rows in set (0.00 sec)

mysql&amp;gt; select * from arch;
+------+-----------------------+
| id | arch |
+------+-----------------------+
| 1 | The one |
| 1 | The null one |
| 1 | The mother of the one |
| 1 | The father of the one |
| 1 | The flag of the one |
| 1 | The null one |
+------+-----------------------+
6 rows in set (0.00 sec) 

mysql&amp;gt; select * from flag;
+---------------------------------+
| flag |
+---------------------------------+
| FLAG-&amp;lt;redacted&amp;gt; |
+---------------------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yasss after a solid hour of digging, I&amp;rsquo;ve found the flag for the third level!&lt;/p&gt;
&lt;h2 id="level-four---morpheus---oracle"&gt;Level Four - Morpheus -&amp;gt; Oracle
&lt;/h2&gt;&lt;p&gt;Again we&amp;rsquo;re logging on as morpheus, but this time the goal is to access the oracle account.&lt;/p&gt;
&lt;p&gt;Lots of tasty stuff under /var/tmp/.viminfo, now that I&amp;rsquo;ve found it. References to files in /backup/, to /tmp/Gathering.py, /tmp/mail_cypher&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t make the mistake of trying to cat .swo; it&amp;rsquo;ll eat your console session.&lt;/p&gt;
&lt;p&gt;Found this interesting thing in mail, but it&amp;rsquo;s not helpful: &lt;code&gt;forensics.localdomain : Apr 14 21:14:33 : morpheus : user NOT in sudoers ; TTY=pts/4 ; PWD=/home/trinity ; USER=root ; COMMAND=/usr/sbin/usermod -aG neo morpheus&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In one of the /backup files, I found the remains of an SSH key, and it worked! Access to the oracle account achieved. In the home folder, we&amp;rsquo;ve got a handy-dandy Base64-encoded flag in flag.txt.&lt;/p&gt;
&lt;h2 id="level-five---oracle-encrypted-file"&gt;Level Five - Oracle Encrypted File
&lt;/h2&gt;&lt;p&gt;There&amp;rsquo;s a file in the oracle home folder named encflag.txt.enc:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;U2FsdGVkX1+dCl4WEHNJKBqA8a4fQeheOgA7oiNmjwlJQvGaQAgqcIsGRIcbdHKF
heSs51JRSEmOLqVyGvoxDA--
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Decoding the base64 returns a binary blob, prefixed with the string &amp;ldquo;Salted&amp;rdquo;. This is one of the levels that I never completed originally, so maybe it&amp;rsquo;s time to give it another crack.&lt;/p&gt;
&lt;p&gt;A quick google of &amp;ldquo;salted base64&amp;rdquo; reveals an &lt;a class="link" href="https://security.stackexchange.com/a/124333" target="_blank" rel="noopener"
 &gt;interesting comment on StackExchange&lt;/a&gt;. Apparently I&amp;rsquo;m looking at a file encrypted with the OpenSSL &amp;rsquo;enc&amp;rsquo; command, so I first copy the file to my own computer to work.&lt;/p&gt;
&lt;p&gt;I discover that the command &lt;code&gt;openssl enc -in testfile -d -a&lt;/code&gt; will un-base64 it, then load the file in. I need to pass it a password to decrypt with though, so now I need to find that.&lt;/p&gt;
&lt;p&gt;Oh my god I just did &lt;code&gt;cat .*&lt;/code&gt; in the oracle home folder and literally found an alias that reads and decrypts the file. I can&amp;rsquo;t believe that took me almost an hour.&lt;/p&gt;
&lt;p&gt;There are no words.&lt;/p&gt;
&lt;h2 id="level-six---trinity---neo"&gt;Level Six - Trinity -&amp;gt; Neo
&lt;/h2&gt;&lt;p&gt;Okay getting serious now. Using Trinity&amp;rsquo;s account, I need to find the password for the neo account.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a bit noisy on login:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;You have mail.
Last login: Tue Apr 25 16:29:29 2017 from &amp;lt;le blah&amp;gt;
-bash: hello: command not found
Sup Neo!
ls: cannot open directory /home/neo: Permission denied
cat: phonebook: Permission denied
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A vague tickle in my memory prompted me to run sudo -l right off the bat. Rewarded with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;User trinity may run the following commands on this host:
 (neo) /bin/cat /home/trinity/*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So of course I immediately run &lt;code&gt;sudo -u neo /bin/cat /home/trinity/*&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This gives us a &amp;lsquo;phone book&amp;rsquo; containing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The Oracle 1800-133-7133
Persephone 345-555-1244





copy made by Cypher copy utility on /home/neo/phonebook
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Trinity&amp;rsquo;s .bashrc contains a bit of kruft:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hello neo
echo &amp;quot;Sup Neo!&amp;quot;
$(ls -lart /home/neo)
cat phonebook
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Really not useful. I remember finding Trinity&amp;rsquo;s password with &lt;code&gt;ps aux&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root 3241 0.0 0.0 4188 572 ? S Jan14 1:47 /bin/sh /root/backup.sh -u trinity -p Flag-08grILsn3ekqhDK7cKBV6ka8B
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It looks a little bit like a MySQL connection string, so I try that but no dice. Nothing under /var/tmp this time, and grep doesn&amp;rsquo;t find anything useful under the /backup goldmine.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s some weirdness under /etc/passwd. I don&amp;rsquo;t know what this means, but saving it for later:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;trinity:x:1002:1002:trinity,%,lsdf(940998+(n.~,3):/home/trinity:/bin/bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I looked through the mail file, but nothing jumped out at me there. Also trawled again through /backup, as well as /var/backups. Then /etc and /var. Argh.&lt;/p&gt;
&lt;p&gt;Finally I start looking for Persephone. Nothing helpful, but it reminds me of the last line in the phonebook.&lt;/p&gt;
&lt;p&gt;copy made by Cypher copy utility on /home/neo/phonebook&lt;/p&gt;
&lt;p&gt;And then I remember that the sudo command allows a * at the end of the cat command, which might allow me to do path traversal&amp;hellip;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo -u neo /bin/cat /home/trinity/../neo/phonebook
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, after a whole hour of digging, I&amp;rsquo;m awarded Neo&amp;rsquo;s password!&lt;/p&gt;
&lt;h2 id="level-7---neo-is-not-alone"&gt;Level 7 - Neo is Not Alone
&lt;/h2&gt;&lt;p&gt;I don&amp;rsquo;t know what this clue means, but I bet it has something to do with Persephone. Persephone comes from Greek mythology as one of Zeus&amp;rsquo; daughters, and the goddess of the underworld. Does that help me here? I don&amp;rsquo;t know, it&amp;rsquo;s getting late&amp;hellip;&lt;/p&gt;
&lt;p&gt;I run &lt;code&gt;cat .*&lt;/code&gt; in Neo&amp;rsquo;s home directory to see if there&amp;rsquo;s anything hiding there, but no luck this time. Also nothing for &lt;code&gt;sudo -l&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s an unreadable file (owned by root) called &amp;lsquo;result.stat&amp;rsquo;, that&amp;rsquo;s probably related to something. I browse the mail history and see:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;forensics.localdomain : Dec 7 14:08:08 : neo : user NOT in sudoers ; TTY=pts/2 ; PWD=/home/neo ; USER=morpheus ; COMMAND=/home/morpheus/egrep /home/morpheus/../neo/result.stat
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That could be handy. I do remember an egrep in /home/neo, will have a look. Lots of reference to /bin/monitor, too.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m only in the neo group, so nothing to see there.&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;ps aux | grep neo&lt;/code&gt; shows a heap of /bin/monitor processes started by root, but running under neo. There&amp;rsquo;s also a &amp;ldquo;SCREEN&amp;rdquo; instance there, but running &lt;code&gt;screen -D -RR&lt;/code&gt; doesn&amp;rsquo;t reclaim it, so something&amp;rsquo;s up there. I&amp;rsquo;m pretty sure there&amp;rsquo;s something there in /bin/monitor.&lt;/p&gt;
&lt;p&gt;In all honesty this one had me beat. It was half-past midnight and I was exhausted. I knew that there was something special about /bin/monitor, and I knew there was something special about the fact that it was running as neo. But I took the expedient route and had a quick google. I found the answer at &lt;a class="link" href="http://blog.dornea.nu/2016/10/30/ringzer0-ctf-sysadmin-linux/" target="_blank" rel="noopener"
 &gt;http://blog.dornea.nu/2016/10/30/ringzer0-ctf-sysadmin-linux/&lt;/a&gt; - without this I could have been looking for years. However, as is so often the case, this tutorial was the basis of some great learning for me.&lt;/p&gt;
&lt;p&gt;Because the process is owned by neo, and because /bin/monitor could be &lt;em&gt;read&lt;/em&gt; by neo, it meant I could run a stack trace. &lt;em&gt;I have never done this before&lt;/em&gt; - no false impressions here, I totally relied on that dornea.ru page to tip me off to the usage of strace. But once I knew that, I had the flag.&lt;/p&gt;
&lt;p&gt;I was very well misled by this one, actually. The Persephone comment in the phonebook totally led me down the wrong path, and I spent quite a long time searching for her details on the system. It was the reddest herring possible.&lt;/p&gt;
&lt;h2 id="level-8---morpheus---cypher"&gt;Level 8 - Morpheus -&amp;gt; Cypher
&lt;/h2&gt;&lt;p&gt;Okay it&amp;rsquo;s late now so I&amp;rsquo;m going to try to thrash this one quick. Nothing in &lt;code&gt;ps aux&lt;/code&gt; for cypher. Grepping /backup found a python file and a dump showing a cron job runs this file every minute. The contents of the python file are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import os
os.system('ps aux &amp;gt; /tmp/28JNvE05KBltE8S7o2xu')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can&amp;rsquo;t read the output file, but I can edit the python script! This is gonna be easy.&lt;/p&gt;
&lt;p&gt;After a little bit of trial and error, I edited the python script to first list the contents of the /home/cypher folder, and after that, to output the contents of /home/cypher/flag.txt&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s important to note that the python file is recreated every three minutes when it&amp;rsquo;s run, so you need to redo your changes for every iteration.&lt;/p&gt;
&lt;h1 id="fin"&gt;Fin
&lt;/h1&gt;&lt;p&gt;That&amp;rsquo;s the end! I&amp;rsquo;m quite pleased I&amp;rsquo;ve managed to finish all of the Sysadmin Linux section. Of course that&amp;rsquo;s also scary, because it means I need to break into the other sections. That&amp;rsquo;s OK though&amp;hellip; it&amp;rsquo;s a good time to do it!&lt;/p&gt;</description></item><item><title>RingZer0team CTF - Challenge 148</title><link>https://www.ericlight.com/post/r0-148.html</link><pubDate>Sat, 27 May 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/r0-148.html</guid><description>&lt;p&gt;There are a bunch of fantastic Capture The Flag security challenges on &lt;a class="link" href="https://www.ringzer0team.com" target="_blank" rel="noopener"
 &gt;RingZer0Team.com&lt;/a&gt;. I&amp;rsquo;ve been working through some of these for a wee while now, and with the &lt;a class="link" href="https://www.cybersecuritychallenge.org.nz/" target="_blank" rel="noopener"
 &gt;New Zealand Cyber Security Challenge&lt;/a&gt; coming up again soon, I thought I&amp;rsquo;d get back into some of them.&lt;/p&gt;
&lt;p&gt;Challenge 148 (&amp;ldquo;Sysadmin Linux Level 2&amp;rdquo;) is one of a series of challenges where you&amp;rsquo;re trying to breach the security of a Linux system. I actually finished most of these last year, but I wanted to finish my last two. Of course, to get to the last two stages, you need to use the flags from the &lt;em&gt;previous&lt;/em&gt; stages. So I&amp;rsquo;m revisiting them.&lt;/p&gt;
&lt;p&gt;We start by SSH&amp;rsquo;ing into a particular user account on the ringzer0team server:&lt;/p&gt;
&lt;p&gt;You have mail.
Last login: Thu Apr 27 02:52:40 2017 from &lt;somewhere&gt;
morpheus@forensics:~$&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s only one file in the home folder, and I can&amp;rsquo;t read it. There&amp;rsquo;s a /home/trinity folder with full read access, but also nothing legible.&lt;/p&gt;
&lt;p&gt;Running ps aux reveals what appears to be Trinity&amp;rsquo;s password:&lt;/p&gt;
&lt;p&gt;root 3241 0.0 0.0 4188 572 ? S Jan14 1:44 /bin/sh /root/backup.sh -u trinity -p Flag-&lt;redacted&gt;&lt;/p&gt;
&lt;p&gt;Aha, and /etc/fstab contains what appears to be The Architect&amp;rsquo;s password, in base64:&lt;/p&gt;
&lt;p&gt;/dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0
/dev/fd0 /media/floppy0 auto rw,user,noauto 0 0
#//TheMAtrix/phone /media/Matrix cifs username=architect,password=$(base64 -d &amp;ldquo;&lt;redacted&gt;&amp;rdquo;),iocharset=utf8,sec=ntlm 0 0&lt;/p&gt;
&lt;p&gt;Great! Now I can carry on to my &lt;em&gt;actual&lt;/em&gt; goal, which was to nail challenge 91 (&amp;ldquo;Sysadmin Linux Level 7&amp;rdquo;)!&lt;/p&gt;</description></item><item><title>RingZer0team CTF - Challenge 57</title><link>https://www.ericlight.com/post/r0-57.html</link><pubDate>Fri, 05 May 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/r0-57.html</guid><description>&lt;p&gt;This is a continuation of my series on &lt;a class="link" href="https://www.ringzer0team.com" target="_blank" rel="noopener"
 &gt;RingZer0Team.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Challenge 57 (&amp;ldquo;Hash Breaker Reloaded&amp;rdquo;, under the Coding Challenges) is one of a series of challenges where you&amp;rsquo;re simply presented with a hash - you need to return the plaintext value to the page within 3 seconds.&lt;/p&gt;
&lt;p&gt;In contrast to &lt;a class="link" href="https://www.ericlight.com/post/r0-56.html" &gt;Challenge 56&lt;/a&gt;, &lt;strong&gt;this&lt;/strong&gt; challenge also includes a salt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;You have 3 seconds to break this hash
Send the answer back using https://ringzer0team.com/challenges/57/[clear_text]


----- BEGIN HASH -----
ab9507edbb2501b3c02e47c51af0178d68655980
----- END HASH -----

----- BEGIN SALT -----
c2ac9d8d004b4011d0864e76c7ebaaccfd18464bb8ff66bdbf19a703eb95a944
----- END SALT -----
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The hash looks like another SHA-1, but of course the online hash reversers don&amp;rsquo;t have the &lt;em&gt;now-salted&lt;/em&gt; hash in their rainbow tables. I figured that the challenge was a simple continuation of the previous challenge, so I crossed my fingers and guessed the hash was simply a number (from last time), concatenated with the plain-text salt.&lt;/p&gt;
&lt;p&gt;&amp;hellip; And I was lucky! The below code got me the flag:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/python3
from requests import get
from hashlib import sha1
from re import search

url='https://ringzer0team.com/challenges/57'
session=dict(PHPSESSID='&amp;lt;blahblah&amp;gt;')
resp=get(url,cookies=session)
hash=resp.text.split(&amp;quot;-----&amp;quot;)[2].split(&amp;quot;\t&amp;quot;)[2].split(&amp;quot;&amp;lt;&amp;quot;)[0]
salt=resp.text.split(&amp;quot;-----&amp;quot;)[6].split(&amp;quot;\t&amp;quot;)[2].split(&amp;quot;&amp;lt;&amp;quot;)[0]
newhash=''
salt=salt.encode('utf-8')
x=0
while newhash != hash:
		newhash=sha1(str(x).encode('utf-8')+salt).hexdigest()
		print(&amp;quot;%s = %s&amp;quot; % (newhash, x))
		x+=1
	
resp=get(url+'/'+str(x-1),cookies=session)
flag=search(&amp;quot;FLAG-.{24}&amp;quot;,resp.text).group()
print(flag)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As last time, there&amp;rsquo;s no error handling in that code, so if it runs for more than a few seconds it&amp;rsquo;s probably toast.&lt;/p&gt;</description></item><item><title>RingZer0team CTF - Challenge 56</title><link>https://www.ericlight.com/post/r0-56.html</link><pubDate>Tue, 02 May 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/r0-56.html</guid><description>&lt;p&gt;There are a bunch of fantastic Capture The Flag security challenges on &lt;a class="link" href="https://www.ringzer0team.com" target="_blank" rel="noopener"
 &gt;RingZer0Team.com&lt;/a&gt;. I&amp;rsquo;ve been working through some of these for a wee while now, and with the &lt;a class="link" href="https://www.cybersecuritychallenge.org.nz/" target="_blank" rel="noopener"
 &gt;New Zealand Cyber Security Challenge&lt;/a&gt; coming up again soon, I thought I&amp;rsquo;d get back into some of them.&lt;/p&gt;
&lt;p&gt;Challenge 56 (&amp;ldquo;Hash Breaker&amp;rdquo;, under the Coding Challenges) is one of a series of challenges where you&amp;rsquo;re simply presented with a hash - you need to return the plaintext value to the page within 3 seconds.&lt;/p&gt;
&lt;p&gt;Of course, this is impossible to do manually, so it&amp;rsquo;s a programming challenge.&lt;/p&gt;
&lt;p&gt;The hash looks like a simple SHA-1, so I put it into an online hash reverser and discovered it&amp;rsquo;s just a SHA1 hash of a random number. SHA1 is really fast, so this should be simple.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how I tackled the problem:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!python
# It's in Python3, because of reasons
from requests import get
from hashlib import sha1
from re import search
calculated_hash=''
x=0

# Your session cookie needs to go here
session=dict(PHPSESSID='&amp;lt;cookie contents&amp;gt;')

# Load the web page
url='https://ringzer0team.com/challenges/56'
resp=get(url,cookies=session)

# Extract the hash from the page contents
target_hash=resp.text.split(&amp;quot;-----&amp;quot;)[2].split(&amp;quot;\t&amp;quot;)[2].split(&amp;quot;&amp;lt;&amp;quot;)[0]

# Iterate hashes from zero until the calculated hash matches the target hash
while calculated_hash != target_hash:
		calculated_hash=sha1(str(x).encode('utf-8')).hexdigest()
		print(&amp;quot;%s = %s&amp;quot; % (calculated_hash, x))
		x+=1

# If we got here, yay! We found the key. Now submit it back to the site, and print our magic flag
resp=get(url+'/'+str(x-1),cookies=session)
flag=search(&amp;quot;FLAG-.{24}&amp;quot;,resp.text).group()
print(flag)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s no error handling in that code, so if it runs for more than a few seconds it&amp;rsquo;s probably toast.&lt;/p&gt;</description></item><item><title>Making Lektor work with grsecurity</title><link>https://www.ericlight.com/post/lektor.html</link><pubDate>Sat, 29 Oct 2016 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/lektor.html</guid><description>&lt;p&gt;I started using &lt;a class="link" href="https://grsecurity.net/" target="_blank" rel="noopener"
 &gt;grsecurity&lt;/a&gt; on my servers in 2015, and there&amp;rsquo;s always a bit of &lt;a class="link" href="https://wiki.archlinux.org/index.php/Grsecurity" target="_blank" rel="noopener"
 &gt;tuning&lt;/a&gt; &lt;a class="link" href="http://hardenedlinux.org/system-security/2016/01/10/hardening-your-desktop-linux-mint-with-grsec.html" target="_blank" rel="noopener"
 &gt;required&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I was recently playing with &lt;a class="link" href="https://www.getlektor.com" target="_blank" rel="noopener"
 &gt;Lektor&lt;/a&gt; (before I swapped to &lt;a class="link" href="https://www.getpelican.com" target="_blank" rel="noopener"
 &gt;Pelican&lt;/a&gt;), and I had a bit of trouble with my grsec kernel. In particular, Lektor and Pelican are both run within a virtualenv Python environment, and grsec eats it like popcorn in two different ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;TPE (Trusted Path Execution) throws a wobbly:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;[253241.370019] grsec: From {ssh-origin-ip}: denied untrusted exec (due to file in world-writable directory) of /tmp/#50 by /usr/local/lib/lektor/bin/lektor[lektor:60593] uid/euid:1000/1000 gid/egid:1000/1000, parent /bin/bash[bash:60581] uid/euid:1000/1000 gid/egid:1000/1000&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This block occurs because the virtualenv violates grsecurity&amp;rsquo;s Trusted Path Execution protection - the Python executable isn&amp;rsquo;t under a trusted path, and the user isn&amp;rsquo;t in the TPE-bypass group.&lt;/p&gt;
&lt;p&gt;To resolve this one, add your user to the TPE group. This will allow the user to execute binaries which aren&amp;rsquo;t in trusted locations:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;sudo usermod -aG grsec-tpe $USER&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;RWX protection. This is a common problem with Python-based apps, even though Python has an exception (Edit 2020-04-12 - Issue 6 from &lt;a class="link" href="https://github.com/thestinger/paxd/" target="_blank" rel="noopener"
 &gt;https://github.com/thestinger/paxd/&lt;/a&gt; has been deleted) by default.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;[ 207.534876] grsec: From {ssh-source-ip}: denied RWX mmap of &amp;lt;anonymous mapping&amp;gt; by /usr/local/lib/lektor/bin/lektor[lektor:534] uid/euid:1000/1000 gid/egid:1000/1000, parent /bin/bash[bash:477] uid/euid:1000/1000 gid/egid:1000/1000&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;First, create your PaX ELF headers, and then disable grsec&amp;rsquo;s MEMPROTECT extension on the included python2 binary, while you enable EMUTRAMP:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;sudo paxctl /usr/local/lib/lektor/bin/python2 -c&lt;/code&gt;&lt;br&gt;
&lt;code&gt;sudo paxctl /usr/local/lib/lektor/bin/python2 -Em&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Result!&lt;/p&gt;</description></item><item><title>Updating the modem and radio firmware on a Samsung Galaxy 5 (G900I)</title><link>https://www.ericlight.com/post/g900i-update.html</link><pubDate>Thu, 27 Oct 2016 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/g900i-update.html</guid><description>&lt;p&gt;A couple months ago, &lt;a class="link" href="http://www.checkpoint.com" target="_blank" rel="noopener"
 &gt;Check Point&lt;/a&gt; revealed their discovery of the &lt;a class="link" href="http://blog.checkpoint.com/2016/08/07/quadrooter/" target="_blank" rel="noopener"
 &gt;Quadrooter vulnerability&lt;/a&gt; affecting the Qualcomm chipsets in oodles of Android phones.&lt;/p&gt;
&lt;p&gt;I use &amp;ndash;CyanogenMod&amp;ndash; &lt;a class="link" href="http://www.lineageos.org" target="_blank" rel="noopener"
 &gt;LineageOS&lt;/a&gt; on a Samsung Galaxy S5, so thankfully I &lt;a class="link" href="https://web.archive.org/web/20161223020015/http://www.cyanogenmod.org/blog/cm-13-0-release-znh5y" target="_blank" rel="noopener"
 &gt;received patches&lt;/a&gt; for three of the four vulnerabilities in only a few days.&lt;/p&gt;
&lt;p&gt;However, that last vulnerability was part of a proprietary binary blob for controlling the Qualcomm LTE chipset, only patchable by Samsung themselves. It took a while for the Samsung updates to roll out, and then I got distracted for a while, but I finally downloaded my firmware. The package I&amp;rsquo;ve used is &amp;ldquo;G900IDVU1CPH3&amp;rdquo;, which seems to be compatible at least with the three NZ-based carriers, as well as all the Australian carriers.&lt;/p&gt;
&lt;p&gt;There are a couple little issues with the firmware upgrade, easily fixed if you know how. I&amp;rsquo;m going to assume you know exactly how to do everything without help. I&amp;rsquo;m sure you&amp;rsquo;re pleased.&lt;/p&gt;
&lt;p&gt;In particular, the version of Heimdall in the Debian Sid repositories (1.4.1-2) doesn&amp;rsquo;t quite work with the SGS5. It appears &lt;a class="link" href="https://www.google.com/search?q=ERROR%3A&amp;#43;Failed&amp;#43;to&amp;#43;send&amp;#43;request&amp;#43;to&amp;#43;end&amp;#43;PIT&amp;#43;file&amp;#43;transfer%21&amp;#43;samsung" target="_blank" rel="noopener"
 &gt;other people&lt;/a&gt; have had similar problems.&lt;/p&gt;
&lt;p&gt;The beginning of fix for me came from &lt;a class="link" href="https://github.com/turboyz" target="_blank" rel="noopener"
 &gt;turboyz&lt;/a&gt; on Github, at the bottom of this post: (Edit 2020-04-12: GitHub Issue 348 from &lt;a class="link" href="https://github.com/Benjamin-Dobell/Heimdall/" target="_blank" rel="noopener"
 &gt;https://github.com/Benjamin-Dobell/Heimdall/&lt;/a&gt; has been deleted); however, he&amp;rsquo;s manually made a couple changes to BridgeManager.cpp, which appear to be no longer necessary. We can simply build it from source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get install build-essential cmake zlib1g-dev libusb-1.0-0-dev git
git clone https://github.com/Benjamin-Dobell/Heimdall.git
cd Heimdall

# OPTIONAL: Remove the `if(NOT DISABLE_FRONTEND)` codeblock at the end of Heimdall/CMakeLists.txt
# I believe this just saves time compiling the GUI

mkdir build &amp;amp;&amp;amp; cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
cd bin 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you&amp;rsquo;ve got a nice new Heimdall installation, with the approproate updates to allow it to talk nicely to the new Samsung bootloader.&lt;/p&gt;
&lt;p&gt;I copied my new baseband files into the Heimdall/build/bin folder, just to get them all together. The last step is to flash your NON-HLOS.bin and modem.bin files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./heimdall flash --APNHLOS NON-HLOS.bin --MODEM modem.bin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I happen to have an issue on my phone currently where, even though the modem and LTE drivers have both been successfully installed, and even thought the Quadrooter tester is no longer showing any vulnerabilities, my Baseband version on my phone is still shown as the old one. I haven&amp;rsquo;t been able to figure out why yet, but I don&amp;rsquo;t think I&amp;rsquo;ll worry about it for now. There have been reports that you should first do this with &amp;ndash;no-reboot, wait for the update to complete, then pull your battery, then when you power back on, immediately go &lt;em&gt;back&lt;/em&gt; into download mode and re-flash. Apparently this helps update the recognised Baseband version, but to be honest it didn&amp;rsquo;t help me.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re completely 100% lucky and absolutely nothing goes wrong, you win! You should now have the most recent Samsung modem and LTE chipset drivers available for your phone&amp;hellip; without having to roll back to the stock Samsung firmware.&lt;/p&gt;
&lt;p&gt;Incidentally, if you want to save gigabytes and time downloading said firmware, and if your phone is precisely a Samsung Galaxy S5 (G900I), and if you definitely want firmware G900IDVU1CPH3, I&amp;rsquo;ve extracted the important files (modem.bin and NON-HLOS.bin) and stored them here:&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://www.ericlight.com/files/G900IDVU1CPH3_modem_LTE.zip" target="_blank" rel="noopener"
 &gt;https://www.ericlight.com/files/G900IDVU1CPH3_modem_LTE.zip&lt;/a&gt;&lt;br&gt;
SHA256 hash = a2ab13063583f6e83a3c2d8b79521a59ba103dda30a24bddf9248dd5a25bff3c&lt;/p&gt;
&lt;p&gt;I promise I haven&amp;rsquo;t intentionally backdoored them, but I make no warranties of any sort. They might just be pictures of my foot.&lt;/p&gt;
&lt;p&gt;Good luck!&lt;/p&gt;</description></item><item><title>Using ECDSA certificates with Let's Encrypt</title><link>https://www.ericlight.com/post/ecdsa_lets_encrypt.html</link><pubDate>Thu, 27 Oct 2016 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/ecdsa_lets_encrypt.html</guid><description>&lt;p&gt;&lt;a class="link" href="https://www.letsencrypt.org" target="_blank" rel="noopener"
 &gt;Let&amp;rsquo;s Encrypt&lt;/a&gt;&amp;rsquo;s Certbot will generate an RSA key by default. But we want to step into the new and exciting world of elliptic curve cryptography! Unfortunately Certbot doesn&amp;rsquo;t really roll that way, so there are a couple hoops to jump through first.&lt;/p&gt;
&lt;p&gt;A word of caution: this post has been written in retrospect, some time after I actually got ECDSA working. That means there are bound to be squiggly little steps that I&amp;rsquo;ve missed, and I certainly should have provided screenshots or snippets that I&amp;rsquo;ve missed. Sorry.&lt;/p&gt;
&lt;p&gt;This post assumes you&amp;rsquo;ve already installed Certbot. I had a working regular certificate from Certbot before I changed to ECDSA, so if you have problems following this from scratch, I do recommend trying that first.&lt;/p&gt;
&lt;p&gt;For future reference, I&amp;rsquo;m running the latest certbot available in Debian unstable, which is version 0.8.1-3.&lt;/p&gt;
&lt;p&gt;I got most of this information from &lt;a class="link" href="https://scotthelme.co.uk/tag/lets-encrypt/" target="_blank" rel="noopener"
 &gt;Scott Helme&amp;rsquo;s website&lt;/a&gt;, which has been awesome.&lt;/p&gt;
&lt;p&gt;In brief:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Generate yourself an ECDSA private key:&lt;/p&gt;
&lt;p&gt;openssl ecparam -genkey -name secp384r1 | openssl ec -out ec.key&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can change the curve that you use, if you feel a bit wiggly about the &lt;a class="link" href="http://blog.cr.yp.to/20140323-ecdsa.html" target="_blank" rel="noopener"
 &gt;controversy around the NSA &amp;amp; NIST&lt;/a&gt; degrading the quality of the curves. I don&amp;rsquo;t feel particularly wiggly about that, myself.&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;
&lt;p&gt;Generate a Certificate Signing Request (CSR) with your shiny new key:&lt;/p&gt;
&lt;p&gt;openssl req -new -sha256 -key ec.key -nodes -out ec.csr -outform pem&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That will give you ec.key (your private key), and ec.csr (your certificate signing request). Time to get Let&amp;rsquo;s Encrypt involved.&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;
&lt;p&gt;Create your certificate:&lt;/p&gt;
&lt;p&gt;certbot certonly -w /var/www/html/ -d {your_domain} &amp;ndash;email &amp;ldquo;{your_email}&amp;rdquo; &amp;ndash;csr ./ec.csr &amp;ndash;agree-tos&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If everything goes perfectly, that should leave you with a new shiny set of certificates &amp;ndash; quite possibly named something clumsy like 0000-cert.pem and 0001-fullchain.pem, or similar. Throw those into your nginx config and give it a test to see if it&amp;rsquo;s working.&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Schedule your certificate renewals:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I had particular trouble with the renewal process of ECDSA certificates, because &lt;code&gt;certbot renew&lt;/code&gt; isn&amp;rsquo;t compatible with custom CSR&amp;rsquo;s. You need to run &lt;code&gt;certbot certonly&lt;/code&gt; to pass the &amp;ndash;csr argument, and then you need to deal with the output yourself.&lt;/p&gt;
&lt;p&gt;Even more irksome, the certonly function will fail if you ask it to renew certificates which already exist:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;An unexpected error occurred:
OSError: [Errno 17] File exists: '/etc/letsencrypt/live/{your_domain}/cert_ecdsa.pem'
Please see the logfiles in /var/log/letsencrypt for more details.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There doesn&amp;rsquo;t seem to be any way to tell certbot to overwrite the old certificates automatically, so I created a /etc/letsencrypt/temp folder, and wrote up a really yuck cron job for it. If I were working on a production system I&amp;rsquo;d do something better, but this works for my lowly domain:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Recreate certs under /etc/letsencrypt/temp
30 2 24 * * certbot certonly -w /var/www/html/ -d {your_domain} --email &amp;quot;{your_email}&amp;quot; --csr /path/to/your/ec.csr --agree-tos --non-interactive --webroot --cert-path /etc/letsencrypt/temp/cert_ecdsa.pem --fullchain-path /etc/letsencrypt/temp/fullchain_ecdsa.pem

# Backup current certs to home dir
31 2 24 * * mv /etc/letsencrypt/live/{your_domain}/cert_ecdsa.pem ~/certbackup/
31 2 24 * * mv /etc/letsencrypt/live/{your_domain}/fullchain_ecdsa.pem ~/certbackup/

# Move new certs to live folder
32 2 24 * * mv /etc/letsencrypt/temp/* /etc/letsencrypt/live/{your_domain}/

# Restart nginx
33 2 24 * * service nginx restart
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&amp;rsquo;s all! It seems to be working so far, but I&amp;rsquo;m sure something is going to fail at some point &amp;ndash; maybe I&amp;rsquo;ll hit my request limit, or the Let&amp;rsquo;s Encrypt service will be down, and I&amp;rsquo;ll lose my certs. If it happens too often I&amp;rsquo;ll come up with a nicer cronjob and update this post.&lt;/p&gt;</description></item></channel></rss>