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!!

53 thoughts on “Setting Up SPF, SenderId, Domain Keys, and DKIM

  1. @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!

  2. 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

    • 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!

      • You can use the dkimproxy described above with Exchange. Just configure Exchange to use your proxy as the outgoing “smarthost” or “outbound server” or whatever the Exchange programmers decided to call it. (I’m assuming Exchange has the feature – if not, it is the only MTA on the planet that doesn’t.)

  3. 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

    • 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.

  4. Just a reminder for those stumbling upon this information:

    Domainkeys is in the meantime considered obsolete and SPF has serious downsides that many consider it broken and it receives little support nowadays.

    Thus the most sensible choice is to simply use dkim and ignore the rest. DKIM beeing mostly downward compatible with domainkeys and without the drawbacks of SPF should receive more and more support in the future. The latest exim versions now support it out of the box and the first comprehensive and understandable setup guids are appearing so that looks promising, as long as one keeps in mind that no single method will ever be the solution to spam. I receive some google-groups spam that is of course properly dkim signed for instance.

    • Yes, Domainkeys is the older version (more or less) of DKIM. Luckily when you implement DKIM using this guide you get Domainkeys for free, so why not:)

      I know there’s a lot of discussion regarding SPF versus SenderId versus… but I’m not aware of any SPF issues so severe that an outgoing mail server is better off not implementing it… Can you provide more info on that?

      Unless I’m mistaken, Microsoft (MSN, hotmail, etc…) still uses SenderId as the primary anti-spam measure, so unless they’ve switched entirely over to DKIM, I’m not sure I agree with ignoring everything other than DKIM. Supporting the four options here is pretty easy, and doesn’t take long to setup.

    • SPF may or may not provide benefits depending on your situation, but it has no downsides – except publishers who neglect basic sanity checking of their policy (many free tools available – including on this page), and idiot mail receivers who blindly check SPF (and reject on FAIL) in situations where it is undefined (like behind an MX or unlisted forwarder). If done according to spec, the worst SPF can do is provide no result.

  5. Hi All, could I please have a quick explanation. SPF is reasonably easty to set up as it’s done at domain level and the company managing the domain can set that up quickly. But I am confused regarding DKIM. Does the email marketing system need to add the dKIM signatures automatically into emails or will an email server/mta do this if it has the ability or both?
    Thanks.

    • Alex,

      whoever is sending the e-mails needs to add the DKIM header. This is usually done by having the server/mta send the mails through a DKIM proxy, which is the solution spelled out above.

      Does that help?

      Devon

  6. Thanks Devon, it does. But like a few other people in this thread, I am looking for a Microsoft based solution that will work with any Windows email server.

    Thanks.
    Alex.

  7. Thanks Devon for this helpful post.
    I want to let my registered users(whom I have their email addresses) to send their post to my website by just emailing it to let say x@foo.com.
    What actions should I take to prevent email spoofing and forgery?
    Is it enough to check the SPF? Should I limit them to famous email providers like yahoo and gmail?
    Is there any feasible and safe solution at all?
    I would appreciate if you advise me on that.

    Thanks,

    Al

    • Al,

      tough question. I’m sure you’re aware of the recent problems Posterous has had with this very issue: http://news.ycombinator.com/item?id=1441997

      My recommendation is to definitely enforce SPF/DKIM/etc… if the records exist, however this isn’t enough (and many folks may not have those technologies in place on their mail systems. I’d recommend either having unique and hard to guess addresses for each user, sending a reply e-mail with a confirmation link to confirm the action, or simply putting mailed entries in a moderation queue to be approved via a website by the user. I’m not sure what your whole plan is, and how much those changes might negatively impact the usability, but relying on mail headers for full identification is very risky

      Devon

      • Another clever option I heard was to have each user pick a secret word which has to be the first word in the subject of the e-mail. The secret word is of course removed from the post.

  8. Hi there. Do you need to have your own server or virtual server to do this? What about websites hosted on shared servers, ie CPANEL. I have setup domainkeys and SPF no problem, (but no DKIM). I guess I am asking is it possible to have a working DKIM setup in this situation?

    Thanks,

    • Dean,

      you should be able to do this on a virtual server, as long as you can install things (like the DKIM proxy). If it’s a control panel access only type deal, it might not be doable.

      Devon

  9. Pingback: March (Q)Mail Server Madness » ghidinelli.com

  10. I was just seeking this information for some time. After 6 hours of continuous Googleing, at last I got it in your website. I wonder what’s the lack of Google strategy that don’t rank this kind of informative sites in top of the list. Generally the top web sites are full of garbage.

  11. hello Devon,
    i am configure a mail server for bulk mailing. using postfix on centos with SPF and DKIM. problam is my server running on particular x.x.x.1 ip and hostname is abc.com. and my bulk mailing software running on particular x.x.x.2 ip and hostname is xyz.com. when i am sending mail xyz.com shows in header and mail goes to spam. now you tell me where i maintain SPF and DKIM record on abc.com or xyz.com. if any configuration need for server also tell me.

  12. ; <> DiG 9.7.0-P2-RedHat-9.7.0-10.P2.el5_8.1 <> indigitalplan.com
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48210
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;indigitalplan.com. IN A

    ;; ANSWER SECTION:
    indigitalplan.com. 1795 IN A 119.252.148.27

    ;; AUTHORITY SECTION:
    indigitalplan.com. 1795 IN NS ns2.rediffmailpro.com.
    indigitalplan.com. 1795 IN NS ns.rediffmailpro.com.

    ;; Query time: 3 msec
    ;; SERVER: 203.187.255.90#53(203.187.255.90)
    ;; WHEN: Wed Jul 11 18:19:56 2012
    ;; MSG SIZE rcvd: 100

    its pointing to wrong ip…hostname to ip is not resolving..showing wrong ip

  13. I have successful installed DKIM with Exim on Debian and have also SPF.

    Just to finish the task I would like to add also DomainKeys. Somebody wrote here that DKIM includes DomainKeys (more or less). But DomainKeys test failed. How can I include DomainKeys ?

  14. Hey Devon,

    Thanks for the great post and being so attentive with the Q&A. I’m trying to implement DKIM, but our enterprise software, Infusionsoft, sends our email – usually on a number of different servers. They’ve publicized that they support DKIM but I can’t find anyone in tech support who knows what it is. Do you have any experience with Infusionsoft with this issue and can you confirm if they do or do not support DKIM?

    Thanks!
    -Scott

  15. Hi, thanks for the very good article, I have a situation where I am sending emails from another server (domain 1) as domain 2 (on another server). I need it to be signed so it is not rejected or marked as spoof. How should I set up my keys? And which domain should be signed with which?
    I’d love any pointers, thanks.

    • Sean,

      the DKIM signature needs to be setup based on the domain of the From address of the email. The signing has two pieces, a signing proxy, running on domain1, and a public key in a TXT DNS entry in the DNS zone file of domain2 (assuming domain2 is used in the From address). Does that make sense?

      Devon

  16. Pingback: E-mail sent with postfix are marked as spam - Just just easy answers

  17. Is there anyone out there who has found a good tutorial on how to setup DKIM inside of cPanel? More specifically, where do I go to create my digital key?

    Thanks!

  18. So I’m having a little bit of trouble setting up DKIM on our server. I get to the part with TXT entry and it tells me to put
    selector1._domainkey IN TXT “k=rsa; t=s; p=MHwwDQYJK … OprwIDAQAB”

    I’m not sure how to enter that into my DNS provider’s TXT records. The options I get is
    Host TTL TEXT

    for the SPF record I put
    Host TTL TEXT
    @(none) 7200 v=spf1 a mx ?all

    That works fine, but I’m not sure how to put the DKIM TXT records in.

    • Tay,

      the hostname is the selector you choose and setup in your dkimproxy configs plus ._domainkey.yourhost.com. For instance mine is:

      ds_dkim._domainkey.digitalsanctuary.com.

      Then the TXT part is your public key: “k=rsa; t=s; p=MHwwDQYJK … OprwIDAQAB”

      Does that make sense?

      • I got here after googling around and getting nowhere about how to install both spf and dkim.

        I am in the process of setting up postfix/opendkim/milter-greylist to try and support both spf and dkim verification and dkim message signing on a replacement to my existing exim based mail server. Both are running Debian, although my new server is on a raspberry pi. I think I have the configuration at the server covered.

        The beginning of your article is quite explicit on how to set up the spf record in the DNS, but having read the article and all the comments, this seems to be the first place that you mention putting the DKIM public key in the DNS

        However, I am still confused. What do you put in the TXT record if you wish to support BOTH spf and dkim, can both go in the same TXT record together – if so how?

        It seems the spf record has quotes, the DKIM public key doesn’t. Is that correct?

        The reason I ask is that my DNS provider seems to only provide an interface for a single TXT entry in my dns zone file and I still haven’t found out even whether its permissible to have more than one generally.

        • The quotes/no-quotes thing is a red herring. Ignore that.

          The SPF ruleset goes into a TXT record of the root domain (blah.com) and tells recipients what mail servers are allowed to send mail from addresses at this domain.

          The DKIM public key goes into a TXT record of a sub-domain (ds_dkim._domainkey.blah.com) and is used to verify that that mail server actually sent the email itself.

          They are definitely different hostname records in the DNS zone file. They can often be on different domains entirely in real life (you have a 3rd party mail system sending mail for your domain).

          Does that make sense?

  19. Pingback: How I setup my Digital Ocean droplet with ZPanel and configured the DKIM and SPF records - Ben Powell

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>