Setting up secure custom email domain: My Email security setup.
After setting up this website yesterday, the next logical step was to get my own @kevhq.com email domain. Not a how-to post but I’ll go through the choices I made and the security hardening I put in place.
First off, fuck Google. I went with Proton Mail. Why?
- Privacy. They are not selling or harvesting my data. Or at least claim not to be.
- Multiple addresses beyond just the ”+” Gmail trick. My gmail is mostly spam at this point so I want to have a system generating email address per service for easy and good hygien going forward.
- Four euro a month. I’m happy to pay for something I use every day. If you are not paying, you are the product as the saying goes.
- Solid reputation for security.
Basic setup
The basics were straightforward. I added my custom domain to Proton Mail, set up MX, SPF hard fail, DKIM and DMARC records. This is simple so won’t expand on this.
The nerdy stuff: MTA-STS and TLS-RPT
Wait, what is this and why bother? Most email uses opportunistic transport encryption. This means:
- It might not actually be encrypted in transit.
- Even if it usually is, an attacker could intercept the handshake and downgrade it to plain text so they can read it.
- In some cases, they could even redirect it to their own mail servers.
- All without you knowing. Yes, email is an old outdated, flawed technology.
SPF, DKIM, and DMARC do not solve these problems.
MTA-STS does. It tells the world (or more specifically mailing servers):
- Which MX servers can receive mail for my domain.
- That TLS encryption must be used when sending mail to me.
- If you can’t set up encryption, then don’t send the mail at all.
For a much better covering of this I highly recommend reading this and this
The problem
Proton Mail supports MTA-STS for their normal users but not for custom domains. So I had to build my own setup.
The solution
After reading a couple of guides, I went for a simple once-off infrastructure setup:
- A locked down S3 bucket with a
mta-sts.txt
file. - Cert issued by ACM for mta-sts.kevhq.com.
- CloudFront using ACM cert in front of the bucket with an Origin Access Identity (OAI)
- An A Alias DNS record for
mta-sts.kevhq.com
pointing to the CloudFront distribution - Two TXT records for
_mta-sts
and_smtp._tls
(for reporting).
Effectively all I am doing here is hosting Proton’s policy myself, because Proton don’t host it for custom domains. Exact instruction for AWS can be found in the link above.
Why not just proxy to Proton?
A fair question. If I just proxied mta-sts.kevhq.com
to Proton’s file, I wouldn’t have to maintain it if they updated it. I could only think of three reasons Proton might change their file:
- TTL change: I can ignore this, I want my own TTL.
- Going from enforce to testing: I don’t want this change applied to me.
- MX record change: If Proton changes their MX records, I’ll need to update my MX records anyway, so updating this policy file at the same time is no extra hassle.
First send
I could now send and receive email from kevhq.com. The first email I sent to Gmail went straight to the spam folder. This is fairly normal for a brand new domain. Reputation takes a little while to build.
Final hardening
Would love to run DANE but can’t due to very low adoption plus Proton doesn’t support it yet.
The final cleanup security steps were:
- NULL MX records for subdomains like
www
andmta-sts
, which should never send or receive mail. - BIMI record (without VMC) pointing to a minimal SVG logo. While not strictly security thing (aside from mabye a small trust signal), it is small set and forget thing.
Simple email setup, solid security and privacy, and now I own my inbox.