Avoiding the SPAM Folder – DKIM

In my last post, I mentioned that after the public launch of HelpEncourage.Me, many of our emails were being sent to the SPAM folder by the big three (Google, Yahoo, and Hotmail). 

The first step I took to resolve this issue was adding an SPF record to authorize mail servers to send email on behalf of the HelpEncourage.Me domain.  This helps prevent spoofing, since it is trivial to set whatever domain you like on your outgoing mail.

Unfortunately, implementing the SPF record by itself was not enough.

Enter DomainKeys Identified Mail

With the SPF record correctly authorizing our outgoing mail server, and the messages successfully passing the “SPAM” content test, my only remaining option before moving to one of the dedicated mail-sending services was to implement DomainKeys Identified Mail (DKIM).

At its core, DKIM is a message-signing protocol that uses public-key cryptography to verify that a message is coming from a given domain (and has not been tampered with).  It does this by creating an encrypted hash of the message contents (both the headers and body) and appending it to the message via a “DKIM-Signature” header.  The recipient of a message can then verify the message content and sender by decrypting the message hash using the associated domain’s public key.

Generating a private key

The first step in implementing DKIM is to generate a public and private key which can be used to encrypt and decrypt the message hash.  Since I am on Windows, the simplest way to generate a private key is to use the Win32 OpenSSL tool.  You can also check out openssl.org for more information on generating a key.

Once OpenSSL is installed, generating a key is straightforward.  Simply navigate to the OpenSSL executable directory on a command line and type:

openssl genrsa –out private.key 1024

This will generate a 1024-bit private key file called “private.key”.  The size of the key is specified in bits at the end of the command.  The “genrsa” option instructs OpenSSL to generate a RSA key.  For most purposes, 1024-bits should be sufficient and is the recommended key size for “corporate use” according to RSA Laboratories.

Generating a public key from the private key

Once you have a private key, you need to retrieve the public key.  Again, OpenSSL makes this process rather painless:

openssl rsa –in private.key -out public.key -pubout

Note that we no longer want to generate a key, so we use the “rsa” option instead of “genrsa”.  Since we aren’t generating a key, we tell it to use the private key we generated earlier, create a new key file called “public.key”.  The “pubout” option tells OpenSSL to only output the public portion of the key.

Creating a DKIM record

Now that we have a public and private key, we can create the appropriate DKIM records in DNS.  DKIM records consist of two TXT records.  The first record has a name of “_domainkey.<domain>” and specifies the policy for the domain given by <domain>:

_domainkey.helpencourage.me     TXT     o=~\; r=postmaster@helpencourage.me

For our purposes, the important options in this record are “o=~” (note the tilde) and “r=postmaster@helpencourage.me”.  The first option specifies that some emails from this domain will be signed.  If you want to specify that all emails will be signed, use a minus (“-“) instead of a tilde.  The second option specifies the “responsible email address”.

Once we have set the policy for our domain, we need to publish the public key.  Again, we create a TXT record, but this time the name will have a <selector> prepended to it (“<selector>._domainkey.<domain>”).

The <selector> is just a unique identifier that can be used to reference the correct record.  For example, for HelpEncourage.Me, we use “p1” as our selector (short and easy to remember):

p1._domainkey.helpencourage.me     TXT     k=rsa\; p=...PUBLIC_KEY...

There are two important options for this record.  The first, “k=rsa”, specifies that we are using an RSA key.  Currently this is the only algorithm supported and this option can be omitted, but I always like to be thorough in case it changes in the future.  The second option is the reason for the record and is required to successfully use DKIM.  It specifies the public key to use to verify the message signature, and takes the form “p=<PUBLIC KEY>”.

To get the appropriate value for this option, you must use the public key file we created above and copy all the text between “—–BEGIN PUBLIC KEY—–“ and “—–END PUBLIC KEY—–“.  Do not include the delimiters.

Signing your messages

Once you have setup you DNS records, you can start signing your email messages.  This is usually done at the server level, and if your SMTP server does not support signing your message, you may be in for some additional work.  Fortunately for us, our server supports DKIM signing, and we could enable it via the control panel.  All we needed to do was upload our private key and point the SMTP server to it.

Verifying your signature

Fortunately, many of the same tools we used to verify our SPF record can be used to verify that you have correctly setup DKIM signing.  Notably, the Port25 verifier provides a wealth of verification information, and Google makes available all sorts of information via the message headers.