DKIM is a technique based on Yahoo!’s DomainKey. Some may say that it look alike SPF (Sender Policy Framework), but the two is different. DKIM is authenticating the email sent by checking the signature againts the domain’s public key. On the contrary, SPF check the MTA (mail server) that sends the email againsts the domain’s list of MTA. For the simplicity, let’s say that the sending domain is UI and the receiving domain is GMail, so DKIM works like this:

  1. User foo send an email
  2. The UI mailserver signed the email and send it to GMail mailserver
  3. GMail then querying the DNS and search for the public key for the sending domain.
  4. After that, GMail checks signature and the data.
  5. If it is alright, then GMail deliver the message to the recipient’s mailbox.

DKIM uses two encyption algorithms: RSA-1 (or just RSA) or RSA256. Those are public and private key pair authentication. The magic is what get encrypted by the private key can only be decrypted by public key and vice versa. But, you can’t decrypt using the same key that used to encrypt the data.

This mechanism is differ from SPF. For mailserver that implements SPF, it would just ask the DNS about a list of legal mailserver that have the right to send email originating from that particular domain.

Let’s us set Postfix to use DKIM. I assume that the mailserver is already functional and running.

There are two applications in Debian repository that serve the same purpose. The first is DKIM-Proxy which is a stand alone service that get injected and then inject back. It would run two processes which one would handle incoming traffic (verifying the email) and the later would do the signing. Both have their own socket to communicate with the mailserver.

The second is DKIM-Milter (or dkim-filter as Debian named it). It uses Sendmail‘s Milter protocol. So, it would run just like a plugin in Postfix. From my experimentation, I choose this because of the convinience for me. But, who knows you would choose the other.

Now, let’s install DKIM-Milter:

# apt-get install dkim-filter

The installation includes dkim-genkey tool to generate configurations including the DNS setting. Use the tool to generate DNS entry and private key:

# dkim-genkey -d -s mail

The parameter:

  • -d means we would like to sign mails from
  • -s mail sets the selector’s name is “mail“. Selector is an entry in DNS that holds public key that will be used by other mail servers to verify the signature signed by origin mail server. Well, I decide not to define this further to simplify things. You could google it.

The command will generate two files: mail.txt which contains DNS entry and mail.private which is the private key that would be used to sign the letter. Here’s the example of mail.txt:

mail._domainkey IN TXT "v=DKIM1; g=*; k=rsa; p=MIGfMA0GCS...AB" ; ----- DKIM mail for

The public key entry is being cut to save space pertaining aesthetic aspect in this blog post. I would put the private key into /etc/dkim directory. The directory is non-existence, so we have to create it first.


# mkdir /etc/dkim
# mv mail.private /etc/dkim

Now, the DNS part. I would refined the entry to add “t=y” and remove the comments. I’m also appending our domain after _domainkey (watch for the dot after “id”). So, it would be just like this: IN TXT "v=DKIM1; g=*; t=y; k=rsa; p=MIGfMA0GCS...AB"

And put that in your DNS database and reload it.

Default installation do not run the DKIM-Milter. We need to set the DKIM-Milter in order to run. First, edit /etc/dkim-filter.conf file. Here’s the relevant things that I’ve change to suite my need: (just find the line)

KeyFile     /etc/dkim/mail.private
Selector    mail
Mode        sv
Amazing thing about Debian is it has a great documentation style, so you can read the comments on the configuration file for further information. To have a functional DKIM-Milter, edit /etc/default/dkim-filter file to set where it should listen/respond to. To simplify things, I choose to have network socket than the UNIX socket. Unix socket slightly better in performance, but it must be set so that the chrooted Postfix and the DKIM-Milter service can both read and write it. I uncomment this:
SOCKET="inet:12345@localhost" # listen on loopback on port 12345
Last piece that should be configured is the Postfix configuration to use the DKIM-Milter. Edit /etc/postfix/ file and add these lines:


smtpd_milters = inet:localhost:12345
non_smtpd_milters = inet:localhost:12345
Lastly, restart Postfix and DKIM-Milter service:
# invoke-rc.d dkim-filter restart
# invoke-rc.d postfix restart

We are using the friendly GMail for testing. Here’s what we do in one of our testing subdomain before we set the DKIM: Before DKIM

After we set the DKIM:
After DKIM

Now GMail knows our test subdomain. To check if our verification also works, we send the a mail from GMail to our test domain and would have these on the header:

Authentication-Results:; dkim=pass (1024-bit key); dkim-asp=none

There are things that I’m not covering, like the multiple selector and using 3rd party like Verisign to accomplish that, handling subdomains, using both DKIM and DomainKey, setup UNIX socket, etc. Don’t worry, for a single domain, the tutorial may run well.

Reference: Coker, Russel. 2008. Installing DKIM and Postfix in Debian. Postfix. 2009. Postfix before-queue Milter support. Sendmail Consortium, The. 2009.