Author Archives: josh

Replacement Hot Water Service

All my electricity is green: my retailer buys RECS sufficient to back my electricity purchases. As such, I don’t care how much electricity I use, except such that it costs me money.

Breakeven analysis is fun.

My house has a twelve year old 160 litre resistive electric hot water service (HWS). General opinion seems to be that a HWS will last perhaps as long as 12 years before failing (my last house had one that was 30 years old and still going strong). It’s currently inside the house (taking up valuable floorspace), and may not survive being moved outside in the coming renovation. I want an instantaneous gas HWS (unlimited hot water at exactly the temperature I dictate), but refuse to use gas.

Instantaneous electric HWS exist and are only about $1000, but require three-phase power (an upgrade costing a surprisingly small $1000, plus electrical work on my side of the divide).  How much power will it consume?  Turns out, the same as resistive heating the water, but it’s all peak electricity.  That pushes its daily cost quite high.  There are other HWS options; reusing the existing tank (free-ish), replacing it with a larger tank (still resistive, $1000), sucking up all the spare electricity from the PV solar system (perhaps $1000), or a heat pump ($3400), and combinations of the above.

I was able to figure out how much electricity we’re using to power our HWS by virtue of it being on a separate meter to the rest of the house – 4.6kWh/day, costing about $0.85/day because it runs off peak. Hot water consumption is expected to increase after the renovations.  It turns out that how much hot water is consumed, and when, is very important for accurately pricing electricity consumption. I’ve a fairly complex spreadsheet modeling current and projected consumption patterns, and the resultant energy requirement timing and costs. We have a PV solar system, which is how I thought I could push our cost of hot water down – heat it from the panels during the day, when electricity is cheap for me ($0.119/kWh).  If your tank is too small (which ours will be/nearly is already) then you’ve got to heat using electricity other than cheap solar electricity.

I calculated the Total Cost of Ownership at the 5 year mark, and the average daily cost of hot water for the various options (note, this is for my projected hot water consumption profile – yours will differ, altering the values):

Option TCO Daily Cost
Keep existing HWS, peak electricity $4,340 $2.27
Keep existing HWS, off peak only, coupled to instantaneous electric HWS $7,411 $2.69
Buy 315L resistive HWS, off peak only $5,497 $2.46
Keep existing resistive HWS, run off PV solar and off-peak $3,764 $1.51
Buy 315L resistive HWS, run off PV solar $4.968 $1.63
Buy 315L heat-pump HWS, run off PV solar $3,888 $0.27

The heat pump can run off solar using its built-in clock, saving $1000 in diverter costs. You can see that its TCO is a little more than a salvage job on the existing HWS run from solar power, but the daily cost means the heat pump is going to pull away at a mad rate. Hot water that cheap is making me think of grand ways to heat my house.

Ditching gas

All my electricity is green: my retailer buys RECS sufficient to back my electricity purchases. When I calculated my household’s Green House Gas emissions equivalence, we pulled in emissions below 15% of that of the average Australian household. In fact, our emissions were down to two sources: our car (7000 km/year @ 9l/100km – emitting a quarter of that of the average Australian household) and our natural gas consumption (20300MJ/year – home heating emissions 57% of that of the average Australian household).  Apparently emissions can vary from 3 to 30 tonnes/year – I’ve calculated my household at around 2.5 tonnes per year at the moment. I think we can do better. How about 1.5 tonnes per year?

I’ve had a poke around the non-hydrocarbon motorised transport market. There isn’t much there for me, cars are north of $50,000, lifespans are limited. If I could buy an electric car for $20,000 that was going to last 20 years, I’d be up for it. Because I can’t, hydrocarbons will continue to be used for this form of transport. Will revisit when car fails, I’m guessing in less than a decade. Besides, I’m pretty convinced “car ownership” will end up being something people did in the 20th century, not the 21st.

We don’t cook with gas; we have an induction cooktop. I hate electric cooking – resistive electric cooking. It’s inefficient, slow, too cold, too hot, ugly and messy and too expensive. I’ve always cooked on gas. Induction cooking has turned me around; it’s everything gas cooking is, without the explosions, burnt-on gunk, poisoning and GHG emissions.  However, it is fussy (it only works with ferrous cookware) but that’s inconvenient, not a showstopper (example: coffee pecolators are almost all aluminium, and those that aren’t have a very small base. The pecolator has to go in a small pot to be used).

Our gas consumption is purely for space heating via a ducted heating system. It costs less than $770/year to heat our house, so an electric replacement will need to be competitive with that. Having run the numbers, I’ve calculated our gas consumption produced 4000kWh of heat in the house each year. Doing that with air conditioners would (assuming 400% efficiency, which is pretty middle-of-the-road) require 1000kWh of electricity. I seem to pay about 30 cents/kWh (if you can figure out what your electricity actually costs you, I’d love to hear what you did to get that number), so that’s $300/year to run air conditioners instead of ducted heating. Payback is less than 10 years if $4000 is spent on adding aircon units.

From an environmental and financial perspective it’s time to ditch gas, so I’m off. Each gas bill raises the daily connection fee.  It’s about $1/day now, so if you don’t use much gas there’s an increasing incentive to use no gas at all. Nearly half my bill is for the privilege of having a gas supply.

But wait! I love wok cooking, and there’s almost no way to wok-fry stuff without gas. What to do? For a couple of years we’ve used a butane camp stove as a stop-gap until we got around to plumbing in our dedicated wok burner, but if we’re cutting off gas we’ll continue living like animals for the rest of our squalid lives! No fear, says my plumber: convert to LPG – like used for BBQ cooking. And so, we now happily wok-fry on gas, which I figure will cost us $30 – $60 a year to refill the bottle. $38 for the LPG conversion kit for the burner, which would have been avoided if I’d thought this all through a couple of years ago when buying the wok burner.

The next problem is: what to do about hot water?

Securely run a low memory/low CPU Minecraft server

If you’ve got next to no memory and CPU available to run a Minecraft server, don’t fret. Cuberite is what you’re after. At them moment, Cuberite isn’t bug-free, nor indiscernible from a genuine Minecraft server, but it’s quite usable – and instead of needing 4GB+ of RAM, it needs less than 300MB. And it needs next to no processing power: some people run Cuberite on their Raspberry Pi and have plenty of CPU available.

I would at this point go on about how this is a significant point of difference between C++ and Java, but Java optimizes for something different to C++.  I got into an interesting discussion with Cathy about this after reading a question someone had about what Java was trying to be good at. I used to think that VB was the new COBOL, but clearly Java is the new COBOL; those Java programs are going nowhere, they’re verbose and easy to understand and maintain.

A point to note: The Minecraft protocols are bandwidth heavy, I found if I wanted to run a server at home I’d be able to have one, perhaps two players. Thus is Internet in Australia. Instead I’ve dropped this onto a free AWS VPS instance and bandwidth is no problem.

Still, it’s a random piece of software off the Internet, so we’re going to give it its own user account for our own safety. Let’s install the software:

curl -sSfL | sh
sudo mv Server /usr/local/cuberite
cd /usr/local/cuberite

Cuberite allows configuration through a web interface.  We now enable webadmin.ini
; Please restart Cuberite to apply changes made in this file!

Port 8080 is the alternative html port (http/https).  You could cd into webadmin and run and get https serving, but your browser will barf on the certificate. Instead, let’s use a LetsEncrypt certificate, one that we installed earlier. First we make our one-line shell script for running the daemon:

sudo useradd -c "Cuberite server" -f -1 -M -r cuberite
chown -R cuberite:`whoami` /usr/local/cuberite/
sudo nano /etc/init.d/

# Provides: cuberite
# Required-Start: $local_fs $network
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: cuberite
# Description: Cuberite server, a Minecraft server lookalike
cd /usr/local/cuberite
sudo -u cuberite /usr/local/cuberite/Cuberite -d &

Next we set it going when the box starts up:

sudo chmod +x /etc/init.d/
sudo update-rc.d defaults

Before we can go to the website we need to allow user cuberite to get to the certificates:

sudo groupadd privkey_users
sudo usermod -aG privkey_users cuberite
sudo sudo chmod g+rx /etc/letsencrypt/live/
sudo sudo chmod g+rx /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/live/
sudo chown root:privkey_users /etc/letsencrypt/live/
sudo -u cuberite ln -s /etc/letsencrypt/live/ /usr/local/cuberite/webadmin/httpscert.crt
sudo -u cuberite ln -s /etc/letsencrypt/live/ /usr/local/cuberite/webadmin/httpskey.pem

Changing these permissions doesn’t affect apache2’s ability to get them.
The reason we’ve used a group here is to allow both Cuberite and any other app (for example, exim) to access the private keys; just add any other user that needs to use the private keys to the privkey_users group.

Remember to punch a firewall hole for port 8080. Fire up Cuberite now:

sudo service cuberite restart

And check if that worked, there should be about one entry:

ps -aux | grep cuberitps -aux | grep cuberit

If not, you can check in the logs directory to see what’s wrong.

So now:

sudo lsof -i :8080

should be secure.  Note the https is mandatory, as your browser will use http if you fail to specify a protocol.

Where do you wake up from a bed in Minecraft?

After issuing many /time set night commands, I can tell you the waking-location algorithm for Minecraft. This presumably also affects your spawn point.

Two locations are checked, and if they fail to select an acceptable location the pillow-location is used regardless of consequences of picking this location. An acceptable location is on the same level as the bed, and has two transparent-non-solid blocks above it (i.e. you will be standing next to the bed without your head or body embedded in something that’s killing you).

The process is the same for each of the two locations:

Sweep x-1 to x+1:
  Sweep z-1 to z+1:
    if the location is acceptable, we're done

The locations are checked in the order: pillow-part-of-bed, non-pillow-part-of-bed. The effect is:
From the Minecraft wiki:

For a bed to be usable as a spawn point, the player must be able to stand next to the bed at the same level as it. There must be a solid block at the same ‘floor’ level as the bed, with 2 transparent blocks of space (for example, air) for the player to stand in, in one of the ten blocks that surround the bed. It doesn’t matter if the bed itself has blocks above it.

Netgear Stora upgrade v3: 2-disk-JBOD to 1-disk-JBOD

So, we’re butting heads up against the storage capacity of our Netgear Stora again (93% full). The NAS currently has 2 x 2TB drives and no more free bays to drop drives into, so whatever the next arrangement is it has to involve getting rid of at least one of the current drives. The Stora is currently backed up to an external drive enclosure with a 4TB drive mounted in it. Other things are also backed up on that external drive, so it’s more pressed for space than the Stora.

So here’s the plan:

  • collect underpants
    This was a flippant comment, but it’s upgrade season and we recently acquired a computer second hand, which had an i5-3470S CPU, the most powerful thing in the house by a significant margin. I wanted the dual Display Port outputs, but unfortunately it could only be upgraded to 8GB of RAM, so instead the CPU got swapped into our primary desktop (and a graphics card acquired to run dual digital displays). Dropping in a replacement CPU required replacing the thermal grease, and that meant a rag to wipe off the old grease, thus the underpants.
  • backup the Stora to the 4TB drive
  • acquire a cheap 8TB disk because this is for backing up, not primary storage
  • clone the 4TB drive onto it using Clonezilla
  • expand the cloned 4TB partition to the full 8TB of drive space
    Well, that didn’t work.  Clonezilla didn’t seem to copy the data reliably, but admittedly I was running a stupidly old version.  Several hours of mucking around with SATA connectors and Ubuntu NTFS drivers later, I gave up and copied the disk using Windows.  It took several days, even using USB3 HDD enclosures, which is why I spent so much time mucking around trying to avoid it.
  • backup the Stora to the 8TB drive
  • remove the 2 x 2TB drives from the Stora
  • insert the 4TB drive into the Stora
  • allow the Stora to format the 4TB drive
  • pull the 4TB drive
  • mount the 4TB and 2 x 2TB drives in a not-otherwise-busy machine
  • copy the data from the 2 x 2TB drives onto the 4TB drive
  • reinsert the 4TB drive into the Stora
  • profit!

And, by profit, I mean cascade the 2TB drives into desktop machines that have 90% full 1TB drives… further rounds of disk duplication ensue. 1TB drives then cascade to other desktop machines, further rounds of disk duplication ensue.

At the end of this process, the entire fleet will have been upgraded. But the original problem of butting heads against the Stora will not have been addressed; this will hopefully a simple matter of dropping another drive in.

The last time we did this, we paid $49.50/TB for storage.  This time around, it was $44.35; a 10% drop in storage prices isn’t anything to write home about in a four-and-a-half year window.

Trustworthy email: authentication using exim4, SPF, DKIM and DMARC

The email authentication technologies we’re about to implement are, according to the authentication authorities, all you need to be regarded as being from your domain when you send email, and someone else not being from your domain.  Effect: your emails can be considered trustworthy by email receivers who use these technologies. If they don’t use these technologies, they can’t tell.

At the very least, Google will be less likely to think your email is spam.

PTR record

A PTR record can be obtained from your host’s nameserver – it’s a reverse DNS record for your IP address. If the PTR record points at rather than (your domain), and you’re claiming to be sending mail from, what’s the email recipient meant to think?


will tell you what the host for that IP is. Lodge a ticket with your hosting provider and get that PTR record changed to This might take about a day.

SPF record

Create a Sender Policy Framework record on your nameserver:

TXT @ "v=spf1 a mx -all"

This says “for my domain, I will only send email from IP addresses listed on the nameserver”.  Nameserver changes take time to propagate.

After your nameserver changes have propagated, you can go to to check out if you got it right.


DomainKeys Identified Mail is where things get more involved.  We’re doing this on a Debian Linux, like Ubuntu for exim4. We’re making our signing key 2048 bits, which is long enough to make life slightly unpleasant for us. Fortunately for you I’ve written a bash script that outputs the TXT record we need to create on the nameserver – because some nameservers (I’m looking at you, Gandi) can’t hold “long” strings – it’s broken into “small” strings:

sudo apt install openssl
cd /etc/exim4
sudo openssl genrsa -out dkim.private 2048
sudo openssl rsa -in dkim.private -out dkim.public -pubout -outform PEM
echo $(echo $(date -u +%Y%m%d && echo '') | sed -e 's/[ ]//g' && echo $(echo ' TXT "v=DKIM1; p="' && echo $(grep 'PUBLIC KEY' -v dkim.public) | sed -e 's/[ ]//g' | fold -w200 | sed -e 's/\(.*\)/"\1"/g'))

which gives something like
20170419._domainkey TXT “v=DKIM1; p=” “MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvCNqU0Njd4YQ4e89T3FNc+uyOS2JwUqynGk7uwcSYHjIE2MGRuTxi56s4JgPKSnCVlBkJlUnXQHXFp2UGnLm8SADtjRMfWwpNxz6TmzXBpMnNZV1zvuoBBdcxh0Qg1TtCSACtWM6ehml0BmOHVA8Ippqj9iRlP2HMjuVMxZXewN9eJl”

That all goes into one nameserver TXT record, spaces and all.  The world will join up the ” ” and get one big string. Note the bold number up there? That’s the selector. That a number needs to get larger with each new key.  Periodically you’re going to have to reissue your key because security.  You know what gets larger as time goes by?  The date.  Use the date.  If you screw up, use tomorrow’s date, etc.

Once you’ve got our public key out to the public via our public nameserver, we need to get exim to sign the payloads:

sudo nano conf.d/main/01_exim4-config_listmacrosdefs

After the line CONFDIR = /etc/exim4, add:

#DKIM loading
DKIM_CANON = relaxed
DKIM_DOMAIN = ${sender_address_domain}
DKIM_SELECTOR = 20170419

and reload the mail server

sudo service exim4 restart

After an appropriate delay for nameserver propagation, use to check your work.
If that works out, from to ensure everything checks out:

echo -e "Test my DKIM plz\nMsg Body\n.\n\n" | mail -v


Domain-based Message Authentication, Reporting and Conformance is where the wheels can come off if you screwed anything up.  We’re going to set things up so that when you screw it up, computers scold you rather than putting your emails in the bin.

You will need to create two dmarc reporting accounts.  Servers will email you a (surprisingly detailed) report card on how you’re doing with your implementation. It’s best if these accounts are on the same domain, because technically you need to be or it’ll be ignored (Google will happily mail reports off-domain even if the other domain hasn’t said that’s okay).  Yours are and, according to the following nameserver entry: 1800 IN TXT "v=DMARC1;p=none;pct=100;;"

none is the consequence for screwing up. none is where we’ll start at, and see what the reporting records say to us.  After a while, you’ll be comfortable that everything is ticking along nicely, and you’ll up the consequent to quarantine (shove it in spam) or reject (burn it).

After your nameserver changes have propagated, you can go to to check out if you got it right.

As a human, to read the records sent to you, upload the files to

Making a captcha deamon for spamgourmet installations

For those of you following along at home, this is part of a cookbook style instruction set for getting spamgourmet going, but because of screwed up permission logic I can’t post this section there.

The captcha is for validating humanity when creating spamgourmet accounts. We’re going to limit what parts of the OS it can tromp over:

sudo useradd -c "captcha server for spamgourmet" -f -1 -M -r captcha
sudo /bin/mkdir -p /var/www-spamgourmet/captchasrv/
sudo chown -R captcha /usr/local/lib/spamgourmet/captchasrv/
sudo chown -R captcha /var/www-spamgourmet/captcha

Now we make our one-line shell script for running the daemon

sudo nano /etc/init.d/

# Provides:          captchasrv
# Required-Start:    $local_fs $network
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: captchasrv
# Description:       captcha daemon for spamgourmet
sudo -u captcha perl /usr/local/lib/spamgourmet/captchasrv/ &

Next we get it going

sudo chmod +x /etc/init.d/
sudo update-rc.d defaults

And check if that worked, there should be about four entries:

ps -aux | grep captc

Now the captcha server will start whenever the computer starts.

How to to install the Crypt::Eksblowfish::Bcrypt module, and Crypt::Random

Have you gotten the error
Can't locate Crypt/Eksblowfish/ in @INC (you may need to install the Crypt::Eksblowfish::Bcrypt module)
and wondered what to do? Wonder no more!

sudo apt install libcrypt-eksblowfish-perl

and perhaps

sudo apt install libdigest-bcrypt-perl

What about
Can't locate Crypt/ in @INC (you may need to install the Crypt::Random module)

sudo apt install unzip make gcc
cd Math-Pari-2.01080900/
perl Makefile.PL
sed -i 's/CLK_TCK/CLOCKS_PER_SEC/g' pari-2.1.7/src/language/init.c
make test
sudo make install
cd ..
tar zxvf Crypt-Random-1.25.tar.gz
cd Crypt-Rando1.25.tar
perl Makefile.PL

Easy! Only takes a few hours if you don’t know what you’re doing.

Installing a secure Apache webserver to run Perl

So, you want to run Perl on the web, because it’s the 90s all over again. You want HTTPS, because… no, there’s no because.  You want HTTPS.  Who wouldn’t?  Here’s what you do on a Debian Linux such as Ubuntu:
sudo apt-get install apache2 libapache2-mod-perl2
mod-perl is an Apache module that allows Perl programs to be executed from Apache.

Our goal is to get /var/www/html/ running at

print "Hello World"

Disable the default Apache virtual host:

sudo a2dissite 000-default.conf

Create an file in /etc/apache2/sites-available with your text editor, replacing instances of with your own domain name in both the configuration file and in the file name /etc/apache2/sites-available/

<VirtualHost *:80>
     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined
     <Directory /var/www/>
              Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
              AllowOverride None
              AddHandler cgi-script .pl
              Require all granted

<IfModule mod_ssl.c>
<VirtualHost *:443>
     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined
     <Directory /var/www/>
              Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
              AllowOverride None
              AddHandler cgi-script .pl
              Require all granted

If you have multiple sites, you’ll want to do things with DocumentRoot to isolate them from each other. But that’s for another post.

You might add in DirectoryIndex / to make execute your program.

The Directory section above allows you to isolate executable code from served code, which is good practice. For this example we’re dumping the executable in with everything else, which is questionable.

Repeat this process for any other domains you host.

sudo a2ensite
sudo ln -r -s /etc/apache2/sites-available/ /etc/apache2/sites-enabled/
sudo service apache2 restart

Punch holes in your firewall for ports 80 and 443.  Navigate to to check all is okay. You ought to see Hello World displayed for your website.

Having security used to be a pain.  SSL certificates signed by a recognised CA cost money, and then you’d have to keep them up to date, and there wasn’t process automation, so you’d do all that stuff by hand.  LetsEncrypt address all these problems, handing out free certificates and scripted everything.

Now it’s time for the S part of HTTPS:
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache
sudo certbot --apache

certbot renew
If that works, we’ll automatically renew our 90-day certificates every month:
echo '@monthly root /usr/bin/certbot renew >> /var/log/letsencrypt/letsencrypt-auto-update.log' | sudo tee --append /etc/crontab

Done.  You’ll never have to worry about certificates again. Now alter your Apache sites-available file (look in /etc/apache2/sites-available/) to include the (optional) redirect HTTP to HTTPS and the mandatory location of the SSL certificates:

<VirtualHost *:80>
# Only allow HTTPS
RewriteEngine on
RewriteCond %{SERVER_NAME} =
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]

<IfModule mod_ssl.c>
<VirtualHost *:443>
SSLCertificateFile /etc/letsencrypt/live/
SSLCertificateKeyFile /etc/letsencrypt/live/
Include /etc/letsencrypt/options-ssl-apache.conf

