Site Network: Personal | Professional | Photography

Technical Blog

This blog will contain content related to Java, Seam, Security, my sites and projects, as well as other technical subjects I am interested in.

Comments and questions are welcome!

Setting Up SPF, SenderId, Domain Keys, and DKIM

If you run a mail server, and if you hate spam, you should setup your mail server to make use of all the best anti-spam tools available. There are two sides to spam, sending and receiving.

On the receiving side, you have things like blacklists, spamassassin, bayesian filtering, and lots more. I’ll probably cover this side of things in greater depth in another post.

On the sending side, first and foremost, you have to ensure your server is not acting as an open relay, and allowing spam to be sent through it. After that’s done, you want to be sure that e-mail you send isn’t flagged as spam by people receiving it. And, being a good e-mail citizen, you you want to support the anti-spam standards that are out there.

There are four primary standards for verifying senders and servers.

Sender Policy Framework (SPF) – from their FAQ:

Sender Policy Framework (SPF) is an attempt to control forged e-mail. SPF is not directly about stopping spam – junk email. It is about giving domain owners a way to say which mail sources are legitimate for their domain and which ones aren’t. While not all spam is forged, virtually all forgeries are spam. SPF is not anti-spam in the same way that flour is not food: it is part of the solution.

SenderId – a Microsoft technology which is very similar to SPF:

The Sender ID framework, developed jointly by Microsoft and industry partners, addresses a key part of the spam problem: the difficulty of verifying a sender’s identity.

DomainKeys – from Wikipedia:

DomainKeys is an e-mail authentication system designed to verify the DNS domain of an e-mail sender and the message integrity.

DKIM – an evolved form of DomainKeys, from Wikipedia:

DKIM uses public-key cryptography to allow the sender to electronically sign legitimate emails in a way that can be verified by recipients. Prominent email service providers implementing DKIM (or its slightly different predecessor, DomainKeys) include Yahoo and Gmail. Any mail from these domains should carry a DKIM signature, and if the recipient knows this, they can discard mail that hasn’t been signed, or that has an invalid signature.

SenderId is primarily used by Microsoft mail services like Hotmail/MSN, while DomainKeys and DKIM are primarily used by Yahoo. SPF is used by many mail services.

I’m going to walk you through setting up these anti-spam technologies. I will be setting them up for my domain, digitalsanctuary.com, and using my mail server, which is postfix running on Debian. Your setup and requirements may vary.

Let’s start with SPF. First, you need generate an SPF record for your domain(s), that essentially lists what mail servers are allowed to send mail from that domain. The easiest way to set up the SPF record is with a tool, like this online wizard.

First, I type in my domain name, and press the “Begin” button. The setup for digitalsanctuary.com is actually very simple. I only run one mail server. It runs on the same IP as my DNS A record for digitalsanctuary.com, and it’s the MX record for the domain as well. I don’t send e-mail through other mail servers. So my SPF record looks like this:

“v=spf1 a mx ~all”

Which says that mail from @digitalsanctuary.com can only come from the A or MX record IP addresses for the digitalsanctuary.com domain. Using the wizard you can setup your own domain SPF tuned to your needs. Once you have the record, you need to add it as a TXT entry in your DNS. Instructions are on the lower part of the SPF wizard I pointed you to. I use SoftLayer’s DNS servers, and on their web admin, I had to enter a “@” in the NAME field for the record for it to work correctly. Once that’s done, you can verify that it shows up correctly using a DNS query:

Motoko:~ modoc$ dig digitalsanctuary.com TXT

; <<>> DiG 9.4.2-P2 <<>> digitalsanctuary.com TXT
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36859
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;digitalsanctuary.com. IN TXT

;; ANSWER SECTION:
digitalsanctuary.com. 796 IN TXT "v=spf1 a mx -all"

;; Query time: 8 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Sun Feb 22 22:40:48 2009
;; MSG SIZE rcvd: 67

If you see your SPF record showing up in the Answer Section, then it should be working.

You can further test this by sending e-mail to check-auth@verifier.port25.com which will send you a reply with a detailed breakdown of various spam checks.

The reply at this point, should look like this:

Summary of Results
==========================================================
SPF check: pass
DomainKeys check: neutral
DKIM check: neutral
Sender-ID check: pass
SpamAssassin check: ham

There’s the SPF check pass, and wait! There’s also a Sender-ID check pass. How did that happen? SenderId is very similar to SPF. You can read about the differences here (be aware that the openspf folks have a very specific view point on the topic). Essentially they use the same DNS record syntax, and both systems are used to check the validity of the sending server based on who’s sending it, however they match who’s sending the mail at different layers of the SMTP stack. SPF uses the “MAIL FROM” data from the “envelope” layer which is passed as a header value during the SMTP communication. SenderId instead uses the “best” address from the list of address headers in the message itself. If you aren’t a SMTP expert, that sounds pretty confusing. Luckily for most of you, the difference really doesn’t matter. Your MAIL FROM envelope value, and the From address header, will typically be the same. If your outgoing mail system is more complex than this, then you’re likely enough of an SMTP expert to understand the difference, and setup a separate SenderId DNS record. For the rest of us, we’ve just killed two birds with one stone.

At this point you’ll probably want to register your SPF record as your SenderId record with Microsoft. You can do that here: https://support.msn.com/eform.aspx?productKey=senderid&page=support_senderid_options_form_byemail&ct=eformts&scrx=1.

