Thursday, September 08, 2005

Spamalot, less

Until last night, spam had become a real problem for me. Through combinations of SpamAssassin and various other mail filters, I was filtering out about 850 messages/day. Then around 30 more that slipped through the filters that I would mark as spam manually. Then, for the last few days I've been topping 1,000 spams per day. Ouch.

Part of the problem is that I refuse to try to hide my e-mail address, the same one I've been using for over 10 years now. Mostly out of stubbornness, but also because I don't think I should have to. I always give out my legit e-mail address when I sign up for new stuff, I stick mailto links on every web page I have just about, and I have multiple e-mail addresses that go to the same mailbox.

Needless to say, I'm on a few lists.

To make it more complicated, I don't believe in blacklists. I think they are unfair and unreasonable, and I've found myself on the wrong end of spam vigilantism more than once (you mat remember when my server and all the sites on it got knocked off the net for several days). I had to find a better solution, one that didn't involve any work on anyone else's part when they wanted to e-mail me.

So last night I grabbed the latest version of qpsmtpd, a drop-in replacement for the SMTP server that comes with Qmail. I've been running it for a little while, but haven't really delved too deeply into the plugins before. Except for the plugin that I wrote that is. Turns out there are a WEALTH of useful spam-fighting plugins in the distribution. And the good ones fight spam not by blacklisting (which is evil), but by either enforcing or exploiting ACTUAL STANDARDS.

For instance, the SMTP specs say that a mail client should connect to the remote server and wait for a banner message before starting the conversation. Spammers often ignore this, so the check_earlytalker plugin waits a second before displaying the banner. When a spam-cannon hits the server and starts talking before it should, we drop the connection.

Enforcing standards really cleans up a lot of wayward e-mail. Requiring the remote host to accept bounces, as defined in RFC 821 takes out a chunk of spam. Requiring a hostname that actually exists in the From: address takes out another chunk. Verifying originating mail servers via their SPF records takes care of even more.

But the coolest plugin is called greylisting. Basically the idea is that the first time a mail server connects to mine, I tell them I'm too busy to talk to them and to try again later. I keep doing this for some duration (I have it set to 20 minutes), and if they try again after the initial 20 minute trial period but before another 3 or 4 hours go by, then I allow future messages to arrive with no delay. Since a large majority of spam engines are based on zombie botnets or some custom message sending system, the very first denial is enough for them to not try again. Imagine a telemarketer that weeds out everyone who had voicemail, and you always screen calls from people you don't recognize. (Note: this means that if you haven't sent me e-mail in a while, the first time you send a message to me it may take half an hour for me to receive it. And this applies to all messages coming into balance, not just those to me. Also, IMAP, POP3, and SMTP can now all work via SSL if anyone cares).

The result? In the last 24 hours, my spam mailbox has gone from more than 1,000 messages in my one-day-of-spam queue to a grand total of 88 received spams (3 of which were not caught by SA). With no vigilante-style blacklists. Will it last? For a while, unless the practice becomes widespread. But for a 90% reduction in spam volume I'm ready to try it out for a while at least.