I really hate dspam, but it is the absolute best anti-spam solution I’ve ever seen. It works stupidly well. I can turn it on, and it catches all the spam. I don’t care if my email address is on a whole pile of lists. Dspam doesn’t care. It does a fantastic job of marking that crap, and then I happily filter it into a folder, and only keep like 30 days worth, just in case of a false positive. Mostly because I’m paranoid.
But Dspam’s documentation is absolutely horrid. The C code is full of loops and
GOTOs. It is horrid. There’s shared code but the log messages don’t
tell you in which process the thing actually had a problem in, additionally, it doesn’t actually log anything useful. Often times you just get
Segmentation fault, or if you’re lucky you get the usage of the application. Bleeding worthless.
Debug mode doesn’t help much more either.
But all that aside, I met someone awesome in the
#postfix channel on irc.freenode.net that helped me solve all these stupid problems.
I’ve used the Dovecot Antispam Plugin to solve my retraining problems. It truly is the easiest way to retrain.
Basically, any move into or out of a configureable folder (unless you’re moving into the trash, like deleting a message) it will call the appropriate
spam retraining method. I tell dspam to retrain on a signature. Peace of cake. Works in all cases. Except where DSpam sucks, which I’ll detail.
Old Mailserver Setup
My old mailserver is dying slowly. It’s really old now, and the box is having problems. It’s been so long since I set it up, however, that it’s a work of art now and I don’t completely understand how it functions. It’s an old SourceMage Linux box that I’ve kept around for probably almost 10 years now. It hasn’t been kept up to date like I wanted, becuase it would break things.
It’s also running a much older version of dspam, and the newer dspam behaves a bit differently.
The basic flow of that server is as follows: “` SMTP: postfix -> Dspam -> procmail -> my mailbox
IMAP: my mailbox -> dovecot ”`
Postfix delivers to the dspam command, which through a TrustedDeliveryAgent, delivers to procmail, which handles the filtering, and gets it
into my home
Maildir. Dovecot is then detached from the process, but it servers up imap and provides postfix with sasl support for authentication
Desired New Mailserver Setup
I want to have mail come in, filter through dspam, but not have dspam make any decisions. It’s only job is to tokenize and modify the mail message on the way through. It’ll add it’s headers, and whatever else I told it to add, and then hand it on to the next item.
I’m thinking I could just pipe it. I spent the better half of the day learning exim in the hopes that it would be easier to do there than in postfix. Sadly I was mistaken, dspam through the command line interface was too brittle, and inflexible to make it work. I had to give up. Back to postfix, since I knew that much better.
After a bit of time, I had re-established my desired postfix setup, and was able to use it. I had set up Dovecot-LDA
and it’s happily delivering mail to my maildir. Now I needed to find a way to integrate dspam. After about 3 hours of working towards making that
happen I gave up and asked in the
#postfix channel to see if anyone there could help me with piping stuff through dspam.
A wonderful person by the handle of
adaptr had the magic secret of destiny: Use
mailbox_transport and LMTP
the message into dspam, and then have dspam LMTP it back to dovecot. Turns out the LMTP server is even the recommended way to do it, as “it is somewhat
easier to configure, and gives better performance.”
I didn’t even know you could do that. I ended up with something like this:
smtp:postfix -> lmtp:dspam -> lmtp:deliver -> dovecot-lda -> my mailbox
It worked like a charm. Well, it did after I worked out a few more kinks in dspam’s interaction with dovecot and with postfix. After those relatively minor problems were worked out, however, I was able to get mails going into dspam, and filtering. The only thing I didn’t have was correction. I couldn’t tell dspam that a message was trained wrongly. That’s kind of a deal breaker for me.
At one point, I had it properly forwarding things, and doing the right stuff, it would tag it as [SPAM] and deliver it for me, or if I forwarded something that was not supposed to be spam, it’d just deliver it. No new signatures and such. But Dspam is extremely picky, and occasionally, it wouldn’t behave properly and I’d get nasty errors and bounces. Switching to using the Dovecot Antispam plugin worked great. No more problems.
I’ve got dspam also running the mail through clamav, to catch viruses. This will annotate the email with an
X-Dspam-Result: Virus, and so I just update
my Sieve filters to catch it and throw it also into the Spam folder. However, initially I’d forgotten about this.
I ended up with a mail in my Inbox that was obviously spam, that I didn’t think dspam tagged, and I moved it into Spam. Boom. Failure. Additionally,
the dspam server process dies with a segfault. Dspam always dies with a segfault if something doesn’t work exactly as it expects.
This is a huge shortcoming of dspam, probably the biggest shortcoming. It’s still outweighed by it’s awesome abilities to filter mail.
Solution for the brittleness is to make sure that I don’t do anything dspam doesn’t expect, and set up the systemd init script to always restart dspam’s daemon process, no matter what. A lousy solution for some awesomely lousy software.
I should rewrite that sucker, stealing all the cool maths that it uses and ship something better.
Finally, I don’t have any of the stats or webui I used to have on the old mailserver. Those things were also too brittle and stale to get to cooperate. The preferences don’t work at all, and the graphs were only kind of functional. That web-ui is ancient and really needs to be updated to newer web standards. That would resolve several of the maintainability problems of it, and maybe even make it more useful. Of course, Dspam itself needs to be improved so that it can function well in a multi-user environment without switching the actual user who executes the commands. There’s some tricky problems to solve there regarding authentication, however.