<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Linux on Such geek. Wow.</title><link>https://www.ericlight.com/tags/linux.html</link><description>Recent content in Linux on Such geek. Wow.</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Thu, 27 Aug 2026 00:00:00 +1200</lastBuildDate><atom:link href="https://www.ericlight.com/tags/linux/index.xml" rel="self" type="application/rss+xml"/><item><title>DR planning (aka how to rebuild my PC)</title><link>https://www.ericlight.com/post/disaster-recovery.html</link><pubDate>Thu, 27 Aug 2026 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/disaster-recovery.html</guid><description>&lt;img src="https://www.ericlight.com/post/disaster-recovery/gmktec.png" alt="Featured image of post DR planning (aka how to rebuild my PC)" /&gt;&lt;p&gt;This one is written for future me, when I inevitably suffer the consequences of buying a $150 micro-PC from AliExpress equipped with an SSD that was swept off the floor after a flood.&lt;/p&gt;
&lt;p&gt;&amp;hellip; I regret nothing.&lt;/p&gt;
&lt;p&gt;Anyway.&lt;/p&gt;
&lt;p&gt;The blog itself is just static files (at some point I&amp;rsquo;ll write up the Pelican -&amp;gt; Hugo journey), so although the blog will keep running, I&amp;rsquo;ll have lost the ability to change anything. This blog has been written as I&amp;rsquo;ve set up my toolchain on a brand-new machine, so it&amp;rsquo;s kinda my disaster recovery plan.&lt;/p&gt;
&lt;h2 id="the-toolchain"&gt;The toolchain
&lt;/h2&gt;&lt;p&gt;I run Debian, and this blog is based on Hugo now, so grab the extended Hugo binary from &lt;a class="link" href="https://github.com/gohugoio/hugo/releases" target="_blank" rel="noopener"
 &gt;the releases page&lt;/a&gt; and get the non-snapd version of &lt;a class="link" href="https://github.com/sass/dart-sass/releases" target="_blank" rel="noopener"
 &gt;Dart Sass&lt;/a&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-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt install -y git curl golang-go
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tar xzf ~/Downloads/hugo_extended_*.tar.gz -C ~ hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tar xzf ~/Downloads/dart-sass-*-linux-x64.tar.gz -C ~/Downloads
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mv ~/hugo /usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mv ~/Downloads/dart-sass /opt/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ln -sf /opt/dart-sass/sass /usr/local/bin/sass
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hugo version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="the-keys"&gt;The keys
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;New machine, new keys&lt;/em&gt;&lt;/strong&gt;, or so they say.&lt;/p&gt;
&lt;p&gt;Lol nevermind, nobody says that. Restore them from my password manager like an adult. Then rebuild &lt;code&gt;~/.ssh/config&lt;/code&gt;. &lt;em&gt;(make sure the blog server is the top line, for reasons that will soon become apparent)&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="restore-the-blog-content"&gt;Restore the blog content
&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;git clone git@github.com:rhyven/ericlight.com.git ericlight.com
cd ericlight.com
hugo mod get
hugo --minify --gc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;rsquo;ll bring down the content of the blog itself, along with &lt;code&gt;go.mod&lt;/code&gt; which will automatically pull down the Stack theme once we run &lt;code&gt;hugo mod get&lt;/code&gt;. This is the point where I can have a look with &lt;code&gt;hugo server&lt;/code&gt; and have a sense-check.&lt;/p&gt;
&lt;p&gt;Incidentally, that also pins the Stack theme to the version I was running; update that with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hugo mod get -u github.com/CaiJimmy/hugo-theme-stack/v4
hugo mod tidy
rm -rf public resources/_gen
hugo server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[this will absolutely rumble CSP ffs]&lt;/p&gt;
&lt;h2 id="the-publish-script"&gt;The publish script
&lt;/h2&gt;&lt;p&gt;Recreate &lt;code&gt;publish_blog.sh&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-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;set -e
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SERVER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;awk &lt;span style="color:#e6db74"&gt;&amp;#39;/^Host /{print $2; exit}&amp;#39;&lt;/span&gt; ~/.ssh/config&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd ~/ericlight.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rm -rf public resources/_gen
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hugo --minify --gc
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rsync -az --delete --dry-run --itemize-changes public/ &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$SERVER&lt;span style="color:#e6db74"&gt;:/var/www/ericlight.com/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;read -r -p &lt;span style="color:#e6db74"&gt;&amp;#34;Dry-run info above. Hit Ctrl+C now if that looks cursed, or Enter to publish.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rsync -az --delete public/ &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$SERVER&lt;span style="color:#e6db74"&gt;:/var/www/ericlight.com/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Oh yeah, it&amp;rsquo;s all coming together.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="writing-a-post"&gt;Writing a post
&lt;/h2&gt;&lt;p&gt;Hugo posts are &lt;em&gt;page bundles&lt;/em&gt; (unlike Pelican, from which I&amp;rsquo;ve recently migrated), so it&amp;rsquo;s a directory with an &lt;code&gt;index.md&lt;/code&gt; in it, and the images live alongside:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir ~/ericlight.com/content/post/yeah-so-my-ssd-finally-shat-the-bed
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Front matter needs &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt;, &lt;code&gt;categories&lt;/code&gt;, &lt;code&gt;tags&lt;/code&gt;, &lt;code&gt;summary&lt;/code&gt;, and maybe even a hero &lt;code&gt;image&lt;/code&gt; to make it all look nice.&lt;/p&gt;
&lt;p&gt;Images go in the post&amp;rsquo;s own folder, referenced by bare filename:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![Alt-text for screen readers](screenshot.png &amp;quot;The caption everyone sees&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Leave the caption off and the theme just shows the alt text instead, which is usually fine.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;draft: true&lt;/code&gt; plus &lt;code&gt;hugo server -D&lt;/code&gt; to preview before committing to anything.&lt;/p&gt;
&lt;h2 id="publishing-it"&gt;Publishing it
&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;git add -A
git commit -m &amp;quot;New post: ssd failure post, as predicted&amp;quot;
git push
./publish_blog.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;git add -A&lt;/code&gt; rather than &lt;code&gt;git add .&lt;/code&gt;, because &lt;code&gt;-A&lt;/code&gt; catches deletions too.&lt;/p&gt;
&lt;h2 id="what-about-things-that-arent-the-blog-eric"&gt;What about things that aren&amp;rsquo;t the blog, Eric?
&lt;/h2&gt;&lt;p&gt;There isn&amp;rsquo;t much! I&amp;rsquo;d need to reinstall Steam and StarCraft, reinstall the ESPHome builder and connect it to Home Assistan&amp;hellip; that&amp;rsquo;s about it.&lt;/p&gt;
&lt;p&gt;In fact, this article&amp;rsquo;s mere existence illustrates a regression towards infrastructure managment that I&amp;rsquo;m not entirely pleased with&amp;hellip;&lt;/p&gt;
&lt;p&gt;Until next time!&lt;/p&gt;</description></item><item><title>task pve-bridge blocked for more than 120 seconds - on Proxmox with MDATP</title><link>https://www.ericlight.com/post/mdfe_bridgebreak.html</link><pubDate>Sun, 13 Mar 2022 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/mdfe_bridgebreak.html</guid><description>&lt;img src="https://www.ericlight.com/post/mdfe_bridgebreak/mdatp-bridge1.jpg" alt="Featured image of post task pve-bridge blocked for more than 120 seconds - on Proxmox with MDATP" /&gt;&lt;p&gt;Today I updated and rebooted a bunch of servers - all in a day&amp;rsquo;s work. Everything went fine, until one of the hosts (the big one) didn&amp;rsquo;t boot up again properly.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve got two hosts, both running ProxmoxVE (version 7.1) and Microsoft Defender for Endpoint (version 101.61.69-insiderfast). On reboot, one of the hosts came up fine; the other didn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;Long story short, uninstalling mdatp fixed the problem - wild hypothesis, but I suspect it was interfering with either network bridge or interprocess communication.&lt;/p&gt;
&lt;p&gt;The rest of this post is technical info for people who might be able to fix it, and so that this blog post will come up for the other people who inevitably bump into this!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Symptoms - upon boot, the host came up, was apparently able to launch one VM, and recieved a timeout for all subsequent VM&amp;rsquo;s:&lt;/p&gt;
&lt;p&gt;&lt;img alt="A screenshot of the failed VM start actions." class="gallery-image" data-flex-basis="1462px" data-flex-grow="609" height="210" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.ericlight.com/post/mdfe_bridgebreak/mdatp-bridge1.jpg" srcset="https://www.ericlight.com/post/mdfe_bridgebreak/mdatp-bridge1_hu_6327a14e3e9952cd.jpg 800w, https://www.ericlight.com/post/mdfe_bridgebreak/mdatp-bridge1.jpg 1280w" width="1280"&gt;&lt;/p&gt;
&lt;p&gt;The lines are truncated, but all those pink lines are showing &lt;code&gt;TASK ERROR: start failed: command '/usr/bin/kvm -id 153 [...]' failed: got timeout&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I say &amp;lsquo;apparently&amp;rsquo; launched one VM, because I was unable to interact with it - in fact &lt;strong&gt;all&lt;/strong&gt; the launch-on-boot VM&amp;rsquo;s appeared to have booted, except everything about them was non-responsive, including Proxmox stats windows and console.&lt;/p&gt;
&lt;p&gt;Trying to manually interact with the VM&amp;rsquo;s using &lt;code&gt;qm&lt;/code&gt; failed entirely - the console froze, completely unresponsive to either ^C or ^X, until I forcefully disconnected from SSH.&lt;/p&gt;
&lt;p&gt;Checking dmesg revealed a horror story:&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-console" data-lang="console"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:36 buckwheat kernel: [ 159.853700] vmbr1: port 1(eth3) entered blocking state
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:36 buckwheat kernel: [ 159.853703] vmbr1: port 1(eth3) entered forwarding state
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:43 buckwheat kernel: [ 166.700586] ixgbe 0000:81:00.1 eth3: NIC Link is Down
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:43 buckwheat kernel: [ 166.701135] vmbr1: port 1(eth3) entered disabled state
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:45 buckwheat kernel: [ 168.294208] ixgbe 0000:81:00.1 eth3: NIC Link is Up 10 Gbps, Flow Control: RX/TX
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:45 buckwheat kernel: [ 168.294343] vmbr1: port 1(eth3) entered blocking state
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:45 buckwheat kernel: [ 168.294349] vmbr1: port 1(eth3) entered forwarding state
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:47 buckwheat pvestatd[5040]: VM 112 qmp command failed - VM 112 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 112 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:50 buckwheat pvestatd[5040]: VM 105 qmp command failed - VM 105 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 105 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:53 buckwheat pvestatd[5040]: VM 115 qmp command failed - VM 115 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 115 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:55 buckwheat pve-guests[11257]: start failed: command &amp;#39;/usr/bin/kvm -id 153 -name Eden -no-shutdown -chardev &amp;#39;socket,id=qmp,path=/var/run/qemu-server/153.qmp,s&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:56 buckwheat pvesh[5530]: Starting VM 153 failed: start failed: command &amp;#39;/usr/bin/kvm -id 153 -name Eden -no-shutdown -chardev &amp;#39;socket,id=qmp,path=/var/run/qem&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:56 buckwheat pve-guests[5530]: &amp;lt;root@pam&amp;gt; end task UPID:buckwheat:000015C7:00000710:622D6A6F:startall::root@pam: OK
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:56 buckwheat systemd[1]: Finished PVE guests.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:56 buckwheat systemd[1]: Reached target Multi-User System.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:56 buckwheat systemd[1]: Reached target Graphical Interface.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:56 buckwheat systemd[1]: Starting Update UTMP about System Runlevel Changes...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:56 buckwheat systemd[1]: systemd-update-utmp-runlevel.service: Succeeded.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:56 buckwheat systemd[1]: Finished Update UTMP about System Runlevel Changes.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:56 buckwheat systemd[1]: Startup finished in 4.603s (kernel) + 2min 54.823s (userspace) = 2min 59.427s.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:56 buckwheat pvestatd[5040]: VM 104 qmp command failed - VM 104 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 104 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:59 buckwheat pvestatd[5040]: VM 153 qmp command failed - VM 153 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - got timeout
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:54:59 buckwheat pvestatd[5040]: status update time (30.177 seconds)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:55:18 buckwheat pvestatd[5040]: VM 104 qmp command failed - VM 104 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 104 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:55:21 buckwheat pvestatd[5040]: VM 153 qmp command failed - VM 153 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 153 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:55:24 buckwheat pvestatd[5040]: VM 112 qmp command failed - VM 112 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 112 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:55:27 buckwheat pvestatd[5040]: VM 105 qmp command failed - VM 105 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 105 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:55:30 buckwheat pvestatd[5040]: VM 115 qmp command failed - VM 115 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 115 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:55:30 buckwheat pvestatd[5040]: status update time (30.186 seconds)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:55:48 buckwheat pvestatd[5040]: VM 153 qmp command failed - VM 153 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 153 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:55:51 buckwheat pvestatd[5040]: VM 104 qmp command failed - VM 104 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 104 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:55:54 buckwheat pvestatd[5040]: VM 115 qmp command failed - VM 115 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 115 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:55:57 buckwheat pvestatd[5040]: VM 105 qmp command failed - VM 105 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 105 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:56:00 buckwheat pvestatd[5040]: VM 112 qmp command failed - VM 112 qmp command &amp;#39;query-proxmox-support&amp;#39; failed - unable to connect to VM 112 qmp socket - timeout a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:56:00 buckwheat pvestatd[5040]: status update time (30.191 seconds)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 16:56:00 buckwheat kernel: [ 243.301563] INFO: task wdavdaemon:5583 blocked for more than 120 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The wdavdaemon is shown blocking here, but pve-bridge turned up just as frequently in the logs:&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-console" data-lang="console"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root@buckwheat:/var/log# grep blocked syslog
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 18:34:14 buckwheat kernel: [ 242.802463] INFO: task wdavdaemon:5740 blocked for more than 120 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 18:34:14 buckwheat kernel: [ 242.802658] INFO: task wdavdaemon:4899 blocked for more than 120 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 18:34:14 buckwheat kernel: [ 242.802840] INFO: task pve-bridge:6117 blocked for more than 120 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 18:34:14 buckwheat kernel: [ 242.802945] INFO: task pve-bridge:7734 blocked for more than 120 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 18:34:14 buckwheat kernel: [ 242.803057] INFO: task pve-bridge:9120 blocked for more than 120 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 18:34:14 buckwheat kernel: [ 242.803170] INFO: task pve-bridge:10283 blocked for more than 120 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 18:36:15 buckwheat kernel: [ 363.631430] INFO: task wdavdaemon:5740 blocked for more than 241 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 18:36:15 buckwheat kernel: [ 363.631610] INFO: task wdavdaemon:4899 blocked for more than 241 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 18:36:15 buckwheat kernel: [ 363.631776] INFO: task pve-bridge:6117 blocked for more than 241 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mar 13 18:36:15 buckwheat kernel: [ 363.631872] INFO: task pve-bridge:7734 blocked for more than 241 seconds.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So the interesting thing is that another node - foxtail - was also updated to the same version of both Proxmox and mdatp. The only obvious difference I can see are the numbers of VLANs each of them are bridging to:&lt;/p&gt;
&lt;p&gt;This is a list of the bridges now, when they&amp;rsquo;re both working (sorry, Markdown hates tabs; the below should be four tidy columns):&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-console" data-lang="console"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root@foxtail:/var/log# brctl show
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bridge name	bridge id		STP enabled	interfaces
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fwbr101i0	8000.9e7164f22bab	no		fwln101i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							tap101i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vmbr0		8000.c2602668d5f4	no		eno1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							fwpr101p0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							tap100i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							tap109i0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;versus&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-console" data-lang="console"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root@buckwheat:/var/log# brctl show
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bridge name	bridge id		STP enabled	interfaces
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fwbr102i0	8000.6	abd66965438	no		fwln102i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							tap102i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fwbr104i0	8000.f60b3f1a3118	no		fwln104i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							tap104i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fwbr105i0	8000.961281d6d5dc	no		fwln105i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							tap105i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vmbr0		8000.90e2bad572a8	no		eth2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							tap112i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							tap115i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							tap153i0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vmbr0v5		8000.0ea35ee013ba	no		eth2.5
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							fwpr104p0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vmbr0v666	8000.1a23193ccf17	no		eth2.666
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							fwpr102p0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;							fwpr105p0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vmbr1		8000.90e2bad572a9	no		eth3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But when buckwheat was broken, the majority of the bridges were not visible:&lt;/p&gt;
&lt;p&gt;&lt;img alt="A screenshot of the active bridges on each VM host. Buckwheat is missing a lot." class="gallery-image" data-flex-basis="2118px" data-flex-grow="882" height="145" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.ericlight.com/post/mdfe_bridgebreak/mdatp-bridge2.jpg" srcset="https://www.ericlight.com/post/mdfe_bridgebreak/mdatp-bridge2_hu_eda51eb7137e999c.jpg 800w, https://www.ericlight.com/post/mdfe_bridgebreak/mdatp-bridge2.jpg 1280w" width="1280"&gt;&lt;/p&gt;
&lt;p&gt;At some point during troubleshooting, I restarted pvedaemon - although the service had started correctly, the restart failed with error: &lt;code&gt;timeout waiting on systemd&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Acronis Cyber Protect and Microsoft Defender on the same Linux system</title><link>https://www.ericlight.com/post/mdfe_acronis.html</link><pubDate>Sun, 07 Nov 2021 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/mdfe_acronis.html</guid><description>&lt;p&gt;A few months ago, I &lt;a class="link" href="https://www.ericlight.com/post/mdfe_linux.html" &gt;published what I learned&lt;/a&gt; from playing with the Linux version of &lt;a class="link" href="https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/microsoft-defender-endpoint-linux?view=o365-worldwide" target="_blank" rel="noopener"
 &gt;Microsoft Defender for Endpoint&lt;/a&gt; a few months back. If you&amp;rsquo;re here, you&amp;rsquo;ll have possibly already read my original post. There was a bit of tuning required to get it to behave nicely; just adding some sensible audit logging exclusions.&lt;/p&gt;
&lt;p&gt;Well the Acronis Cyber Protect backup platform has recently been added to the bundle, and it had a few specific requirements, so I&amp;rsquo;ve documented them here.&lt;/p&gt;
&lt;p&gt;There are four Acronis processes which MDATP will spend a lot of time scanning and rescanning. Exclude those from the scanning engine by executing the following commands as root:&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;mdatp exclusion process add --path /usr/lib/Acronis/Schedule/schedul2-bin
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mdatp exclusion process add --path /usr/lib/Acronis/APL/active-protection
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mdatp exclusion process add --path /opt/acronis/aakore
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mdatp exclusion process add --path /usr/lib/Acronis/BackupAndRecovery/mms
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are also five processes which need to be excluded from auditctl, unless you want your audit logs rotated every ten minutes. Again, these must all be run as root.&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;echo -a never,exit -S &lt;span style="color:#ae81ff"&gt;41&lt;/span&gt; -S &lt;span style="color:#ae81ff"&gt;42&lt;/span&gt; -F comm&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;mms&amp;#34;&lt;/span&gt; -k exclude_acronis &amp;gt;&amp;gt; /etc/audit/rules.d/01-exclusion.rules
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo -a never,exit -S &lt;span style="color:#ae81ff"&gt;41&lt;/span&gt; -S &lt;span style="color:#ae81ff"&gt;42&lt;/span&gt; -S &lt;span style="color:#ae81ff"&gt;43&lt;/span&gt; -F comm&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;adp-agent&amp;#34;&lt;/span&gt; -k exclude_acronis &amp;gt;&amp;gt; /etc/audit/rules.d/01-exclusion.rules
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo -a never,exit -S &lt;span style="color:#ae81ff"&gt;41&lt;/span&gt; -S &lt;span style="color:#ae81ff"&gt;42&lt;/span&gt; -S &lt;span style="color:#ae81ff"&gt;43&lt;/span&gt; -S &lt;span style="color:#ae81ff"&gt;288&lt;/span&gt; -F exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/usr/lib/Acronis/APL/active-protection -k exclude_acronis &amp;gt;&amp;gt; /etc/audit/rules.d/01-exclusion.rules
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo -a never,exit -S &lt;span style="color:#ae81ff"&gt;41&lt;/span&gt; -S &lt;span style="color:#ae81ff"&gt;42&lt;/span&gt; -S &lt;span style="color:#ae81ff"&gt;43&lt;/span&gt; -F exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/opt/acronis/bin/updater -k exclude_acronis &amp;gt;&amp;gt; /etc/audit/rules.d/01-exclusion.rules
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo -a never,exit -S &lt;span style="color:#ae81ff"&gt;41&lt;/span&gt; -S &lt;span style="color:#ae81ff"&gt;42&lt;/span&gt; -S &lt;span style="color:#ae81ff"&gt;288&lt;/span&gt; -F exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/opt/acronis/aakore -k exclude_acronis &amp;gt;&amp;gt; /etc/audit/rules.d/01-exclusion.rules
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once you&amp;rsquo;ve created the exclusions, you can either reboot or run &lt;code&gt;service auditd restart&lt;/code&gt;. Either way, make sure you run &lt;code&gt;service auditd status&lt;/code&gt; to ensure nothing went wrong with the exclusions.&lt;/p&gt;</description></item><item><title>Microsoft Defender for Endpoint (mdatp) on Debian Sid</title><link>https://www.ericlight.com/post/mdfe_linux.html</link><pubDate>Wed, 07 Jul 2021 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/mdfe_linux.html</guid><description>&lt;p&gt;** 2021-08-01 Update: **&lt;/p&gt;
&lt;p&gt;This is a better string to find out what&amp;rsquo;s hitting your audit log: &lt;code&gt;cat /var/log/audit/audit.log* | cut -d ' ' -f26 | sort | uniq -c | sort -n | tail -n 6 | head -n5&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Linux doesn&amp;rsquo;t have many great antivirus options available.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t get me wrong, there are actually a few options nowadays. We&amp;rsquo;ve got the ever-present &lt;a class="link" href="https://www.clamav.net/" target="_blank" rel="noopener"
 &gt;ClamAV&lt;/a&gt;; &lt;a class="link" href="https://www.bitdefender.com" target="_blank" rel="noopener"
 &gt;BitDefender&lt;/a&gt; has a good reputation, but I haven&amp;rsquo;t played with it yet; &lt;a class="link" href="https://www.sophos.com/en-us/support/documentation/sophos-anti-virus-for-linux.aspx?" target="_blank" rel="noopener"
 &gt;Sophos AV&lt;/a&gt; for Linux &lt;em&gt;seems&lt;/em&gt; to be in limbo. &lt;a class="link" href="https://www.eset.com/int/home/antivirus-linux/" target="_blank" rel="noopener"
 &gt;ESET for Linux&lt;/a&gt; exists, as does &lt;a class="link" href="https://techdocs.broadcom.com/us/en/symantec-security-software/endpoint-security-and-management/endpoint-protection/all/getting-up-and-running-on-for-the-first-time-v45150512-d43e1033/installing-clients-with-save-package-v16194723-d21e1502/installing-the-client-for-linux-v95193124-d21e2986.html" target="_blank" rel="noopener"
 &gt;Symantec Endpoint Protection&lt;/a&gt; for Linux. That&amp;rsquo;s a pretty decent range - but they each have some real drawback. Assuming the price is right, you still see compatibility, usability, licensing dramas, or resource drain challenges.&lt;/p&gt;
&lt;p&gt;Most recently, the Linux version of &lt;a class="link" href="https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/microsoft-defender-endpoint-linux?view=o365-worldwide" target="_blank" rel="noopener"
 &gt;Microsoft Defender for Endpoint&lt;/a&gt; entered the playing field. I finally got to play with this and I gotta say&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Holy shit.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Look, I know we enjoy ragging on Microsoft. They&amp;rsquo;ve demonstrated some awful behaviour over the years, and every action still harkens back to the &amp;ldquo;Embrace, Extend, Extinguish&amp;rdquo; &lt;em&gt;modus operandi&lt;/em&gt;. But they&amp;rsquo;re doing really great work with the Defender/DATP/MDFE/whatever line. Even the basic Defender has been steading climbing the ranks, to the point where virtually &lt;em&gt;all&lt;/em&gt; guidance I&amp;rsquo;ve heard for the last two years is: &amp;ldquo;if you&amp;rsquo;re not going full EDR, just use regulr Defender&amp;rdquo;. It&amp;rsquo;s no SentinelOne or CrowdStrike, but overall Defender just Gets The Job Done.&lt;/p&gt;
&lt;p&gt;So, I was excited to try the Linux version. Long story short, it was a dream. The installation process was &lt;em&gt;streaks ahead&lt;/em&gt; of the competition. Resource usage is generally negligible, adding an average load of around 0.5% CPU, going up to about 16% CPU during a scan. There&amp;rsquo;s a robust health and connectivity test built-in. Basically the whole thing just works, to the same level we&amp;rsquo;ve learned to expect from the Windows version. Oh and this one has &lt;strong&gt;actual documentation&lt;/strong&gt; which seems to be considered optional by some of the competitors. 🙃&lt;/p&gt;
&lt;p&gt;However.&lt;/p&gt;
&lt;p&gt;You may find that mdatp is frantically scanning files that freqently Do Things. Bind9 (named) for example, might be handling hundreds of queries a minute. Each one of them triggers &lt;em&gt;not only&lt;/em&gt; an mdatp scan, but also auditd entries&amp;hellip; which often logs more than once per query. I was finding logs being filled and rotated &lt;strong&gt;every seven minutes&lt;/strong&gt; in some cases&amp;hellip; and then punctuated by auditd yelling &amp;ldquo;my buffer is full, I can&amp;rsquo;t log all these events!&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;So as a result, I&amp;rsquo;ve spent quite a few hours learning how to wrangle auditd around exclusions. Here&amp;rsquo;s what I&amp;rsquo;ve learned:&lt;/p&gt;
&lt;h1 id="you-need-to-lie-to-install-mdfe-on-sid"&gt;You need to lie to install MDFE on Sid
&lt;/h1&gt;&lt;p&gt;Edit &lt;code&gt;/etc/os-release&lt;/code&gt; and change &lt;code&gt;VERSION_ID=&amp;quot;11&amp;quot;&lt;/code&gt; to &lt;code&gt;VERSION_ID=&amp;quot;10&amp;quot;&lt;/code&gt;. After that, you can install MDFE following the regular instructions. Don&amp;rsquo;t forget to change it back later!&lt;/p&gt;
&lt;h1 id="troubleshooting-performance-issues"&gt;Troubleshooting performance issues:
&lt;/h1&gt;&lt;p&gt;&lt;em&gt;See also: &lt;a class="link" href="https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/linux-support-perf?view=o365-worldwide" target="_blank" rel="noopener"
 &gt;https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/linux-support-perf?view=o365-worldwide&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;First step - find the processes that mdatp is spending the most CPU time on:&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;&lt;span style="color:#75715e"&gt;# Download Microsoft&amp;#39;s parser (only do this once)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget -c https://raw.githubusercontent.com/microsoft/mdatp-xplat/master/linux/diagnostic/high_cpu_parser.py
&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:#75715e"&gt;# Ask Defender to output the stats, and then parse it looking for high CPU:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ mdatp diagnostic real-time-protection-statistics --output json | python high_cpu_parser.py
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;925&lt;/span&gt; 	mongodb		&lt;span style="color:#ae81ff"&gt;29184&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;37575	pulseaudio	&lt;span style="color:#ae81ff"&gt;47&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;21355	packagekitd	&lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;37588	dbus-daemon	&lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;37550	sshd		&lt;span style="color:#ae81ff"&gt;25&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; Yikes, it&amp;rsquo;s probably not necessary to scan MongoDB thirty thousand times! You can exclude a process from mdatp like this: &lt;code&gt;sudo mdatp exclusion process add --path /usr/bin/mongod&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;But that&amp;rsquo;s not all&amp;hellip; even though mdatp is no longer &lt;strong&gt;scanning&lt;/strong&gt; the application, you still have auditd frantically logging &lt;em&gt;every single thing it does&lt;/em&gt;. That&amp;rsquo;s also going to cause periodic slowdowns as the auditd buffer fills up, overflows, panicks, and then purges the stuff it couldn&amp;rsquo;t write down.&lt;/p&gt;
&lt;h2 id="syslogaudit-logging-issues"&gt;Syslog/audit logging issues
&lt;/h2&gt;&lt;p&gt;You can find out if anything is spewing a billion entries into your audit log, by just grepping for the rotation in syslog:&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;&lt;span style="color:#75715e"&gt;# grep &amp;#39;Audit daemon rotating&amp;#39; /var/log/syslog&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Jul &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt; 01:00:08 spam auditd&lt;span style="color:#f92672"&gt;[&lt;/span&gt;28996&lt;span style="color:#f92672"&gt;]&lt;/span&gt;: Audit daemon rotating log files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Jul &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt; 04:00:05 spam auditd&lt;span style="color:#f92672"&gt;[&lt;/span&gt;28996&lt;span style="color:#f92672"&gt;]&lt;/span&gt;: Audit daemon rotating log files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Jul &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt; 06:57:01 spam auditd&lt;span style="color:#f92672"&gt;[&lt;/span&gt;28996&lt;span style="color:#f92672"&gt;]&lt;/span&gt;: Audit daemon rotating log files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Jul &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt; 09:57:18 spam auditd&lt;span style="color:#f92672"&gt;[&lt;/span&gt;28996&lt;span style="color:#f92672"&gt;]&lt;/span&gt;: Audit daemon rotating log files
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; Filling up a log file every three hours is &lt;em&gt;weird&lt;/em&gt;, but previously this server was doing it every few minutes. You can see what&amp;rsquo;s causing all the log rotations with:&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;&lt;span style="color:#75715e"&gt;# cat /var/log/audit/audit.log* | cut -d &amp;#39; &amp;#39; -f26 | sort | uniq -c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;138581&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/bin/bash&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/bin/hostname&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/bin/nano&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;684&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/lib/systemd/systemd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;4754&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/lib/systemd/systemd-logind&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;209&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/lib/systemd/systemd-user-runtime-dir&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;119&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/opt/microsoft/mdatp/sbin/osqueryi&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;9&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/bin/apt-get&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;2133&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/bin/dbus-daemon&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;13212&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/bin/perl&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;10784&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/bin/pmxcfs&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;14&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/bin/rrdcached&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/bin/sort&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/lib/postfix/sbin/cleanup&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;880&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/lib/postfix/sbin/pickup&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;175&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/lib/postfix/sbin/qmgr&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;27&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/lib/postfix/sbin/smtp&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/lib/postfix/sbin/trivial-rewrite&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/sbin/cron&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;10326&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/sbin/ebtables-legacy&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;10326&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/sbin/ebtables-legacy-restore&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/sbin/postdrop&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/sbin/qmeventd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/sbin/sendmail&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;56&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/sbin/smartd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;3255&lt;/span&gt; exe&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/sbin/sshd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The number on the left shows the number of times that binary has had it&amp;rsquo;s activity logged. This should clearly show the problem executables&amp;hellip; today we&amp;rsquo;re looking at &lt;code&gt;perl&lt;/code&gt;, &lt;code&gt;pmxcfs&lt;/code&gt;, and &lt;code&gt;ebtables-legacy&lt;/code&gt;. Once you&amp;rsquo;ve got that, you need to determine which &lt;em&gt;syscalls&lt;/em&gt; are part of regular noise:&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;&lt;span style="color:#75715e"&gt;# grep /usr/bin/pmxcfs /var/log/audit/audit.log* | cut -d &amp;#39; &amp;#39; -f 4 | sort | uniq -c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;10856&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;8142&lt;/span&gt; syscall&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;263&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;1357&lt;/span&gt; syscall&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;43&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;1357&lt;/span&gt; syscall&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;84&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Referring to &lt;a class="link" href="https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/" target="_blank" rel="noopener"
 &gt;this document&lt;/a&gt;, we can see these syscalls are sys_accept, sys_rmdir, and sys_unlinkat. Since pmxcfs is the ProxmoxVS Cluster File System, these are frankly all pretty normal syscalls for it to make. Let&amp;rsquo;s ignore them.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;echo -a never,exit -S 43 -S 84 -S 263 -F exe=/usr/bin/pmxcfs -k exclude_PVE_internals &amp;gt;&amp;gt; /etc/audit/rules.d/01-exclusion.rules&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;^ Gotta do that as root, btw, or just append the line however you see fit. Once you&amp;rsquo;ve added exclusions for all of your high-noise entires, run &lt;code&gt;service auditd restart&lt;/code&gt; and then &lt;code&gt;service auditd status&lt;/code&gt; to make sure it worked properly.&lt;/p&gt;
&lt;p&gt;On my Zentyal box I had to add a bunch of entries to exclude logging of certain high-noise things. For example, DNS query resolution (via named) and Samba activity:&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;cat /etc/audit/rules.d/01-exclusion.rules
&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;-a never,exit -S 41 -S 42 -S 49 -S 82 -S 288 -F exe=/usr/sbin/named -k exclude_DNS_queries
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-a never,exit -S 43 -F exe=/usr/sbin/winbindd -k exclude_Samba
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-a never,exit -S 41 -S 42 -S 43 -S 87 -F exe=/usr/sbin/smbd -k exclude_Samba
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-a never,exit -S 41 -S 43 -S 87 -F exe=/usr/sbin/samba -k exclude_Samba
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;A word of warning:&lt;/strong&gt; Don&amp;rsquo;t just ignore everything willy-nilly. The audit logging system &lt;em&gt;exists&lt;/em&gt; so you can track activity on the system - blithely sending 100% of the log entries to the bin will undermine what the audit sytem exists for!&lt;/p&gt;
&lt;p&gt;&amp;hellip; That&amp;rsquo;s all I&amp;rsquo;ve got so far. I&amp;rsquo;ll keep updating this if I bump into anything new!&lt;/p&gt;</description></item><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>Getting TrueNAS (FreeNAS 12) to work with an APC NMC2 UPS (AP9631)</title><link>https://www.ericlight.com/post/apc_truenas.html</link><pubDate>Thu, 14 Jan 2021 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/apc_truenas.html</guid><description>&lt;p&gt;TrueNAS, and FreeNAS before it, has supported UPS via the NUT software package since forever. But most people using it seem to be using USB-connected UPS devices. I don&amp;rsquo;t have one of these. I&amp;rsquo;m dealing with an IPv4-based APC ups, specifically the Smart-UPS X 1500 (SMX1500RMI2UNC), with an AP9631 NMC2 card.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;re probably here because you&amp;rsquo;re in the same boat: trying to set up a non-USB or Ethernet-based UPS under FreeNAS/TrueNAS, and you can&amp;rsquo;t. You&amp;rsquo;ve noticed the TrueNAS console &lt;em&gt;will not shut up&lt;/em&gt; about errors which read something like:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;nut plugin: nut_connect: upscli_connect (localhost, 3493) failed: Connection failure: Connection refused&lt;/code&gt;. (Or perhaps port 161)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;But why?&amp;rdquo;&lt;/em&gt;, you say. &lt;em&gt;&amp;ldquo;I&amp;rsquo;ve given TrueNAS my UPS hostname, why is it always trying to talk to localhost? And what is this port 3493, when SNMP is 161?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s happening is that &lt;code&gt;upscli&lt;/code&gt; is trying to talk to the &lt;code&gt;upsd&lt;/code&gt; damon &lt;em&gt;on your TrueNAS server&lt;/em&gt;, which is expected to listen on port 3493 - it&amp;rsquo;s &lt;strong&gt;upsd&lt;/strong&gt; which then does the talky with the SNMP driver, which in turn does the talky with the UPS. This is why the TrueNAS console logs look like it&amp;rsquo;s just shouting at itself.&lt;/p&gt;
&lt;p&gt;Okay, let&amp;rsquo;s get into it:&lt;/p&gt;
&lt;h2 id="ups-configuration"&gt;UPS Configuration
&lt;/h2&gt;&lt;p&gt;First, you need to enable SNMP on your AP9631. This was pretty straightforward, but remember that you need to go:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Configuration -&amp;gt; Network -&amp;gt; SNMPv1 -&amp;gt; Access -&amp;gt; &lt;strong&gt;Enable&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Configuration -&amp;gt; Netowrk -&amp;gt; SNMPv1 -&amp;gt; Access Control, and make sure the &lt;code&gt;public&lt;/code&gt; community is set to be accessible from 0.0.0.0&lt;/li&gt;
&lt;li&gt;Reboot your NMC2 card.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This configuration should work with the defaults that the NUT SNMP driver expects - I suggest you get it working like this for now, then tweak to SNMPv3 once you have a confirmed-working connection.&lt;/p&gt;
&lt;h2 id="truenas-configuration"&gt;TrueNAS Configuration
&lt;/h2&gt;&lt;p&gt;Your UPS configuration menu is under TrueNAS -&amp;gt; Services -&amp;gt; UPS. Configure your TrueNAS UPS section like so:&lt;/p&gt;
&lt;h3 id="general-options-section"&gt;General Options section:
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Identifier:&lt;/strong&gt; Up to you, but do yourself a favour and make it &lt;code&gt;ups&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UPS Mode:&lt;/strong&gt; Master&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Driver:&lt;/strong&gt; &amp;ldquo;Various ups 3 (various) SNMP - RFC 1628 (snmp-ups, experimental)&amp;rdquo; &amp;ndash; once you save, this will simply display as &lt;code&gt;snmp-ups$(various)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Port or Hostname:&lt;/strong&gt; The hostname of the ups, hopefully something simple like &lt;code&gt;ups.mydomain.local&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="monitor-section"&gt;Monitor section:
&lt;/h3&gt;&lt;p&gt;Leave the Monitor User, Monitor Password, Extra users, and Remote Monitor all blank/default for now - you can change them once the UPS is talking to you. Note I don&amp;rsquo;t believe it&amp;rsquo;s important to change the Monitor Password under this configuration, as &lt;code&gt;upsd&lt;/code&gt; only listens on the loopback address.&lt;/p&gt;
&lt;h3 id="shutdown-and-email-sections"&gt;Shutdown and Email sections
&lt;/h3&gt;&lt;p&gt;I shall leave in your capable hands.&lt;/p&gt;
&lt;h3 id="other-options"&gt;Other Options:
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Auxiliary Parameters (ups.conf):&lt;/strong&gt; This is where you override the SNMP defaults, if desired. By default, NUT will use SNMPv1 and the &amp;lsquo;public&amp;rsquo; community. &lt;a class="link" href="https://networkupstools.org/docs/man/snmp-ups.htm" target="_blank" rel="noopener"
 &gt;See here for all config options&lt;/a&gt; availble for the SNMP driver. You could do something like this, if you want:&lt;/li&gt;
&lt;/ul&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;community&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;yaysecurity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;snmp_version&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;privProtocol&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;AES&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Auxiliary Parameters (upsd.conf):&lt;/strong&gt; &lt;code&gt;LISTEN 127.0.0.1 3493&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That last line was the magic - this is the bit that makes upsd &lt;em&gt;not only&lt;/em&gt; listen on port 161 (whyyyy), but &lt;em&gt;also&lt;/em&gt; listen on 3493, which is where the rest of the UPS subsystem expects to find UPS data!&lt;/p&gt;
&lt;h1 id="other-interesting-tidbits"&gt;Other interesting tidbits:
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;Running &lt;code&gt;upsc -l&lt;/code&gt; should list all UPS instances configured on your server. Since I&amp;rsquo;ve got one, called &amp;lsquo;ups&amp;rsquo;, I see:&lt;/li&gt;
&lt;/ul&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;# upsc -l
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ups
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;upsc -l&lt;/code&gt; gives you a Connection Refused error, check &lt;code&gt;/usr/local/etc/nut/upsd.conf&lt;/code&gt; to make sure it&amp;rsquo;s listening on 3493. If not, add your auxiliary parameter in TrueNAS and restart the service.&lt;/li&gt;
&lt;/ul&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;# upsc ups
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Error: Connection failure: Connection refused
&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;# cat /usr/local/etc/nut/upsd.conf
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;LISTEN 127.0.0.1 161
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;LISTEN ::1 161
&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;# sockstat -4 -l | grep upsd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;uucp upsd 99934 6 tcp4 127.0.0.1:161 *:*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Above: upsd is definitely not listening on the expected port&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;NUT Config files&lt;/strong&gt;: These live under &lt;code&gt;/usr/local/etc/nut/&lt;/code&gt;. The folder is deleted and recreated every time you edit something in the TrueNAS GUI, so if you&amp;rsquo;re in that folder and change something in the GUI, you&amp;rsquo;ll need to do the whole &lt;code&gt;cd /usr/local/etc/nut&lt;/code&gt; again. No you can&amp;rsquo;t do &lt;code&gt;cd ../nut&lt;/code&gt;, because the whole inode is gone, so the OS doesn&amp;rsquo;t know where you are anymore.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Testing your UPS&lt;/strong&gt;: Once &lt;code&gt;upsd&lt;/code&gt; is listening on 3493, you should be able to run &lt;code&gt;upsc ups&lt;/code&gt;, and it will query your UPS for data. Note that &amp;ldquo;ups&amp;rdquo; is your UPS identifier from the &amp;ldquo;General Options&amp;rdquo; section, also found as the first line of &lt;code&gt;/usr/local/etc/nut/ups.conf&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;# cat /usr/local/etc/nut/ups.conf
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[ups]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; driver = snmp-ups
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; port = ups.mydomain.local
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; desc = 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pollfreq = 15
&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;# upsc ups
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ambient.humidity: 0.00
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ambient.temperature: 23.0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;battery.charge: 100.00
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;battery.date: 05/15/2017
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;battery.packs: 0.00
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;battery.runtime: 1221.00
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;battery.runtime.low: 600
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;battery.voltage: 54.50
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;device.mfr: APC
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;device.model: Smart-UPS X 1500
&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;I think that pretty much covers it. I hope this has been helpful to someone - at very least, I hope it&amp;rsquo;s helpful to future-me!&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s been a little while since I&amp;rsquo;ve worked with UPS management software. I like to think it&amp;rsquo;s because my day job isn&amp;rsquo;t in infrastructure anymore, but also to be honest the whole UPS scene is fairly ugly. I recall speaking with an electrical engineer from Schneider a while ago, who jokingly said something like &amp;ldquo;creating a new UPS or CNC communications protocol is almost a rite of passage for any new engineer&amp;rdquo;. I can see why&amp;hellip; when you&amp;rsquo;re new, and see something &lt;em&gt;superbly awful&lt;/em&gt;, it&amp;rsquo;s quite compelling to try and fix it! But decades now of dependencies really do add up to be a burden.&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>iRedMail: Daily user unknown entries from backup_sogo.sh</title><link>https://www.ericlight.com/post/sogo-unknown.html</link><pubDate>Sun, 01 Nov 2020 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/sogo-unknown.html</guid><description>&lt;p&gt;If you&amp;rsquo;ve been running iRedMail for a while, eventually you&amp;rsquo;ll probably start seeing &amp;lsquo;user unknown&amp;rsquo; events in your daily logs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::text
* Backup all users' data under /var/vmail/backup/sogo/2020/11/01
&amp;lt;0x0x5574a64c36b0[SOGoCache]&amp;gt; Cache cleanup interval set every 300.000000 seconds
&amp;lt;0x0x5574a64c36b0[SOGoCache]&amp;gt; Using host(s) '127.0.0.1' as server(s)
2020-11-01 09:29:12.784 sogo-tool[29749:29749] user 'abdulm' unknown
2020-11-01 09:29:12.786 sogo-tool[29749:29749] user 'bent' unknown
2020-11-01 09:29:12.786 sogo-tool[29749:29749] user 'brettr' unknown
2020-11-01 09:29:12.786 sogo-tool[29749:29749] user 'catalinar' unknown
2020-11-01 09:29:12.787 sogo-tool[29749:29749] user 'clinth' unknown
2020-11-01 09:29:12.787 sogo-tool[29749:29749] user 'danield' unknown
2020-11-01 09:29:12.787 sogo-tool[29749:29749] user 'dannyn' unknown
2020-11-01 09:29:12.788 sogo-tool[29749:29749] user 'darcyk' unknown
2020-11-01 09:29:12.788 sogo-tool[29749:29749] user 'davidl' unknown
* Compress backup files.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is because removal of an iRedMail user doesn&amp;rsquo;t remove the corresponding SOGo user data. You can take care of this with &lt;code&gt;sogo-tool&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
root@server:/# sogo-tool remove abdulm@&amp;lt;domain.xyz&amp;gt; bent@&amp;lt;domain.xyz&amp;gt; brettr@&amp;lt;domain.xyz&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;hellip; etc. Once you&amp;rsquo;re done, run the backup again to make sure you&amp;rsquo;ve got them all:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::bash
root@server:/# /bin/bash /var/vmail/backup/backup_sogo.sh
* Backup all users data under /var/vmail/backup/sogo/2020/11/01
&amp;lt;0x0x563fd0e2b6b0[SOGoCache]&amp;gt; Cache cleanup interval set every 300.000000 seconds
&amp;lt;0x0x563fd0e2b6b0[SOGoCache]&amp;gt; Using host(s) '127.0.0.1' as server(s)
* Compress backup files.
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>ZFS zpool vanishing after upgrading ProxmoxVE 5.4 to 6.2</title><link>https://www.ericlight.com/post/zfs_vanish.html</link><pubDate>Sat, 23 May 2020 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/zfs_vanish.html</guid><description>&lt;img src="https://www.ericlight.com/post/zfs_vanish/lost_zpool.png" alt="Featured image of post ZFS zpool vanishing after upgrading ProxmoxVE 5.4 to 6.2" /&gt;&lt;p&gt;Performing a major version upgrade is never pleasant. I&amp;rsquo;ve been using ProxmoxVE for about ten years now though, and it&amp;rsquo;s consistently done a fantastic job. Since it&amp;rsquo;s based on Debian, all the upgrades are done with a simple &lt;code&gt;apt update &amp;amp;&amp;amp; apt upgrade&lt;/code&gt;, with a variety of steps in the middle to point to new repositories, etc. Nothing out of the ordinary, nothing scary.&lt;/p&gt;
&lt;p&gt;So I&amp;rsquo;ve got two servers - one is an old one, with only a couple testing VM&amp;rsquo;s residing on it. I go ahead and work through the &lt;a class="link" href="https://pve.proxmox.com/wiki/Upgrade_from_5.x_to_6.0" target="_blank" rel="noopener"
 &gt;5.x to 6.x upgrade guide&lt;/a&gt;, and everything Just Works. No problem with that one.&lt;/p&gt;
&lt;p&gt;When I moved onto the other server I had a couple different things I noticed. For example, when trying to upgrade Corosync 2.x to 3.x (a prerequisite for the OS upgrade), I noticed it was trying to uninstall things like &lt;code&gt;corosync-pve&lt;/code&gt;, which &lt;em&gt;really&lt;/em&gt; didn&amp;rsquo;t seem right.&lt;/p&gt;
&lt;p&gt;After comparing &lt;code&gt;dpkg -l&lt;/code&gt; contents between the two servers, I learned that &lt;code&gt;corosync-pve&lt;/code&gt; is actually just a transitional package - completely replaced by the new &lt;code&gt;corosync&lt;/code&gt; package in version 3. And although the server was trying to uninstall &lt;code&gt;corosync-pve&lt;/code&gt;, it was then immediately installing &lt;code&gt;corosync&lt;/code&gt;&amp;hellip; so no problem.&lt;/p&gt;
&lt;p&gt;Things continued to be mildly alarming during the upgrade itself, but not actually toooo bad, as all the removed packages were being replaced. This one, for example:&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;dpkg: pve-libspice-server1: dependency problems, but removing anyway as you requested:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pve-qemu-kvm depends on pve-libspice-server1 (&amp;gt;= 0.12.5-1); however:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Package pve-libspice-server1 is to be removed.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; spiceterm depends on libspice-server1 (&amp;gt;= 0.12.2); however:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Package libspice-server1 is not installed.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Package pve-libspice-server1 which provides libspice-server1 is to be removed.
&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;(Reading database ... 65255 files and directories currently installed.)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Removing pve-libspice-server1 (0.14.1-2) ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; was replaced with &lt;code&gt;spiceterm&lt;/code&gt;. No worries.&lt;/p&gt;
&lt;p&gt;However things went &lt;em&gt;sharply downhill&lt;/em&gt; following reboot. All of my VM images were missing! I had a ZFS zpool that should have been at &lt;code&gt;/VM_Local_zpool&lt;/code&gt; - that folder &lt;em&gt;existed&lt;/em&gt;, and contained an &lt;code&gt;./images&lt;/code&gt; folder, but that was completely empty.&lt;/p&gt;
&lt;p&gt;I quickly checked the storage information in Proxmox, and the result was&amp;hellip; &lt;strong&gt;not good&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="My storage usage - consistently at about 1.2 terabytes, and then suddenly… zero." class="gallery-image" data-flex-basis="428px" data-flex-grow="178" height="298" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.ericlight.com/post/zfs_vanish/lost_zpool.png" width="532"&gt;&lt;/p&gt;
&lt;p&gt;&amp;hellip; Really, not good. :-|&lt;/p&gt;
&lt;p&gt;So I SSH&amp;rsquo;ed into the server and had a quick look at my list of ZFS stores, and discovered that my dataset was entirely absent:&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;# zfs list
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;NAME USED AVAIL REFER MOUNTPOINT
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool 83.8G 23.8G 96K /rpool
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool/ROOT 3.65G 23.8G 96K /rpool/ROOT
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool/ROOT/pve-1 3.65G 23.8G 3.65G /
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool/data 71.6G 23.8G 71.6G /rpool/data
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool/swap 8.50G 25.4G 6.85G -
&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;# zpool list
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool 111G 82.1G 28.9G - - 66% 73% 1.00x ONLINE -
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A bit of Googling led me to the &lt;code&gt;zfs import&lt;/code&gt; command, which resulted in the first piece of good news of the night:&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;# zpool import
&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; pool: VM_Local_zpool
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; id: 6614373363984244305
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; state: ONLINE
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; status: Some supported features are not enabled on the pool.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; action: The pool can be imported using its name or numeric identifier, though
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	some features will not be available without an explicit &amp;#39;zpool upgrade&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; config:
&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;	VM_Local_zpool ONLINE
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 mirror-0 ONLINE
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 wwn-0x50014ee0aeee96ef ONLINE
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 wwn-0x50014ee05998ee25 ONLINE
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It exists! And it&amp;rsquo;s &amp;hellip; online? But where? I don&amp;rsquo;t get it. I went ahead and tried importing it, but got a &amp;ldquo;directory not empty&amp;rdquo; error:&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;# zpool import VM_Local_zpool 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cannot mount &amp;#39;/VM_Local_zpool&amp;#39;: directory is not empty
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, &lt;em&gt;&lt;strong&gt;if&lt;/strong&gt; I&amp;rsquo;d been paying attention&lt;/em&gt; there, I would have realised that &lt;code&gt;zpool list&lt;/code&gt; now contained my VM_Local_zpool:&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;# zfs list
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;NAME USED AVAIL REFER MOUNTPOINT
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;VM_Local_zpool 1.16T 611G 1.16T /VM_Local_zpool
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool 83.8G 23.8G 96K /rpool
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool/ROOT 3.65G 23.8G 96K /rpool/ROOT
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool/ROOT/pve-1 3.65G 23.8G 3.65G /
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool/data 71.6G 23.8G 71.6G /rpool/data
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpool/swap 8.50G 25.4G 6.85G -
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From this point, all I had to do was empty /VM_Local_zpool, and try to remount the zpool. But there&amp;rsquo;s a second trick here.&lt;/p&gt;
&lt;p&gt;ProxmoxVE has a pretty clear idea of How Storage Should Look, so every time it scans a storage device, is makes sure there&amp;rsquo;s an &lt;code&gt;./images&lt;/code&gt; folder in any storage enabled for VM Images. It also makes sure there&amp;rsquo;s a &lt;code&gt;./dump&lt;/code&gt; folder on any storage enabled as a backup target, and a &lt;code&gt;./template&lt;/code&gt; folder on any storage enabled for ISO images. (Reference: &lt;a class="link" href="https://pve.proxmox.com/wiki/Storage:_Directory" target="_blank" rel="noopener"
 &gt;https://pve.proxmox.com/wiki/Storage:_Directory&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;So, when I removed that /VM_Local_zpool/images folder, Proxmox just&amp;hellip; went ahead and recreated it almost immediately, so I still couldn&amp;rsquo;t mount the zpool there.&lt;/p&gt;
&lt;p&gt;In the end, I managed to get my zpool remounted by pairing the &lt;code&gt;rmdir&lt;/code&gt; and &lt;code&gt;mount&lt;/code&gt; commands together on the same 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;# rmdir /VM_Local_zpool/images/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# zfs mount VM_Local_zpool
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cannot mount &amp;#39;/VM_Local_zpool&amp;#39;: directory is not empty
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# rmdir /VM_Local_zpool/images/ &amp;amp;&amp;amp; zfs mount VM_Local_zpool
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;# cd VM_Local_zpool/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/VM_Local_zpool# ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;backup	images
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; and there we go! My mount point, and all my VM images, are back unscathed!&lt;/p&gt;
&lt;p&gt;And just for future reference - I saw a post on the FreeNAS forums that I should the status of the zfs-import-cache service, and enable it if it wasn&amp;rsquo;t started by default&amp;hellip; however it was fine:&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;# systemctl status zfs-import-cache.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;● zfs-import-cache.service - Import ZFS pools by cache file
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Loaded: loaded (/lib/systemd/system/zfs-import-cache.service; enabled; vendor preset: enabled)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Active: active (exited) since Sat 2020-05-23 20:46:54 NZST; 3min 26s ago
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Docs: man:zpool(8)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Process: 1819 ExecStart=/sbin/zpool import -c /etc/zfs/zpool.cache -aN (code=exited, status=0/SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Main PID: 1819 (code=exited, status=0/SUCCESS)
&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;May 23 20:46:54 ~ systemd[1]: Starting Import ZFS pools by cache file...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;May 23 20:46:54 ~ zpool[1819]: no pools available to import
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;May 23 20:46:54 ~ systemd[1]: Started Import ZFS pools by cache file.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&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>sa-compile failing during upgrade</title><link>https://www.ericlight.com/post/sa-compile.html</link><pubDate>Sun, 15 Mar 2020 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/sa-compile.html</guid><description>&lt;p&gt;I just spent an hour troubleshooting the most ridiculous thing. I guess to help people search, I&amp;rsquo;d describe this as &amp;ldquo;dpkg failing at sa-compile in Debian 10&amp;rdquo; but that&amp;rsquo;s really not a good picture of what&amp;rsquo;s happening here&amp;hellip;&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;Setting up sa-compile &lt;span style="color:#f92672"&gt;(&lt;/span&gt;3.4.2-1~deb9u3&lt;span style="color:#f92672"&gt;)&lt;/span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Running sa-compile &lt;span style="color:#f92672"&gt;(&lt;/span&gt;may take a long time&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/bin/sh: 1: x86_64-linux-gnu-gcc: Permission denied
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;make: *** &lt;span style="color:#f92672"&gt;[&lt;/span&gt;body_0.o&lt;span style="color:#f92672"&gt;]&lt;/span&gt; Error &lt;span style="color:#ae81ff"&gt;126&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;command &lt;span style="color:#e6db74"&gt;&amp;#39;make PREFIX=/tmp/.spamassassin22062Ifq5yDtmp/ignored INSTALLSITEARCH=/var/lib/spamassassin/compiled/5.024/3.004002 &amp;gt;&amp;gt;/tmp/.spamassassin22062Ifq5yDtmp/log&amp;#39;&lt;/span&gt; failed: exit &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dpkg: error processing package sa-compile &lt;span style="color:#f92672"&gt;(&lt;/span&gt;--configure&lt;span style="color:#f92672"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;subprocess installed post-installation script returned error exit status &lt;span style="color:#ae81ff"&gt;25&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;&amp;lt;-- snip --&amp;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;Errors were encountered &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; processing:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sa-compile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;E: Sub-process /usr/bin/dpkg returned an error code &lt;span style="color:#f92672"&gt;(&lt;/span&gt;1&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;In my defence, it seemed similar to a recurring issue I&amp;rsquo;ve had on this server in the past, (which I now promise to address in a separate post). That&amp;rsquo;s why I ended up on a red herring hunt.&lt;/p&gt;
&lt;p&gt;Anyway, I spent a bunch of time trying to troubleshoot dpkg and Python, before realising that a few months ago I&amp;rsquo;d installed &lt;a class="link" href="https://cisofy.com/lynis" target="_blank" rel="noopener"
 &gt;Lynis&lt;/a&gt; and worked through a bunch of the hardening recommendations.&lt;/p&gt;
&lt;p&gt;&amp;hellip; One of which is restricting the execute permissions on /usr/bin/gcc. Which is a symlink to /usr/bin/gcc-6. Which is a symlink to x86_64-linux-gnu-gcc-6.&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;root@x:/usr/bin# ls -l x86_64-linux-gnu-gcc-6
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-rw-r--r-- &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; root root &lt;span style="color:#ae81ff"&gt;949016&lt;/span&gt; Feb &lt;span style="color:#ae81ff"&gt;15&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2018&lt;/span&gt; x86_64-linux-gnu-gcc-6
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Yes. I was experiencing problems compiling things because I&amp;rsquo;d removed execute permissions for all users on the compiler I needed, and I&amp;rsquo;d spent an hour ignoring the &amp;ldquo;Permission denied&amp;rdquo; error that told me where to look.&lt;/p&gt;
&lt;p&gt;Fixed with a simple &lt;code&gt;chmod 744 /usr/bin/x86_64-linux-gnu-gcc-6&lt;/code&gt;.&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>Installing PowerChute Network Shutdown on ProxmoxVE</title><link>https://www.ericlight.com/post/pcns_proxmox.html</link><pubDate>Tue, 27 Feb 2018 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/pcns_proxmox.html</guid><description>&lt;p&gt;This is going to be one of those posts where I just dump stuff. Power failures are shite, and if your server isn&amp;rsquo;t talking with your UPS, it won&amp;rsquo;t shut down gracefully. This is the story of my trying to get APC&amp;rsquo;s PowerChute Network Shutdown working on a ProxmoxVE 5.1 environment.&lt;/p&gt;
&lt;p&gt;Note I opted out of using either nut or apcupsd, because I had a nice fancy Network Management Card (NMC2 / Schneider AP9631) available. Also, I wanted to shut down more than a single server, so a USB or Serial cable wouldn&amp;rsquo;t do the trick.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install Java Runtime Environment: &lt;code&gt;apt install openjdk-8-jre&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Download PCNS onto your Proxmox server - &lt;a class="link" href="http://www.apc.com/shop/us/en/categories/power/uninterruptible-power-supply-ups-/ups-management/powerchute-network-shutdown/N-auzzn7" target="_blank" rel="noopener"
 &gt;http://www.apc.com/shop/us/en/categories/power/uninterruptible-power-supply-ups-/ups-management/powerchute-network-shutdown/N-auzzn7&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Extract the download: &lt;code&gt;tar -xvf pcns420Linux-x86-64.tar.gz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;cd ./Linux_x64&lt;/li&gt;
&lt;li&gt;sudo su&lt;/li&gt;
&lt;li&gt;./install.sh&lt;/li&gt;
&lt;li&gt;When prompted for your Java location, use &lt;code&gt;/usr/lib/jvm/java-8-openjdk-amd64/jre/bin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I didn&amp;rsquo;t enable SMTP&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Results in:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; root@ ~/Linux_x64# ./install.sh 
 ------------------------------------------------------------------
 PowerChute Network Shutdown 4.2.0 for Linux
 Copyright (c) 1999-2016 Schneider Electric.
 All Rights Reserved.
 ------------------------------------------------------------------

 OS=Linux

 Initializing ...

 Press any key to display End User License Agreement
 &amp;lt;--snip--&amp;gt;
 Do you agree to the above license terms? [yes or no]
 yes

 Please enter the installation directory or press enter to install to the default directory (/opt/APC/PowerChute):


 Are you sure you want to install PCNS to /opt/APC/PowerChute [Yes|No]? 
 yes
 PCNS will be installed to /opt/APC/PowerChute

 Please enter java directory if you want to use your system java (example:/usr/local/bin/jre/jre1.8.0_91) or press enter to install the bundled Java:
 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin 

 Checking version of Java ...
 Detected Java Version: 1.8.0.151
 Acceptable version

 openjdk version &amp;quot;1.8.0_151&amp;quot;
 OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-1~deb9u1-b12)
 OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)

 JAVA_DIR=/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/

 Copying the installation files ...
 Extracting PCNS files ...
 PCNS is extracted to /opt/APC/PowerChute
 Configuring startup files ...
 Startup script=/etc/rc.d/init.d/PowerChute
 Updating Linux symbolic link ...
 Configure Firewall
 Configuring uninstall script ...
 Setup the m11.cfg file

 Enable SNMP Support [Yes|No]? 
 no
 SNMP Not Enabled

 PowerChute Network Shutdown, v4.2.0
 Copyright (c) 1999-2016, Schneider Electric. All Rights Reserved.
 Startup completed.


 Installation has completed.
 PowerChute Network Shutdown can be accessed through your browser at https://&amp;lt;your_server_ip_address&amp;gt;:6547
 Please complete the configuration wizard so that PowerChute Network Shutdown can protect your server.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once you&amp;rsquo;re finished with that, navigate to the new web portal on your server (second-to-last line in the output above), and complete the setup of your PCNS instance!&lt;/p&gt;
&lt;p&gt;When you&amp;rsquo;re configuring PCNS itself, you&amp;rsquo;ll be prompted for the User Name, Password, and Authentication Phrase for the UPS. These are the user details you use to log into your NMC.&lt;/p&gt;
&lt;p&gt;By default, the Authentication Phrase is &lt;code&gt;admin user phrase&lt;/code&gt;, but you should &lt;em&gt;totally&lt;/em&gt; change this. Assuming you&amp;rsquo;ve updated the firmware on your NMC, you can set the Authentication Phrase at &lt;code&gt;Configuration -&amp;gt; Shutdown&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Setting up your outlet groups and shutdown times are left as an exercise to the reader. :)&lt;/p&gt;</description></item><item><title>Fix Dell Keyboard Backlight under Debian</title><link>https://www.ericlight.com/post/keyboard_backlight.html</link><pubDate>Thu, 11 Jan 2018 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/keyboard_backlight.html</guid><description>&lt;p&gt;My personal laptop is an old Dell Latitude E6410. One of the things I actually love about it, is the fact that the keyboard has a backlight.&lt;/p&gt;
&lt;p&gt;However, because Linux, sometimes that backlight just stops working. When this happens, you&amp;rsquo;ll see error messages in dmesg, such as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dell_wmi: Unknown key with type 0x0011 and code 0x01e2 pressed
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If this happens to you, just run this command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo echo 7 &amp;gt; /sys/devices/platform/dell-laptop/leds/dell\:\:kbd_backlight/brightness
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can echo a higher number if you want your keyboard brighter, but I found 7 to be more than bright enough.&lt;/p&gt;</description></item><item><title>When the problem is DNS: FreeNAS and NFS</title><link>https://www.ericlight.com/post/nfs-dns.html</link><pubDate>Sun, 07 Jan 2018 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/nfs-dns.html</guid><description>&lt;p&gt;I discovered a while ago that NFS requires DNS to function correctly: &lt;a class="link" href="https://redmine.ixsystems.com/issues/4983" target="_blank" rel="noopener"
 &gt;https://redmine.ixsystems.com/issues/4983&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s somewhat annoying, because when your DNS server goes down (and your backups are stored on your FreeNAS server and accessed over NFS), is precisely the time when you really want your backups to be accessible.&lt;/p&gt;
&lt;p&gt;However, turns out it doesn&amp;rsquo;t &lt;em&gt;aaaaactuallyyyyy&lt;/em&gt; need DNS&amp;hellip; it needs &lt;strong&gt;name resolution&lt;/strong&gt;. Specifically, FreeNAS just needs to be able to resolve it&amp;rsquo;s own hostname. Cue the handy-dandy hosts file.&lt;/p&gt;
&lt;p&gt;Under Network -&amp;gt; Global Configuration -&amp;gt; Host name data base, add your details:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.88.5 backupserver backupserver.local backupserver.ad.mydomain.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you have a secondary IP address, duplicate the above line and replace the IP as appropriate.&lt;/p&gt;
&lt;p&gt;Obviously, replace the hostname and your internal domain name with whatever you use. However, be aware that the .local FQDN is &lt;strong&gt;actually&lt;/strong&gt; required, even if you use a different domain name.&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>Compiling Heimdall without installing Qt</title><link>https://www.ericlight.com/post/heimdall-nongui.html</link><pubDate>Wed, 13 Sep 2017 00:00:00 +1200</pubDate><guid>https://www.ericlight.com/post/heimdall-nongui.html</guid><description>&lt;img src="https://www.ericlight.com/post/heimdall-nongui/yuck.png" alt="Featured image of post Compiling Heimdall without installing Qt" /&gt;&lt;p&gt;During my recent &lt;a class="link" href="https://www.ericlight.com/post/broken_phone.html" &gt;Wrecked-phone Saga&lt;/a&gt;, I had some trouble flashing my firmware. My phone was broken at the time, so I couldn&amp;rsquo;t enable ADB Debugging - therefore adb wasn&amp;rsquo;t an option. OEM Bootlock was on, so fastboot wasn&amp;rsquo;t an option. My Recovery bootloader was also broken. I thought my phone was bricked.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s until I remembered Heimdall.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://glassechidna.com.au/heimdall/" target="_blank" rel="noopener"
 &gt;Heimdall&lt;/a&gt; is specifically a tool for working with the partitions on Samsung phones - other visitors need not apply. It works a treat for my Samsung Galaxy S5 (kltedv) though.&lt;/p&gt;
&lt;p&gt;Heimdall, however, is &lt;strong&gt;old&lt;/strong&gt;. The version in the Debian Sid repository is 1.4.1, which &lt;a class="link" href="http://metadata.ftp-master.debian.org/changelogs/main/h/heimdall-flash/heimdall-flash_1.4.1-2_changelog" target="_blank" rel="noopener"
 &gt;dates back to 2015&lt;/a&gt;. And when we have old versions, we also have incompatibilites! Such as Heimdall 1.4.1&amp;rsquo;s &lt;a class="link" href="https://github.com/Benjamin-Dobell/Heimdall/issues/209" target="_blank" rel="noopener"
 &gt;incompatibility with newer versions of Samsung devices&lt;/a&gt; &amp;hellip; such as my precious SGS5.&lt;/p&gt;
&lt;p&gt;Happily, Heimdall is open source, so I was able to download and compile a new version that overcomes the problem. And that&amp;rsquo;s how I found myself staring at the screen and looking at this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Do I really need to install 55 packages to build this?" class="gallery-image" data-flex-basis="568px" data-flex-grow="236" height="595" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.ericlight.com/post/heimdall-nongui/yuck.png" srcset="https://www.ericlight.com/post/heimdall-nongui/yuck_hu_5d669859ae154774.png 800w, https://www.ericlight.com/post/heimdall-nongui/yuck.png 1409w" width="1409"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That is Yuck.bat&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I really didn&amp;rsquo;t want to install 55 packages just to build this. The majority of missing packages were required to build the GUI section of the tool, which I didn&amp;rsquo;t want to use anyway. What if I could &amp;hellip; &lt;em&gt;build Heimdall without building the GUI??&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And of course, that&amp;rsquo;s the title of this article, so here&amp;rsquo;s how to do it!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDIT 2017-12-19: The stuff below is no longer necessary. For better instructions, have a look at my article about &lt;a class="link" href="https://www.ericlight.com/post/new_heimdall.html" &gt;flashing a Samsung G900I back to stock&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Clone the git repository, with &lt;code&gt;git clone https://github.com/Benjamin-Dobell/Heimdall.git&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the CMakeLists.txt file: &lt;code&gt;nano Heimdall/CMakeLists.txt&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Delete the last four lines of CMakeLists.txt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; cmake_minimum_required(VERSION 2.8.4)

 set(CMAKE_MODULE_PATH
 ${CMAKE_SOURCE_DIR}/cmake
 ${CMAKE_MODULE_PATH})

 project(Heimdall)

 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

 option(DISABLE_FRONTEND &amp;quot;Disable GUI frontend&amp;quot; OFF)

 add_subdirectory(libpit)
 add_subdirectory(heimdall)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You&amp;rsquo;re done! Go ahead and build according to the instructions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&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>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>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>Broken log times in APC's PCNS Appliance 4.1</title><link>https://www.ericlight.com/post/apc_pcns.html</link><pubDate>Thu, 27 Oct 2016 00:00:00 +1300</pubDate><guid>https://www.ericlight.com/post/apc_pcns.html</guid><description>&lt;p&gt;Schneider Electric&amp;rsquo;s &lt;a class="link" href="http://www.se.com/en/product-range/61933-powerchute-network-shutdown/" target="_blank" rel="noopener"
 &gt;PowerChute Network Shutdown&lt;/a&gt; is a piece of software which communicates with your local UPS, and initiates system shutdown if the UPS battery is unable to continue providing power. This helps to preserve file integrity in the event of a prolonged power failure.&lt;/p&gt;
&lt;p&gt;Previously, you had to install the PCNS client separately on each virtual machine. Since then though, APC have released a &lt;a class="link" href="https://solutionexchange.vmware.com/store/products/apc-powerchute-network-shutdown-v4-1-for-vmware" target="_blank" rel="noopener"
 &gt;PCNS VMware Appliance&lt;/a&gt; which is installed directly into vCenter, and initiates shutdown on all the VMware guests through a single Virtual Machine. This is a much tidier model, so we&amp;rsquo;ve recently embarked on migrating to the PCNS Appliance.&lt;/p&gt;
&lt;p&gt;After installing the PCNS 4.1 appliance and getting everything working, I discovered that the time on all the log files was wrong by a significant margin. I can&amp;rsquo;t remember exactly what the margin was, it could have been say 8 hours or something.&lt;/p&gt;
&lt;p&gt;I did a bit of research and eventually I discovered a spectaularly old question on the APC forums, dating all the way back to 2011:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;I have installed PCNS 2.2.4 into the vMA of an ESXi 4.1 server. It properly communicates with the associated NMC and performs correctly. However, it reports all the activities in Eastern Standard Time. I don&amp;rsquo;t know where it&amp;rsquo;s picking up that time zone and can&amp;rsquo;t find anywhere to change it. In the vSphere client the time shows up correctly. Checking date inside the vMA from the CLI also shows the correct time and timezone. The date and time setting in the NMC is correct and is set to synch with NTP with correct time zone.&amp;rdquo;&lt;/em&gt;&lt;br&gt;
From: &lt;a class="link" href="http://forums.apc.com/spaces/7/ups-management-devices-powerchute-software/forums/general/6809/pcns-2-2-4-esxi-annoyance" target="_blank" rel="noopener"
 &gt;http://forums.apc.com/spaces/7/ups-management-devices-powerchute-software/forums/general/6809/pcns-2-2-4-esxi-annoyance&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The answers include a broken link to an APC web page about it, but fortunately the poster copied the original post detail, which showed me where to look:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;PCNS uses a standard java function to retrieve the current date from the system when writing events to the log. The Problem on the VIMA is that this function always returns the US date format (PDT).&lt;br&gt;
This is an issue with Java &lt;a class="link" href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6456628" target="_blank" rel="noopener"
 &gt;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6456628&lt;/a&gt;&lt;br&gt;
You can correct the time issue on VIMA by modifying /etc/sysconfig/clock file.&lt;br&gt;
+/etc/sysconfig/clock contains a line ZONE=&amp;ldquo;America/Los_Angeles&amp;rdquo;+&lt;br&gt;
You need to edit the ZONE= to match your region such as ZONE=&amp;ldquo;America/New_York&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Sounds great! But when I looked in /etc/sysconfig/clock, I discovered my time zone was already set to &amp;ldquo;Pacific/Auckland&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;However, it also contained the value &amp;ldquo;UTC = False&amp;rdquo;. I changed this to &amp;ldquo;UTC = True&amp;rdquo;, and et voilà! The problem is fixed!&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>