OpenBSD - Spam

In the past I have used SpamAssassin to manage spam filtering. To be honest I was never completely satisfied with it. Beyond blocking from known deny lists, it applies some analysis to each email and produces a score. You can choose to drop mails over a certain score - but if you do you risk dropping legitimate email. If you can't stomach that, you can send everything over a certain score to a Junk folder.

In my quest to stick closely to vanilla OpenBSD I decided this time around to follow a different approach and use spamd instead. Spamd works by presenting a fake SMTP server to interact with incoming requests. A request is either:

  • Allowlisted - in which case it gets to talk to the real OpenSMTPD daemon.
  • Greylisted - the client is given a temporary error and allowlisted if it tries again within a reasonable time (something spammers usually won't bother with).
  • Denylisted - the client is on a known spammer list - spamd will throttle the connection to one character per second and try to keep the connection open as long as possible - wasting as much of the spammers time and resources as possible.

One of the reasons to use OpenBSD built-in tooling is they are pleasingly tightly coupled. So spamd is driven in part by pf firewall rules:

pass in on egress proto tcp to any port smtp divert-to 127.0.0.1 port spamd
pass in on egress proto tcp from to any port smtp
pass in log on egress proto tcp from to any port smtp
pass out log on egress proto tcp to any port smtp


Where the nospamd and spamd-white tables are automatically populated by spamd.

Getting back at the spammers by clogging up their clients is extremely satisfying, made all the more enjoyable by examining the response codes spamd returns to the clients:

250 Hello, spam sender. Pleased to be wasting your time.
250 You are about to try to deliver spam. Your time will be spent, for nothing.
250 This is hurting you more than it is hurting me.
220 glad you want to burn more CPU cycles on your spam