Next, let’s tackle DKIM. We get another two for one deal here, since DKIM is the evolution of DomainKeys. I recommend using this guide to install DKIMProxy. You need to install a number of Perl modules, listed on that page, and I suggest using CPAN to do so. While CPAN isn’t perfect, it does handle a lot of the dependancies for you.

You basically need to install the following Perl modules:

  • Crypt::OpenSSL::RSA
  • Digest::SHA
  • Digest::SHA1
  • Error
  • Mail::Address
  • MIME::Base64
  • Net::DNS
  • Net::Server
  • Mail::DKIM

Then you’ll need to download the DKIMProxy software, I used version 1.1. Follow the build instructions in the guide I linked to above. Once it’s built, you continue to follow the guide and create your public and private keys. Then add the public key into the DNS for your domain. Then, instead of passing everything in as arguments to dkimproxy.out, I go into this directory (assuming you used the install location in the guide): /usr/local/dkimproxy/etc/ and copy dkimproxy_out.conf.example to dkimproxy_out.conf. Then edit that file and setup your keyfile location, domain, and other changes if needed.

Assuming you copied over the example control script into /etc/init.d/, you can test your setup and start dkimproxy, by typing: /etc/init.d/dkimproxy start

Assuming it starts up cleanly, you’re ready to configure Postfix to use dkimproxy to sign outgoing messages. You may currently be sending mail to your mail sever on port 25, but we can’t simply sign all messages delivered to port 25, since that’s where all your incoming mail arrives as well. So we’re going to setup postfix to listen of port 587 as well. When we send outgoing e-mail, it will go to port 587, and then will be run through the dkimproxy filter to be signed, before being sent out.

Use this guide: Setting up the outbound proxy with Postfix to set things up. Once you’ve configured postfix, reload the postfix configuration.

Now you’ll want to ensure that your mail client is pointed to port 587 instead of port 25.

Next, send another test e-mail to check-auth@verifier.port25.com. Your reply should look like this:

Summary of Results
==========================================================
SPF check: pass
DomainKeys check: pass
DKIM check: pass
Sender-ID check: pass
SpamAssassin check: ham

If it looks like that, then you’re all set! You’ve successfully implemented the four major anti-spam mail sending standards. Congratulations!!

12 Responses to “Setting Up SPF, SenderId, Domain Keys, and DKIM”

  1. Erick says:

    Any way of doing this with Exim instead of Postfix?

  2. Devon says:

    @Erick: almost certainly, unfortunately I don’t use Exim so I can’t really help…. If you do figure it out, it would be great if you can post the how to, or at least a link to it, here. Thanks!

  3. sileNT says:

    I explained here how to set up Exim with DKIMproxy for DKIM and DOmainKeys signing:

    http://blog.wpkg.org/2009/03/28/setting-up-dkimproxy-with-exim-for-dkim-and-domainkeys-signing/

  4. Michael says:

    Anyone know of a free windows version?

  5. Michael says:

    as a smtp smarthost or edge protection?

  6. LM says:

    Spammers seem to “like” our domain and love to “spoof” our address. As a result I am constantly looking for ways to strengthen authentication and verification of our mail server so that it cant be forged.

    I have tried using SPF and I would like to implement DKIM/Domain keys but finding info is like pulling teeth. Is there either a step by step guide or Open source\freeware plugin that will work with Exchange 2003\2007?

    What is the best freeware Whitelist\verified senders list? I have tried one by one with the big guys but it is really a pain.
    Thanks

    • Devon says:

      LM:

      I’m sorry, but I can’t help with Exchange at all, maybe another reader can. Or you could switch to Postfix? :)

      I don’t know of many worthwhile free whitelists. Most of the major mail providers use an in-house list and/or a paid list (like: http://www.goodmailsystems.com/). With Yahoo and MSN you can register yourself as a sender, which helps. If you find any other good solutions, let me know!

  7. SRN Soren says:

    In what DNS record should the DKIM public key published? will it also be inside of the TXT record?

    My understanding is that both spf and DKIM uses the TXT record, is this correct? Can someone give an example of a TXT record value after the SPF and DKIM were configured.

    Thanks

    • Devon says:

      SRN Soren: the DKIM public key will go in a special TXT entry for the domain of the mail server. THe SPF record goes in the default TXT record of the from addresses’ domain name.

      For example, for example.com you might have an SPF record as TXT record for example.com:

      TXT “v=spf1 a mx -all”

      And a DKIM TXT record setup with a hostname exam_dkim._domainkey (that name has to match what’s in your DKIM outgoing proxy signing configuration) in your example.com zone file might look like:

      TXT k=rsa; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCZQqGQWlhdqNvyJuekGhPQ51vlDIe2lPvTMy1BNCGXe97swc5HbpR1D0xsBvT3dY0EBN7bnHya/2KA3mQv8IZLVIeHCc7pWq1q5MN95Vz7MS1XT/+8O7gSkdmiB7vUdGbeUlxs5SQ3fhSGYsp2PFbEAub+I4fm1UyseEyq65jzQIDAQAB

      Does that make sense? Essentially the SPF record is a record for the domain of the from e-mail address saying “these are the servers that are allowed to send e-mail with a from address of this domain”. The DKIM record is a public key, part of a public/private encryption key pain, used to signed outgoing e-mail by a mail server which says “I, the mail server named mymail.example.com, really did send this e-mail”. In fact in some instances they will be on totally different domains. For instance example.com could delegate out-going mail sending to a 3rd party provider. So the SPF record, living at example.com’s DNS would list supermail.mailer.com as a valid sending server for @example.com mail. The DKIM record would be hosted at some_identifier._domainkey.mailer.com, and would sign the e-mail going out.

Leave a Reply