4

I'm trying to set up a mail server using OpenBSD, OpenSMTPD, spamd, and pf. The first problem I've encountered is that many large webmail providers - like Gmail - will retry delivery from a different server with a different IP address, making it hard for them to move pass the greylist into the whitelist. I've written a script that I thought might help by performing a PTR request on the IP of GREY tuples and comparing the resulting domain to a manually maintained list of domains I trust.

  • First, is this a reasonable approach? What problems might I encounter?
  • Second, why don't the GREY records disappear from spamdb after I've whitelisted them via spamdb -a X.X.X.X and they then show up as a WHITE record? Once they're whitelisted, it should be for the entire IP and I imagine the GREY tuple is obsolete by that point. What is the typical life cycle of these spamdb tuples? I've seen some disappear, some duplicated (GREY then WHITE), etc.
  • Third, should I instead be writing these whitelisted IPs from my script to a file, then loading that file as a pf table which passes connections from those trusted domains directly to smtpd? In other words, rather than going through spamd and whitelisting these IPs with spamdb -a which then get added to the <spamd-white> pf table, should I just bypass spamdb, leaving them greylisted, and go directly to some pf whitelist table.

Here's the draft script I wrote to be run periodically to automatically whitelist trusted domains that have been encountered and greylisted:

#!/bin/sh

set -A whitelist \
    amazon.com \
    google.com

spamdb | while read line
do
    IFS="|"
    set -A fields $line
    status=${fields[0]}
    if [[ $status = "GREY" ]]
    then
        ip=${fields[1]}
        ptr=`host ${ip}`
        IFS="."
        set -A tokens $ptr
        size=${#tokens[*]}
        domain="${tokens[size-2]}.${tokens[size-1]}"
        found=false
        IFS=" "
        for whitelisted in ${whitelist[@]}
        do
            if [[ $domain = $whitelisted ]]
            then
                found=true
            fi
        done
        if (($found))
        then
            echo "+ $ip ($domain) has been whitelisted"
            spamdb -a "$ip"                                                                                                                                                                                
        else
            echo "- $ip ($domain) is unrecognized"
        fi
    fi
done

exit 0

1 Answer 1

2
  • It depends™:

    • Keep in mind that DNS PTR records can be false -- just because you get .google.com as part of the PTR, doesn't mean that it's Google that's controlling the IP address in question. To be sure, you might also want to do a forward resolution prior to taking any action (although, to be fair, impact in the case of greylisting will be very limited, as anyone capable of modifying PTR will likely also be capable of successfully bypassing your greylisting in the first place).
    • Handling internet input from sh might not be the best approach.
    • Additionally, you'll spend quite a bit of time doing these resolutions, some of which may timeout, so, you have to make sure to not run this script too often, especially if another copy of it is already running.
  • Feel free to take a look at http://BXR.SU/OpenBSD/usr.sbin/spamdb/spamdb.c#dbupdate. The code doesn't appear to have been written to be too readable, though.

  • I think either approach should be fine. It'll probably be easier to just use spamdb to maintain this automated whitelist, as it'll take care about maintenance, expiration and a little bit of statistics. However, if you do maintain your own list, you have the added benefit of doing a network-wide whitelisting.

Also, if you want to have this limited just to Google, Amazon, and other providers that keep correct SPF records, consider that you might go straight ahead of the game by getting all of their IP-addresses at once, even through automated means (with the help of SPF, for example). See https://support.google.com/a/answer/60764. You can most likely even use an existing SPF library to get a list of all of these IP addresses.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .