I’ve spent the last 3 or 4 weekends playing with technology. I’ve built:
A new self-hosted email system.
I decommissioned my email on Proton and migrated everything to self-hosted docker-mailserver The makers describe it as a, “Production-ready fullstack but simple mail server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.) running inside a container.”
Now, like me, if your understanding of a proper container is an image that runs one process, you should look away now. This is more of a operating system image that runs:
- Postfix as the Mail Transfer Agent.
- Dovecot as the Mail Delivery Agent.
- ClamAV and Freshclam for virus scanning.
- Rspamd or Spamassassin for spam detection.
- Postgrey, Amavis, and more.
It even has cron running things and supervisord controlling it all. But don’t let any of that put you off! I am super happy with it all!
I started with the same Terraform / OpenTofu setup that my webserver uses.
It’s the same t3.medium instance, but instead of running on a Spot instance, I chose an on-demand one with an EC2 Instance Savings Plan. In the Europe (London) region, for a 1 year term and nothing upfront, that should cost me around $22 a month (plus storage) instead of $35 (plus storage).
So now it’s all back under my control. It’s fast. And best of all - I don’t need to deal with Proton’s absurdly poor systems.
A firewall using NFTABLES instead of IPTABLES.
Since I run Debian Sid on both my webserver and the new mail server, I’m using
the very latest tooling in Linux. I noticed that fail2ban
on both machines
were using something called nftables
instead of iptables
and I my usual Geo-blocking scripts didn’t work.
So, I got down to work figuring out the new way to build these things and came up with this script, to block Russia, China, Vietnam, and Taiwan. I’ve popped it online as open source. It should work alongside any built-in firewall on new versions of Linux.
HTTP/3, QUIC, And more firewalling for UDP.
On my webserver, I enabled shiny brand new HTTP/3 and the accompanying QUIC protocol. The interesting bit of this work is that, where the older HTTP/1.1, and 2 using TCP to ports 80 and 443 - QUIC uses UDP to port 80 and 443. So, in addition to lots of NGINX work, I had to open up security groups and do yet more poking of firewalls.
HTTP/3 can handle more traffic and deliver content faster, especially on slower or unreliable networks. It does this by having multiple steams in the same connection, less handshakes, and of course by using UDP transport rather than TCP.
It’s also, in theory, a better security model as it uses TLS 1.3.
DNSSEC for cloudcauldron.io and funderburg.me.
For no particular reason aside from security, and that I could, I setup DNSSEC on both my larger domains. This mostly involved clicking a few buttons in Route53 in AWS to create the signing keys, then adding those details back into the appropriate registrars for the domain. Surprisingly easy work!
Whist I was in Route53, I also moved funderburg.me’s DNS into a new Route53 zone from my DNS provider. They didn’t allow more “exotic” record creations which I’ll talk about below.
An OpenTofu Run for IPv6 on Odin.
It’s been a few months so I re-ran my OpenTofu project for odin
(the webserver)
and the newish freyja
(my mailserver) - mostly just to pick up a fresh base
image of Debian Sid.
But also, it was a chance to enable ipv6 across my VPC and both the ec2 instances. Back into Route53 and added a shiny AAAA record for chris.funderburg.me that points to 2a05:d01c:eb9:2c00:11b5:6c38:49f4:92 - and the job’s a good one.
Still trying to get my head around IPv6 and I’m not sure if that address will change if I reboot - or re-create the machine. I should probably check that! If not, it should be easy enough to use OpenTofu to dynamically update the route53 record.
Enabled the legendarily dangerous HSTS and lots of edge-case security things.
I tried setting up HSTS years ago at work, not quite understanding what I was doing - and its lucky I didn’t get sacked! HSTS very violently enforces HTTPS only connections by leaving an entry in anyone’s browser who visits. This entry tells the browser to NEVER try to connect unencrypted. It also usually says, “and also do this with all my subdomains”. That last one can break casual websites where you forgot to add a certificate.
These days however, I encrypt everything everywhere using Letsencrypt. So, less chance of blowing sites up or having to walk people through scrubbing their browser data. I set it up on funderburg.me and cloudcauldron withing an hour and used the recommended settings of setting it’s timeout first for 10 minutes, now a week. And next week I’ll change it to a month, and the month after, 2 years! In this way I have time to see if I’ve forgotten anything.
And finally, for security’s sake:
- A Certification Authority Authorization (CAA) record, which notes that my web certificates should only come from letsencrypt.org.