So You Want To Run Your Own Mail Server…

Whenever the subject of running your own mail server comes up, there’ll always be two people who chime in.

The first will say “No, don’t do it! It’s a virtually impossible thing to do these days!”

The second will say “Don’t listen to that guy! It’s trivial! I just installed one and I had no problems!”

Both are right, and both are wrong: It’s very much possible to run your own MTA (Mail Transport Agent), but there’s a lot of steps required if this is to be successful (where “successful” is here defined as “Gmail won’t put your email in the spam folder”). Every one of these steps are trivial, but you have to suffer through many TLAs and ETLAs concepts that there’s really no point in knowing anything about.

I mean, just to run a mail server.

So I’ve written a script that does it all for you. Other than the DNS changes that you’ll have to do, but it’ll tell you exactly what you have to put where.

The script requires a Debian or Ubuntu host, and it’ll install a whole lot of stuff. If you already have a partial mail server setup, it may break the server. Nothing’s guaranteed.

After running it, you’ll have a host with (ETLAs incoming) the exim4 SMTP server (with TLS, DKIM signing, ClamAV and Spamassassin), Dovecot IMAP (with TLS), SPF, DMARC and certificates from Let’s Encrypt.

If you’re a spammer (I mean “marketing expert”), please go away. This is not about being able to send out newsletters; it’s for people who want to run their own mail servers for whatever reason (for instance, to avoid the monoculture of Gmail).


Download the script

curl -O

and then run it. Follow the instructions, and you’re done.

Longer version:

Running a mail server doesn’t take much work: After it’s up it, it’s probably going to stay up. However, I’m going to go through all through all the steps the script does, so that if you’re interested you can understand how it all fits together.

This is going to be overly detailed: I’m going to go through everything, point by point, from provisioning a server to configuring your mail client. Prepare to scroll.

The assumptions are: You own a domain, and you want to send out mail from that domain, and you want to receive mail for that domain. In my case, I have the domain “”, and I’ll be using that throughout all the examples.

First of all, you need a name for the server. “mta” is nice, so I’ll call mine “”. Now that the difficult part is over (“there’s only two difficult things in IT: Naming, caching and off-by-one errors”), you need a server.

Any hosting provider is fine: Let’s go with DigitalOcean. After you’ve gotten an account there, click “New Project”, give it a name, and then “Create”.

Create a Ubuntu LTS image; the cheapest one they have. An MTA requires virtually no resources, but if you expect to keep a lot of incoming mail on your IMAP server, you may want one with more storage than 25GB.

These days, it’s nice to have IPv6 support, but it doesn’t really matter much.

You need a way to log in. I strongly recommend adding your public ssh key here, but you can also use a password.

And here’s where you enter that name you came up with earlier.

Then create the server (or “droplet” as DigitalOcean cutesely calls it).

Within a few seconds, your server is created, and that number is the IPv4 address of the server (and the unhelpfully shortened IPv6 address).

Now go to your DNS provider (and you’ll be doing a lot of things here, so keep this window open) and add some resolving.

I’m using Cloudflare, because it’s… nice?

That’s an “A” record for the IPv4 address…

… and an AAAA record for IPv6.

Now you can ssh to the server:

Download the script

curl -O

and then run it:

This will do basic stuff like “apt upgrade”. Nice to have the system somewhat up-to-date.

This will install and enable the ufw firewall, and open the ports we need to run an MTA (ssh, smtp, imaps, http). fail2ban is also installed.

The script will then try to figure out the host name based on the IP address. If it can’t, then it means that reverse DNS wasn’t added automatically, and you have to add a PTR DNS record for the IP address (both IPv4 and IPv6, if you have that). All MTAs need to have reverse IP records, otherwise many MTAs will refuse to accept mail from the server.

This will start a standalone http server and use the Let’s Encrypt servers to acquire a TLS certificate. Answer the questions it asks.

Next, it’ll fetch and configure exim itself (along with SpamAssassin and clamav), and set up DKIM. (DKIM is a way to sign mail so that others can verify that it comes from your mail server.)

This server accepts mail for you, so you need a way to read it. IMAP is the preferred way for most. This IMAP server will also use the Let’s Encrypt certificates to authenticate the connection.

We’re done! That is, we only have to make these DNS changes that the script has summarised. So let’s do them, one by one, in the Cloudflare interface.

First, the DKIM public key. This will allow other MTAs to verify that an email came from this MTA.

Then the SPF data. This says that your MTA is allowed to send mail from your domain.

Then the DMARC data. This says that you should do with failures from DKIM and SPF. (Note that this DMARC policy is very relaxed; you may want to make it more strict.)

Finally, add an MX record for the domain. This means that all incoming mail for the domain will go to this mail server.

Now the server is all set up… except that you probably need a user that’ll receive email there.

You may want to choose a different name (if you have a different name).

Let’s see what the mails look like now:

Mail-Tester is a convenient tool to test how it all went.


Even Gmail can’t complain about your mail now.

Well… unless they do. They’ll probably find some other hoops to run through any day now, but for the moment you should be OK. Oh, and if you’ve provisioned a server that happened to get the IP address of a previous notorious spammer, you may find that your mail gets tagged as spam, anyway. In practice, if you use a reputable hosting service, this isn’t a big problem, but it can happen. If that’s the case, try again and get a new IP address.

Anyway, it might be helpful to also show how to connect to the MTA, right? As an example, here’s Evolution:

Basic info.

IMAP on port 993 (with TLS).

Outgoing email on port 465, with TLS and authentication. Done!

The reason I started thinking about writing this script (and blog post) is twofold: I think it’s a shame that we’re devolving from a decentralised infrastructure for email to a centralised one (i.e., Gmail). We can all see where Gmail is heading — towards a total silo, but it hasn’t quite gotten there yet, because they still have to interoperate somewhat with the rest of the world.

The other is that it’s really annoying that (apparently) nobody has done this before. It’s not like any of the things that the script does is difficult: It’s just that if you don’t know what you’re supposed to do, you can spend hours Googling around, and you’ll mostly get outdated information. For instance, if you search for “exim authentication”, you’ll find this official-looking page that gives horrendous tips like “You also need to add the Debian-exim user into the shadow group, so as to give Exim access to /etc/shadow via PAM.”

No! You should absolutely not let the exim process read the /etc/shadow file, because that’s a way to escalate bugs in the exim server.

And so on.

The script is on Microsoft Github, and pull requests are very welcome. I’m sure there’s many things that can be improved.

Outgoing DKIM and exim4

So, I sent an email to my sister, and I didn’t hear back. After exchanging some SMS-es, it turns out my mails went to the spam box on Gmail.


That’s a new development for my MTA (, so I tried poking around seeing whether I’d ended up in a blacklist or something. But, no, apparently Gmail now sends you to the spam hole if you don’t have DKIM on your outgoing email, and the moon is in the wrong alignment with Saturn.

So I thought “well, enabling outgoing DKIM on exim4 on Debian is surely just one command?” Right?

After googling around, I found… nothing. I did find a bunch of howtos, but they were obviously outdated because the referred to stuff that no longer exist.

So if you’re in my situation, and really don’t want to know anything about DKIM beyond AAARGH GMAIL THINKS I”M A SPAMMER, I’ve written a teensy script that should get you up and going.

At least at the time of writing, and with the current version of Debian Stable. (I’m writing this at on March 22nd, 2020, at 23:43. If you’re trying to set this up any time later than that, you probably have to tweak stuff a bit.)

And look what Mail Tester says now:


Of course, my email is now so authenticated and secure that if my MTA goes down, I’ll never be able to send a single mail ever again.

OTB#48: The Searchers

The Searchers. John Ford. 1956. ⚃

There’s sure a whole bunch of westerns on this survey, padner. I got this one from a 20 disc box set some years back. I think it was this? That’s a pretty solid collection.

This is the only John Ford movie on the list, which is somewhat surprising. And if I remember correctly, this isn’t the most visually striking of his movies…

But perhaps I misremember; it’s been decades since I saw this movie last.


Or perhaps I have never seen it before, because (I’m half an hour in), and nothing seems familiar.

It is pretty startling seeing the white made-up guy playing the lead Native-American role.

[another half hour passes]

OK, I don’t quite get it. I usually love John Ford’s movies, but this is all kinds of … squicky? Around the edges? Like the funny bits where the comedy sidekick accidentally buys a Native-American wife (for the price of a hat)? It’s… in a different, more goofy context, that would still have been pretty odd, but here? Where they’re searching (note: title) after a guy that’s killed (and heavily implied, raped) a whole family, and kidnapped a little girl, it’s…

Weird? Slightly squicky? Especially when the comedy sidekick’s “comedy” spouse abuse sets in?

The mood swings in this movie is enough to give you a whiplash. The deranged cowboy set on revenge and the homey interludes…

OK. On the positive side, it does looks quite nice. I wish I had this on 2K instead of DVD, but it still looks surprisingly spiffy. John Wayne is, as ever, iconic, and the rest of the actors are… present…

I do not understand, at all, why this movie is on this “best of” list in preference over… a dozen other movies by John Ford.

Well, that’s a varied list of directors voting for the movie.

OK, I was bored, so I googled around seeing if anybody had a full data set of all the Sight & Sound polls. Nobody has, but this guy has done an interesting analysis of the available data.

This blog post is part of the Officially The Best series.

OTB#48: Pickpocket

Pickpocket. Robert Bresson. 1959. ⚅

Oh, I’ve got this both on DVD from Artificial Eye and bluray from Criterion…

I’m watching the Criterion release.

OH MY EMACS! Bresson is straight from the screen into my pretentious mind. Those affectless deliveries! The moral quandaries! Those French hairstyles! It’s just pure fabulousness. I’m there from the first frame to the last.




It’s the most thrillerey thriller ever.

Bresson is still hyper-modern; i.e., his style hasn’t arrived yet, but it must some day.

OK, the last fourth is a bit of letdown.

Oh, this one has a lot of leftover liqueurs. It’s all liqueurs! I B Damm’d.

Hm… I had expected something super-flavourful, but the liqueurs weirdly cancel each other out.

This blog post is part of the Officially The Best series.