Now make the secure version live, and in the process the insecure one… shy? When a request is made for a http page, like, the response will be “Here’s where what you asked for has moved to… forever!”:
sudo service apache2 restart
Now requesting ought to deliver you to

Install exim4 STARTTLS using a free LetsEncrypt certificate

Here we are on a Debian Linux, such as Ubuntu and we want to run a mail server. Exim4 is currently the most popular email server, but getting it up and working for free is a hassle – who wants to pay for a SSL certificate, on an ongoing basis? And then there’s the maintenance of the security of it – constant renewal, renouncing and re-installation of the certificates.

Wherever you see, swap in your Fully Qualified Domain Name. That may be
It’s assumed you’re not logged in as root, but user ubuntu
Wherever you see, swap in your machine’s local IP address, from
ifconfig | grep "inet addr" | grep -v ""

Security is all handled automatically by LetsEncrypt’s certbot. I’ll let you look that one up yourself. Run it up and get your certificate for

Once you’ve got that handled, punch a hole in your firewall so that port 25 can get through from the outside world to your machine. Be aware: the outside world is filled full of botnets trying to hack into your machine.  After installing exim, keep an eye on the logs in /var/log/exim4/ for a while.

Let’s install exim4:
sudo apt-get install exim4
sudo dpkg-reconfigure exim4-config

  • pick “Internet site”
  • system mail name is
  • IP address is (the one returned by ifconfig, not the externally accessable one)
  • Other destinations:
  • No relays
  • No smarthost
  • No Dial-on-Demand
  • mbox format (or whatever)
  • Split the files
  • ubuntu for postmaster mail

Check we’re now running a mail server:
sudo netstat -napt
should show
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0* LISTEN 25700/exim4

Now we have a mail server, the world needs to find it. Check your nameserver setting to ensure mail is destined this machine.  You probably want only one MX record.

Check the Internet can send mail to our server. After allowing for the appropriate propagation delay for your nameserver changes, use gmail or something to send an email to – you should be able to read it by typing

Now it’s time to enable MTA-MTA link encryption for secure transport of mail, by enabling STARTTLS on exim4 using our LetsEncrypt certificate
sudo nano /etc/exim4/conf.d/main/03_exim4-config_tlsoptions
Enable STARTTLS by adding/setting in the tlsoptions section:

before any of the IF shenanigans. Also add/replace pointers to the certificates:
tls_certificate = /etc/letsencrypt/live/
tls_privatekey = /etc/letsencrypt/live/

The MAIN_TLS_CERTKEY = no entry fixes an exim4 log message
2017-04-16 09:13:24 TLS error on connection from (IcePlanet) [] (cert/key setup: cert=/etc/exim4/exim.crt key=/etc/exim4/exim.key): Error while reading file.
You will see this when testing with swaks:
$ swaks -a -tls -q HELO -s -au test -ap '<>'
=== Trying
=== Connected to
< - 220 ESMTP Exim 4.86_2 Ubuntu Sun, 16 Apr 2017 09:13:24 +0000 -> EHLO IcePlanet
< - Hello []
< ** 454 TLS currently unavailable *** STARTTLS attempted but failed -> QUIT
< - 221 closing connection
=== Connection closed with remote host.

Allow exim (which when running runs as user Debian-exim) to get to the certificates:

sudo groupadd privkey_users
sudo usermod -aG privkey_users Debian-exim
sudo sudo chmod g+rx /etc/letsencrypt/live/
sudo sudo chmod g+rx /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/live/
sudo chown root:privkey_users /etc/letsencrypt/live/

Changing these permissions doesn’t affect apache2’s ability to get them.
The reason we’ve used a group here is to allow both exim and any other app (for example, a secondary service that wants to use 8080 to serve up a configuration page) to access the private keys; just add any other user that needs to use the private keys to the privkey_users group.

These permission changes prevent the following error message in your log file:
2008-06-03 08:27:35 TLS error on connection from ([]) [] (cert/key setup: cert=/etc/ssl/certs/server.pem key=/etc/ssl/private/server.key): Error while reading file.

Restart the service and the TLS settings ought to be working
sudo service exim4 restart
Test STARTTLS is working from another machine
swaks -a -tls -q HELO -s -au test -ap '<>'
There shouldn’t be any obvious complaining.


