Using OpenBSD's spamd as a greylist mail filter
I have an exchange server that doesn't do a very good job of filtering spam. The server sits
inside the firewall/NAT and is reached through port-forwarding. I wanted to stick a device in between the
Exchange server and the firewall to filter spam, so I needed a device that would work as a bridge and would not require any changes to my firewall or mail server.
Spamd works with the pf firewall to redirect smtp traffic that is passing through the bridge to the
spamd process. Once a server's IP address is added to the whitelist by spamd, traffic from that
machine passes through the bridge unfiltered. Outbound SMTP traffic is also unfiltered. The users
are unaffected because Microsoft Outlook doesn't use SMTP to inject mail into the server, and so
the only thing that should be talking to port 25 (SMTP) should be other mail servers.
I have no idea what I'm doing, although this has worked for me. Remember: I'm not a BSD expert. I only interview them.
- Install OpenBSD
- Full install details can be found at http://www.openbsd.org/faq/faq4.html#Install
- Defaults are always in square brackets, such as [yes]. Hit Enter to accept them.
- Download the cd39.iso boot cd from http://openbsd.secsup.org/3.9/i386/ or use your favorite mirror. This install CD is only a couple megs.
- Boot to the CD, do the install, use the entire disk.
- When you are in the disk partitioner, you can type "d a" to delete the "a" partition, then "a b" to add the "b" swap partition, accept defaults and make it "256M" in size, then "a a" to add the "a" partition and accept the defaults, although you should specify "/" as the mount point. You can "w" to write the partion info, and then "q" to leave.
- When you configure your ethernet card, I used "dhcp" and accepted all the defaults. If you plan on using a static IP, make sure you have an IP, Netmask, and DNS servers.
- To install the sets, choose "ftp", list the mirrors, and use the mirror number to install. Accept the default list of sets. Remember to purchase a CD if this works for you. Think about how much a commercial anti-spam product costs.
- When done, take out the install CD and reboot.
- Add the Second Ethernet Card and Configure Bridge
- Your first card that has an IP address is considered your "egress" card and faces the internet. The new card is connected to the server that you want to protect.
- After the second card is installed and the machine boots, type ifconfig to see the names of the ethernet cards.
- Cards are configured using a file called /etc/hostname.(name of card) such as /etc/hostname.rl0
- Your first card will have configuration information in it already. "man hostname.if" will give you more information.
- If your second card is rl1, then create /etc/hostname.rl1 with just the word "up" in it.
- You can then create a bridge by adding the following to /etc/bridgename.bridge0
- Type "sh /etc/netstart" to restart your networking, or "reboot" if you want. Test your bridge by placing it in between your workstation and your network.You may need to use a cross-over cable. Typing "ifconfig bridge0 down" followed by "ifconfig bridge0 up" should get things going if the bridge doesn't seem to want to pass any traffic.
- Configure the packet filter and spamd
- Edit /etc/rc.conf.local and add the follwing lines
- Move the default firewall rules by typing "mv /etc/pf.conf /etc/pf.conf.default"
- Move the default spamd rules by typing "mv /etc/spamd.conf /etc/spamd.conf.default". You will get an error on boot that the file can't be opened, but I don't use it because I'm only interested in greylisting and don't trust Real Time Blackhole Lists like spews. This is the wrong way to do it.
- Create /etc/pf.conf with the following lines:
## Spamd Stuff
# Local Whitelist File
table <my-white> persist file "/etc/whitelist"
# Table that spamd updates
table <spamd-white> persist
# If not on whitelist, redirect to spamd
no rdr proto tcp from <my-white> to any
rdr pass on egress inet proto tcp from !<spamd-white> to any \
port smtp -> 127.0.0.1 port spamd
# Because this is a bridge, explicit route to this machine
pass out route-to lo0 proto tcp from any to 127.0.0.1 port spamd
## Spamlogd Stuff
# Keep whitelist hosts from expiring
pass in log inet proto tcp from <spamd-white> to any \
port smtp keep state
# Eventually I'll have a line to whitelist servers that my server talks to.
- Reboot and watch the magic happen.
- Checking the status
- "ps ax" should show spamd and friends
- "pfctl -s state" should show connections that are being redirected
- "tail -f /var/log/daemon" should show you a running log of connections
- "spamdb" will show you the greylist database
- "pfctl -t spamd-white -T show" should show you the contents of the spamd-white packet filter table.
- Because spamlogd logs with debug, you won't see anything from it in /var/log/daemon unless you modify /etc/syslog.conf to show debug level messages.
- You may want to edit /etc/newsyslog.conf and increase the size of the daemon log file. I put mine at 500 which for my load keeps a couple days of logs.
- I modified the spamd_flags in /etc/rc.conf.local to be "-v -G 5:4:864" because yahoo was doing a retry every 7 minutes and not getting through.
Later I put sendmail in the middle to see if I could solve some ESMTP problems
with Exchange. I was getting some incoming timeouts, which might be related to
the BDAT verb that is advertised through the CHUNKING verb in exchange server.
I guess some email filters don't understand BDAT, so they block it in the
middle of the SMTP session. I followed MS Article 257569 to try to turn off
CHUNKING, but I was tired of waiting for it to take effect.
I set up sendmail to just receive mail for my domain and bounce it through to
the Exchange server. This is done by setting the normal sendmail flags in
/etc/rc.conf.local, and then adding one line to /etc/mailertable and
/etc/access. You add "mydomain.tld esmtp:[exchange.server.tld]" to the
mailertable, and add "mydomain.tld RELAY" to access table. I then
asked our firewall to forward SMTP connections to the spamd box.
Another quick script:
echo -n "IP address of host:"
echo "Appending $host to $whitelist_file"
echo $host >> $whitelist_file
echo "Promoting $host to a WHITE entry in spamdb"
spamdb -a $host
echo "Restarting pf..."
pfctl -d ; pfctl -e -f $pf_file