« Leica M8 at Badger Game? (Football Photography) | Main | USB drive Cradle from GeekStuff4u.com »

OpenBSD and pf to the rescue again: pf and spamd on a bridge

Today, yet another kudos need to be given to the team of people that help develop and refine OpenBSD. For years, I've been running a qmail server that handles mail for various domains associated with our hosting arm and last week we hit a major snag. The server was running out of inodes available to the /var directory where email is temporarily spooled (either awaiting delivery or being bounced). As every experienced admin out there knows, the overwhelming, majority burden of resource usage these days has to do with processing spam. In our specific case, messages were being bounced from non-users in the domains we handle mail for and would sit awaiting "rejection delivery" for x number of hours. The specific problem we had was that we were being inundated with mail originating from a number of IP addresses that are assigned to Russian and Brasiian web/internet operators. Because I don't like the slash-and-burn approach of simply blocking access to our sites from swaths of IP addresses, I used a tool I've been using for years on my personal domains; pf and spamd (specifically, OpenBSD's pf and spamd). Because the email server is running an older (patched) version of FreeBSD, I didn't want to spend the time that would have been necessary to move the installation to OpenBSD so that I could run pf and spamd natively (yes, I realize there are ports for pf for FreeBSD, but I'm not going to recompile, nor do all the bs required to get that up and running - for more pragmatic reasons, anyway). We have an OpenBSD based bridge set up between our internal network (of machines with public IPs) to cut down on private network traffic out to our internet provider. (Even though they should be tossing the traffic, I've found more than one ISP whose routers happily pass private network traffic beyond your router.) I've never implemented spamd pf rules on a bridge and I was concerned as to how it was going to work. (I often get confused as to traffic flow direction and generic firewalling concepts.) With a little work and some queries on the openbsd-misc list, I found the solution and wanted to make note of it:

The rules that finally worked for pf.conf are:

# macros
filter_if="sis0"
pass_if="xl0"

mail_servers = "{ mailip1, mailip2, mailip3 }"
spamd_no_block = "{ relayip1, relayip2, relayip3 }"

table <spamd> persist
table <spamd-white> persist
table <spamd-pass> persist file "/var/db/spamd_whitelist"

priv_nets="{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"

# options
set loginterface $filter_if
set skip on { lo }

no rdr on $filter_if proto tcp from <spamd-pass> to $mail_servers port smtp
no rdr on $filter_if proto tcp from $spamd_no_block to 66.208.74.153 port smtp
rdr pass on egress inet proto tcp from <spamd> to 66.208.74.153 port smtp \
-> 127.0.0.1 port spamd
rdr pass on egress inet proto tcp from !<spamd-white> to 66.208.74.153 port smtp \
-> 127.0.0.1 port spamd
pass out quick route-to lo0 proto tcp from any to 127.0.0.1 port spamd

# block private traffic from going across the filter_if
block log on $filter_if from any to $priv_nets
block log on $filter_if from $priv_nets to any

The specific issues that I dealt with (and solved my dilemma of it not working) were: a) the bridge needed a real-world IP address assigned to one of the interfaces (up until today, it had only been assigned a private IP so that I could access it from a workstation within the network), b) the items in red needed to be added to the ruleset, and c) I added a rule to allow for certain IP addresses and ranges to have immediate access to the smtp daemon because they use the server to relay email.

I realize that c opens up a hole for abuse if a machine from one of those addresses becomes infected, but between smtp-auth being required for relay and the fact that the networks with that type of access are quite limited, it is a risk I am willing to take.I will admit, the items in red are those whose syntax I don't understand. I don't understand egress or why the route-to rule works like it does. I was pulling out my hair at the point when I finally happened across an entry in the OpenBSD archives that showed these rules and when they worked, I simply sighed a sigh of relief.Since activating the above rules, we have gone from 100+ bogus simultaneous smtp inbound connections to 2-3 at any given point in time. The whitelist is obviously working well because when I started this morning it had two entries in about 10 minutes and now it has a hundred or so. I randomly checked the IPs and they appear legitimate enough. The list of greylisted IPs is over 12000 - that is in under 3 hours for a server that handles mail for only 15 domains.

As far as setup of spamd is concerned, I didn't do any more than add the following to rc.conf.local:

spamd_flags=""
spamd_grey=YES
I love it when stuff just works and when the community behind that stuff like things to remain simple. I will be making an [albeit small] donation to the team today because this saved me days worth of work. I can continue to run a system, which aside from the spam issue, works just fine and doesn't deserve being tossed in the garbage heap. Not only did I save time, but the waste of another perfectly useful machine being sent to a landfill.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About

This page contains a single entry from the blog posted on November 12, 2007 2:14 PM.

The previous post in this blog was Leica M8 at Badger Game? (Football Photography).

The next post in this blog is USB drive Cradle from GeekStuff4u.com.

Many more can be found on the main index page or by looking through the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.