Chris' journal has moved to - My shiny new email config [entries|archive|friends|userinfo]
Chris Boyle

[ website | ]
[ userinfo | insanejournal userinfo ]
[ archive | journal archive ]

My shiny new email config [May. 12th, 2008|04:50 pm]
Previous Entry Add to Memories Tell a Friend Next Entry

[Tags|, , ]
[Mood | frustrated]
[Music |Ghosts - Mind Games]

For just over a week now, I've had a Gandi VM handling my email and a few other services. I want my email server to be reliable, secure, cheap to run and I want it to reject spam reliably and efficiently, since most of my incoming email is spam. Having my own small VM at a well-organised hosting company for much less than colo prices is therefore a good start. I can tweak things to my heart's content and I minimise the effects of other people's tweaking and/or the disappearance of the Intermittently Seen University (aka the Warwick campus network), which were always my two big problems with CompSoc services.

Choice of MTA is the subject of flamewars just as often as any other software decision. I use Postfix, because its configuration is relatively easy to understand, it lets me plug in the filters I want and it's been recommended to me more than once by people with more complex needs than mine. My basic Postfix setup is as one would expect; there are a couple of domains going to me using virtual_alias_maps, I catch postmaster and the like using luser_relay, don't forward any mail, mynetworks_style=host, and so on and so forth.

Looking at my syslog, far and away the most common reason I reject mail is a dodgy HELO string. I'm fairly strict about this; a claimed hostname really ought to exist and not be a known spam host:
smtpd_helo_restrictions = permit_mynetworks reject_invalid_helo_hostname reject_non_fqdn_helo_hostname reject_unknown_helo_hostname reject_rhsbl_helo
I also check SPF on incoming mail before accepting message data, using the postfix-policyd-spf-perl package. My attitude is that anyone who's defined an SPF policy and switched off testing mode probably means it. I've decided against Greylisting in the end. Nice and easy to set up with postgrey, but predictably, spammers have started retrying addresses, so there's not much benefit, at which point I'd rather keep my Instant New Mail™, even from people who haven't emailed me before. The one advantage of it is that the collaborative databases that SpamAssassin uses (see below) are more likely to have caught up with a spam run if I wait while others report it. (Edit: TODO in my copious free time: greylist just the stuff between 5 and N points, which currently goes into my "maybe spam" folder; it may then be above N points and rejectable when it comes back.)

Edit: Knew I forgot something. I also use address verification for a few frequently forged domains such as, straight out of the verification readme.

Once I have the message data, I do one more sender-policy-style check: DKIM, which checks signatures in headers (dkim-filter, again the configuration is fairly obvious) and finally call SpamAssassin for content-based filtering. This is still before-queue filtering, so I minimise my contribution to backscatter in that I don't actually generate a bounce message, I just refuse to enqueue the incoming message in the first place (there may still be intermediate hops which will generate bounces, but the only remedy for that is for me to pretend to accept spam and blackhole it, which I don't like for various reasons). A disadvantage of before-queue is SA doesn't know which addresses map to which users. I've told it to always use me for the moment; if I let others onto this server in future (which I might) I'd have to use either SQL or LDAP for that mapping, shared between Postfix and SA.

I previously used dspam, a simple but clever message classifier, which initially was quite good, but had become less effective in recent years. These days, SpamAssassin seems a better bet again; it's a combination of Bayes, content checks (e.g. phrases suggesting advance fee fraud) and collaborative blacklists. It also looks at things like Received headers: for a lot of my incoming mail, I'm not actually the MX (e.g. my address), but I can tell SA that I trust, at which point it can check the mail hop before that for certain things (e.g. blacklists) retroactively.

I then use procmail to put things in Maildirs as I have for years, and dovecot for IMAP access, which Just Works™ with very little tweaking.

The VM's also very handy as a secure relay for my outgoing mail, wherever I happen to be. Getting Postfix to use PAM/local accounts for that is harder than it ought to be. The easiest way is to delegate authentication to dovecot, strangely enough. Uncomment the auth listener in dovecot.conf, setting it to /var/spool/postfix/private/auth and the Postfix user/group, and tell Postfix smtpd_sasl_type=dovecot and smtpd_sasl_path=private/auth.

Out of personal preference (and in case I want to send from somewhere that blocks port 25 outbound) I've set up the separate submission port for authenticated users only, per RFC 2476, in Postfix's It's worth noting that some options (notably canonical_maps, which I use to fix my sender address no matter what From line I'm using) don't seem to work as -o lines there, for reasons I don't understand (couldn't see anything in the man pages). There might be a bug there, to be investigated in my copious free time.

Retraining SpamAssassin (because, yes, even after all that, some still gets through) is slightly easier now that spamc and spamd allow remote learning or reporting; I have a little script that reads a message, forks and calls spamc -C report, and a shortcut key in mutt, so if I see several spams have slipped in, I can just press it a few times and get on with life. The previous version of said script called spamassassin -r, which, although it was in the background, slowed the machine down noticeably while Perl loaded a bajillion modules once per retraining message. Edit: I can now easily report spam from any IMAP client, using Johannes Berg's dovecot-antispam plugin, which notices when I move messages to a magic SPAM folder, which I can do with one key press in Thunderbird using the keyconfig extension.

On the subject of spam, I can't help but wonder if some sort of global education campaign would help: Newsflash: The Internet is no different from the real world: not everyone is honest. Stop buying from spammers and the spam will go away. Someone, somewhere, is buying this stuff. That person needs to be cluebatted, hard, because spammers are seemingly not in jurisdictions that care about spam, so the only way I can see to stop them in the long term is to remove their market.

I haven't yet found a sensible way to keep a central list of contacts on the server; LDAP seems to be serious overkill but it's all Thunderbird and others will support. Does anyone know of a tiny LDAP server or similar for this sort of situation? For the moment I'll stick with my Palm Treo's contact list (which integrates nicely with mobile email clients) and keep typing addresses into the desktops I use.