Posts Tagged ‘postsrsd’

DKIM on multihosting (opendkim, postsrsd)

March 19th, 2015 No comments

We host several thousands e-commerce entities at Each on its own domain. A good half of them is using freemail as their main e-mail address, some are using our mailboxes and some use their own. We have to transmit emails generated by their customers and order processing for all of them and we offer basic newsletter solution too (along with advanced integration with MailChimp).

As anyone else we have been forced by to introduce DKIM for mass emails. We have learned that is going to build sender’s reputation on the combination of DKIM selector and domain – this means we must use different combination for every e-commerce entity. And we do not want to allow users to change this combination – if they behave like spammers, they should not have bad influence on other our users.


We use postfix and naturally we started with opendkim. The documentation is not the strongest part of the project, so after many hours we came with this setup:

SigningTable lua:/etc/opendkim/SigningTable.lua
KeyTable lua:/etc/opendkim/KeyTable.lua

SigningTable.lua was tough, giving us endless Segmentation fault until we discovered, we cannot return nil.

The global variable query passed to SigningTable contains content of the “From” header. This does not allow us to distinguish e-commerce entities. People could use their freemail address. Until recently there existed directive SenderHeaders Sender,From where different headers could have been used, but this had gone in opendkim 2.10.0 release. We have decided to put it back, but not that versatile – we just hardcoded support for header called: X-DKIM-Sender. Because of internal guts it must have @ in the content, so we pass information about our entity as selector=domain@dkim. You can see in the script below, that we will strip @dkim, and separate selector and domain using the = sign.

You can see we sign everything coming from this mail server with the same private key. Our public key is a TXT record on In order to create a unique selector for every entity we created wildcard CNAME: * CNAME The final step is to modify the sending applications to include the X-DKIM-Sender header. If the user has verified their domain, we would pass this:


If they did not we will use this:



We have combined this with Postfix Sender Rewriting Scheme daemon (to deliver all bouncing messages and auto-replies to the real sender) and hardened SPF record for

SpamAssassin now shows in the first case DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU. In the later DKIM_VALID_AU is missing obviously.

This article was written to help others seeking help with opendkim, perhaps they will not have to read so much C code as I had to to figure this all out 😉

Customer usage of SMTP

Out customers send their email from their email clients using our SMTP server. In this case we have to use email address from their MAIL FROM SMTP command, otherwise they would be able to forge From: header. This requires changes in opendkim: configure --enable-sender_macro

SenderMacro {mail_addr}

Finally on this SMTP server we must use special /etc/opendkim/KeyTable.lua: