Spam filtering with qpsmtpd
We all know e-mail is broken. It's become an arms race between spammers and the world to keep the stuff out of our inboxes. Well, my spam-prevention process got a big shot in the arm yesterday, by installing qpsmtpd, a drop-in replacement for qmail-smtpd.
qpsmtpd is another fine product by Ask Bjørn Hansen. It's written in Perl. Quite modular and extensible through a plugin architecture, so it's naturally a good fit with me.
At this point, if I get a spam e-mail, it's pretty close to a miracle. Here's what an inbound e-mail has to go through:
- First line of defense is qpsmtpd itself, which runs a variety of checks as it receives each e-mail (all of these are provided by qpsmtpd out of the box, unless otherwise indicated):
- "Early talker" check -- if the smtp client starts dictating the e-mail message before qpsmtpd even responds to the HELO (or EHLO) command, the conversation is cut off with a "don't be rude" error, since the client is talking out of turn and is most likely a automated spamming process that isn't waiting on anything to do it's business.
- A check of unrecognized SMTP commands. This is good for rejecting spam sent through HTTP proxies (or at least so says the documentation). More than 4 of these and the connection is cut.
- Check for a resolvable "from" host. Very effective for anonymous spamming, as it requires that the from host resolve.
Yes, if Verisign reimplements Sitefinder, they will break this step.
- rhsbl - Domain-based blacklist provided by rfc-ignorant.org.
- dnsbl - Another domain-based blacklist, powered by Spamhaus, Mail-abuse.org and others.
- From domain check. Simple user-defined list of unacceptable domain names.
- Recipient check. Simple user-defined list of unacceptable recipient names.
- Check for spam "HELO". Rejects messages where the HELO command is from a user-defined list of domains (handles cases where spams announce themselves as coming from yahoo.com or aol.com, both of which never handshake like that).
- Greylisting. Brilliant technique where e-mails are initially, but temporarily rejected. If the originating server retries the message after the greylisting timeout has passed, the mail will pass through. You know all those hijacked computers out there that are spamming? They don't handle soft-bounces like this. Read more about greylisting here. (This is a 3rd party plugin for qpsmtpd, available here.)
- Relay check. Prevents relaying.
- ClamAV scan virus scan (signatures are updated daily).
- SpamAssassin scoring.
- After all this, e-mails are delivered to their inboxes. But wait-- there's more!
- Whitelist/blacklist/challenge-response. I use Knowspam as my POP server, so it picks up the e-mail from my mail server, passing through any valid e-mails and sending challenge e-mails to anyone not already recognized. (I think there are qpsmtpd solutions for this too, but I like the way Knowspam does the challenge/response process, so I'm sticking with them for now.)
- My Apple Mail junk filters are the last line of defense if all else fails. But so far, by this point, there's nothing left to filter.
I'm considering enabling ClamAV as well which will scan for any virus content. I'll wait until I get a viral message first though (not a concern either way since I don't do Windows anymore, but would be helpful to others that use my server for e-mail). (ClamAV is now in the mix.)
If a spam message gets through after all the above, it probably means it's being sent from an individual, using their own e-mail client and with pretty benign content that isn't recognized as spam for whatever reason. They would have also had to go through the Knowspam challenge process which means they have a valid e-mail address. At that point I can just block the e-mail address and/or domain if I want.
I should also point out that since signing up with Knowspam back in August, it has reportedly blocked 22,401 spam messages for me. Thats over 100 a day. Since enabling qpsmtpd (and the greylisting plugin for it) yesterday, that number hasn't gone up. Impressive.
My e-mail inflow has slowed to a trickle of it's former volume. A bittersweet victory. I feel relief, but also a little lonely all of a sudden.