Spamfighting: mail server configuration

In part 1 of this series, I relayed a bit of my story about my use of SPF, DKIM, and DMARC to try to reduce the spam being sent as if from my personal domain, while increasing the odds that legitimate mail from my domain gets through.

In this part, I describe how these are actually implemented in my case.

First, let me describe my email setup. I have one cloud-hosted server,, through which all authentic * email is sent. Senders may be either local to this server (such as postmaster@ which sends the DMARC reports to other mail servers), or may be family members who use a hosted email service (as it happens, all use GMail) as their Mail User Agent. Users make an authenticated connection to, which then DKIM-signs the messages and sends them on toward their destination MX server. These users may also be subscribed to various mailing lists which would break (fail to get their legitimate message through to the expected receivers) if SPF policy were anything except softfail.

As such, my SPF record looks like:
@ 7200 IN TXT "v=spf1 a mx ~all"

Outbound, user-authenticated mail from * should be treated differently than inbound mail. Outbound mail requires only a DKIM milter to sign each message. Messages are signed with a DKIM key, published in my DNS: 7200 IN TXT "v=DKIM1\; k=rsa\; s=email\; p=(some nice long hex string)"

I publish a DMARC DNS record so I can get reports back from DMARC-compliant servers. 7200 IN TXT "v=DMARC1\; p=none\;\;\;
adkim=r\; aspf=r\; rf=afrf "

Inbound mail to * should pass each message through an SPF milter which adds a Received-SPF header, a DKIM milter to check the validity of a DKIM-signed message which adds an Authentication-Results header, and the DMARC milter which decides what to do based on the results of these other two headers, and sends results to DMARC senders. runs CentOS 6.x, sendmail, and a variety of milters. On outbound mail, it runs opendkim. On inbound mail, it runs smf-spf, opendkim, and opendmarc, before sending it on to its final destination. My file is configured as such to allow the different milters to run depending on direction – outbound or inbound:

FEATURE(`no_default_msa', `dnl')dnl
DAEMON_OPTIONS(`Port=submission, M=Ea, Name=MSA, Family=inet6, InputMailFilters=opendkim')dnl
DAEMON_OPTIONS(`Port=smtp,Name=MTA, Family=inet6')dnl
define(`confMILTER_MACROS_HELO', confMILTER_MACROS_HELO`, {verify}')dnl
INPUT_MAIL_FILTER(`smf-spf', `S=inet:8890@, T=S:30s;R:1m')dnl
INPUT_MAIL_FILTER(`opendkim', `S=inet:8891@')dnl
INPUT_MAIL_FILTER(`opendmarc', `S=inet:8893@')dnl

Why do the milters listen on a local TCP socket, instead of a UNIX domain socket? Simply, they don’t yet have SELinux policies in place that let them use a domain socket. Once these packages are properly reviewed and included in Fedora/EPEL, we will adjust the listening port to be a domain socket.

Of these milters, opendkim and opendmarc seem to be properly maintained still. smf-spf, for its whole ~1000 lines of code, has been largely untouched since 2005, and its maintainer seems to have
completely fallen off the Internet. All my attempts to find a valid address for him have failed. There are a variety of other SPF filters, the most popular of which is python-postfix-policyd-spf – which as the name implies is postfix-specific, and as I noted, I’m not running postfix. Call me lazy, but sendmail works well enough for me at present.

These milters are currently under review (smf-spf, libspf2, opendmarc) in Fedora and will eventually land in the EPEL repositories as well. opendkim is already in EPEL.

If you are using SPF, DKIM, and DMARC, what does your configuration look like? Please leave a comment below.

2 thoughts on “Spamfighting: mail server configuration

  1. Very late note: if you have any PayPal accounts you’ll want to inherit PayPal’s SPF policy, as PayPal ‘helpfully’sends mail as you via their servers when you pay for something. Figured that one out with the help of dmarcian.

    • Adam, thanks for the heads up. I use paypal very infrequently, I’m not sure how much I’m going to care. I don’t know if the “10 DNS lookups” rule is enforced for SPF, but paypal uses 5, google uses 4. I can rewrite mine to be an IP address, include those two, and I’m almost out of requests permitted. I did use paypal just yesterday – I’ll watch dmarcian to see if it appears in the logs.

Comments are closed.