Cheap passport photos using The Gimp and 10c printing

Australian Passport requirements are specified by Border Force.  The step that’s most avoidably expensive is the generation of compliant photographic representation of the individual (at $17-$20 per person).

The fun part is that the published instructions talk about “face size” (the skin-visible bit of your head, so from your hairline down to your chin) needs to be between 32mm and 36mm; to allow for the vagueries of conversion we’re going to shoot for exactly 34mm.  The passport application form talks about “chin to crown measurement” being in this range, and the bit where you stick the photo on implies that the chin-to-hairtop has to fit in the image; which one will be enforced is up to the interviewing officer and may lead you to tears.  I ended up taking two scaled images and let the officer choose.  The top we’ll measure to I’ll call “head top”.

Take your appropriately posed and positioned photograph. Don’t crop too aggressively: there’s plenty of pixels in modern photographs, and you can’t add “more person” if you got the ratios wrong.

Load the photo into the Gimp.

Find out how many pixels there are from the chin to headtop by picking Tools | Measure and measuring as close to vertically as you can between these two features. I got 1573 on my image.

Whip out your calculator and divide this by 68% (34mm face height/50mm image height), getting you the number of pixels high your image needs to be to make 50mm – 2313 in my case. The width is 80% (40mm image width/50mm image height) of this number – I get 1850.  Photographs nowadays typically use square pixels.

Now for the image we’re going to paste into. Standard photographs are 6″x4″, or about 152mm x 101mm – let’s call it 150×100. So select File | New, with a size double the height of the cutout, and a width of triple the height of the cutout – mine was 4626 x 6939.

Now we’ll put some guidelines on to help us place accurately. Select Image | Print Size... and put in 6″x4″ (Once you put in the 6″, the 4 should magically fill itself in). Pick View | Show Grid and View | Snap to Grid. Select Image | Configure Grid... and set up a 5mm x 5mm grid. There should be a lot of 5mm boxes on your image now.

Switch to your photograph.

Now check Windows | Dockable Dialogs | Tools Options has got a dialog up, and pick Tools | Selection Tools | Rectangular Select. On the options dialog (which may need resizing so you can see all the options), check Fixed and pick Size from the accompanying drop-down. Enter the dimensions you’ve calculated.

Now select your face, and copy it. Switch to the new image, and paste you image. Position it, and paste in your face. You ought to fit three across, and two down. Six passport photos for 10c! Yay!

Suppose you’re doing two different faces on the one photograph (or more!). Once you’ve gotten as far as doing the calculations for the second image (what are the chances you’ll get the same framing of the face?) and then copying the face, stop. Instead of pasting it into the printable image, pick Edit | Paste As | New Image. Pick Image | Scale Image, ensure Width and Height are locked with a chain symbol, then enter the Height of your original face (2313 in my case). If everything is going hunky-dory, the calculated width will match the new width in the dialog. Press the Scale button, Select | All, copy the image and paste it into your printable image, then position appropriately.

Now, to print out you’ll need a JPEG. Select File | Export, type in a filename ending in .jpg and you’re set. Take to your local Officeworks/Harvey Norman, and 10c later you’ve got your Australian passport photos.

Viali VCCG90SS and VCCG60SS rangehood installation instuctions

As the current home reno project is a kitchen rebuild (walls added and removed, nothing left behind – it’s dramatically more than a remodel) the first step followed was to acquire all the appliances (constructing the kitchen and then finding the oven that you’ve got a very specific sized hole made for is “no longer available” would be… disappointing).

One of the acquisitions was two Viali VCCG90SS rangehood extractor units, one for each cooktop. Noise during operation, rated capacity and acquisition cost all seem acceptable. The instruction manual seems, at first glance, fabulous: large, clear font, line drawings giving unit dimensions, step-by-step installation images and all in a matte A4-sized, easy-to-read format.

When you actually read the instruction manual with the intent of following the instructions for installation, that’s when you run into some difficulties. Let’s be clear: I’ve installed a couple of ducted extractor fans in the past, so rangehoods are not some unknown quantity for me. This is not my first rodeo. I consider myself handy, I’ve installed kitchens from the ground up. I’ve spent quite some time puzzling over this booklet, I’ve searched the Interwebs, I’ve really battled with this.

I will now try to explain how the heck you’re meant to install this Viali rangehood, because the shipped instructions sure don’t. Perhaps I’ll do it via annotation. Continue reading