BSD DevCenter
oreilly.comSafari Books Online.Conferences.


Greylisting with PF
Pages: 1, 2, 3, 4, 5, 6, 7

Known Good Mailers that Have Trouble with Greylisting

There are some problems with greylisting. Be sure to read the whitelisting section at I have taken its whitelist and added it to my whitelist (/usr/local/etc/spamd-mywhite). Also in that file are my own mailservers and any special places which are immune to any spamd intervention.

Directing Things Around the Tarpit

I added a few rules to /etc/pf.rules:

  1. table <spamd> persist
  2. table <spamd-white> persist
  3. table <spamd-mywhite> persist file "/usr/local/etc/spamd-mywhite"
  4. scrub in all
  5. # redirect to spamd
  6. rdr pass inet proto tcp from <spamd-white> to $external_addr port smtp -> port smtp
  7. rdr pass inet proto tcp from <spamd> to $external_addr port smtp -> port spamd
  8. rdr pass inet proto tcp from !<spamd-mywhite> to $external_addr port smtp -> port spamd
  9. # mail!
  10. pass in log inet proto tcp from any to $external_addr port smtp flags S/SA synproxy state
  11. pass out log inet proto tcp from $external_addr to any port smtp flags S/SA synproxy state

That's not too difficult to digest:

  • 1 declares the spamd table. Everyone in this table redirects to spamd. spamd-setup maintains the contents of this table; it runs from a cronjob.
  • 2 declares the whitelist table of locations that have successfully negotiated spamd's greylisting efforts. spamlogd maintains this table.
  • 3 declares a table of locations to exempt from greylisting. I maintain this table manually.
  • 6 makes everyone in the whitelist go straight to the mail server.
  • 7 makes everyone on the greylist go straight to spamd.
  • 8 forces everyone not on my whitelist to talk to spamd.
  • 10-11 feed data to pflog, which spamlogd will monitor and use to update the spamd table.

Note that the use of pass on the RDR rules is significant. Here's an explanation from the OpenBSD PF FAQ:

NAT and Packet Filtering

NOTE: Translated packets must still pass through the filter engine and will be blocked or passed based on the filter rules that have been defined. The only exception to this rule is when the pass keyword is used within the nat rule. This will cause the NATed packets to pass right through the filtering engine.

Also be aware that since translation occurs before filtering, the filter engine will see the translated packet with the translated IP address and port as outlined in How NAT Works.

In short, if you're on a whitelist (either spamd's whitelist or my whitelist), you go straight to the mail server. Everyone else goes to spamd.

On your first visit to spamd, you are asked to come back later. If you do, then you're asked to try again and are added to the whitelist.

By the way, after making changes to /usr/local/etc/spamd-mywhite, tell PF to notice the changes:

$ pfctl -t spamd-mywhite -T replace -f /usr/local/etc/spamd-mywhite
No ALTQ support in kernel
ALTQ related functions disabled
24 addresses added.
39 addresses deleted.

Starting spamd

To start spamd manually:

/usr/local/etc/rc.d/pfspamd start

The first time you run spamd, it may take 10 or 20 seconds for it to come back to the command line. Be patient.

If you get the error message:

 # /usr/local/etc/rc.d/pfspamd start
Starting pfspamd.
spamd-setup: Can't find "all" in spamd config: No such file or directory

...then you probably forgot to create /usr/local/etc/spamd.conf or removed its all section.

Also start pflogd, so that the logging works:

/etc/rc.d/pflog start

After successfully starting spamd, you should see logs like:

# ps auwx | grep pf 
nobody  94067 ?? Ss 11:20AM 0:00.03 spamd: (pf <spamd-white> update) (spamd)
root    94282 ?? Is 11:31AM 0:00.00 pflogd: [priv] (pflogd)
_pflogd 94286 ?? S  11:31AM 0:00.00 pflogd: [running] -s 116 -f /var/log/pflog (pflogd)

I have removed some of the columns from this display to make it fit better on the page.

On a side note, I'd like to see spamd running as something other than nobody. Perhaps I'll work on that later.

spamd-setup maintains the <spamd> table shown on line 1 of the PF rule set found later in this article. To view the contents of this table:

pfctl -t spamd -T show

Pages: 1, 2, 3, 4, 5, 6, 7

Next Pagearrow

Sponsored by: