40

I got DKIM setup on my mail server (postfix and ubuntu) so it signs outgoing emails. I used these instructions: https://help.ubuntu.com/community/Postfix/DKIM

However, I need it to sign emails from any domain (in the From address) and not just my own. I'm building an email newsletter service and clients will be sending their own email through the server.

First I set "Domain *" in /etc/dkim-filter.conf. This got it to include the DKIM headers in all outgoing emails, no matter what the domain.

However, the verification check fails on gmail because it is checking the domain in the from address, and not my domain (and dns record). Does anyone know how to do this?

Brian Armstrong
  • 1,557
  • 3
  • 18
  • 22
  • As dkim-milter has been replaced by opendkim, [my answer on that question](https://serverfault.com/a/1092776/123376) might help. – Robert Siemer Feb 05 '22 at 16:27

4 Answers4

43

Ok I managed to figure this out on my own, but I wanted to post the steps here for posterity because there was zero documentation on this (that I could find) and it was practically guess and check.

After I set "Domain *" as described above, it would sign it like this:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=clientdomain.com;
    s=main; t=1250005729;
    bh=twleuNpYDuUTZQ/ur9Y2wxCprI0RpF4+LlFYMG81xwE=;
    h=Date:From:To:Message-Id:Subject:Mime-Version:Content-Type;
    b=kohI7XnLlw/uG4XMJoloc4m9zC13g48+Av5w5z7CVE0u3NxsfEqwfDriapn7s7Upi
     31F3k8PDT+eF57gOu2riXaOi53bH3Fn/+j0xCgJf8QpRVfk397w4nUWP/y8tz4jfRx
     GhH21iYo05umP0XflHNglpyEX02bssscu2VzXwMc=

notice the "d=clientdomain.com". It was generating this based on the from address in the email, where the from address was something like "contact@clientdomain.com". Obviously if it checked the client's domain and not mine no DNS TXT record was there and the verification would fail.

So anyway I found out in this documentaion that you can set a KeyList parameter. http://manpages.ubuntu.com/manpages/hardy/man5/dkim-filter.conf.5.html

It didn't really describe what I wanted to do, but I figured I'd play with it. I commented out KeyFile and set KeyList to "/etc/mail/dkim_domains.key" which is an arbitrary file name I made up. I then created that file and put this in it "*:feedmailpro.com:/etc/mail/dkim.key". This tells it for any client domain, sign it with my domain (feedmailpro.com), and use the dkim.key file.

Restarted DKIM and postfix

sudo /etc/init.d/dkim-filter restart
sudo /etc/init.d/postfix restart

Now this is the key it generated when I sent a test email.

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=feedmailpro.com;
    s=dkim.key; t=1250005729;
    bh=twleuNpYDuUTZQ/ur9Y2wxCprI0RpF4+LlFYMG81xwE=;
    h=Date:From:To:Message-Id:Subject:Mime-Version:Content-Type;
    b=kohI7XnLlw/uG4XMJoloc4m9zC13g48+Av5w5z7CVE0u3NxsfEqwfDriapn7s7Upi
     31F3k8PDT+eF57gOu2riXaOi53bH3Fn/+j0xCgJf8QpRVfk397w4nUWP/y8tz4jfRx
     GhH21iYo05umP0XflHNglpyEX02bssscu2VzXwMc=

Improvement, you see the d= now is set to my domain (even though the from address of the email was not my domain). However s= got changed to "dkim.key" instead of the selector I chose in dkim-filter.conf. In the original setup instructions I'd set the selector to "mail". That was weird, but I noticed it changed it to the filename of my key, dkim.key.

So I went and renamed "/etc/mail/dkim.key" to "/etc/mail/mail". Also updated the reference to it in "/etc/mail/dkim_domains.key".

Restart dkim-filter and postfix again same as above, and now it started working. Here is the final header which signs correctly using the right selector (apparently based off the filename of the key).

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=feedmailpro.com;
    s=mail; t=1250006218;
    bh=tBguOuDhBDlhv0m4KF66LG10V/8ijLcAKZ4JbjpLXFM=;
    h=Date:From:To:Message-Id:Subject:Mime-Version:Content-Type;
    b=c9eqvd+CY86BJDUItWVVRvI3nibfEDORZbye+sD1PVltrcSBOiLZAxF3Y/4mP6vRX
     MUUNCC004oIH1u7FYafgF32lpuioMP1cd7bi6x3AZ5zH4BYETNBnnz4AhAPBtqlIh/
     FFMz8jkhhLhcM2hDpwJkuKjAe3LzfNVDP8kD11ZI=

Now s=mail is right, and d=feedmailpro.com is right. It works!

Overall this was way harder than I expected and there seemed to be zero documentation on how to do this (signing for all outgoing domains), but I guess it's open source software so I can't complain.

One final note, to check if the TXT DNS record was setup correctly you can do a command like with your domain

dig mail._domainkey.feedmailpro.com TXT

May need to install dig (sudo apt-get install dig). If you're using Slicehost manager to add the DNS entry, you'd enter the TXT record like this.

Type: TXT
Name: mail._domainkey
Data: k=rsa; t=s; p=M5GfMA0...YOUR LONG KEY...fIDAQAB
TTL seconds: 86400

I don't really understand why the name is set to "mail._domainkey" without a period on the end or without my domain, like "mail._domainkey.feedmailpro.com". But whatever, it seems to work so I'm happy.

If you're trying to duplicate this, here are the instructions I started with: https://help.ubuntu.com/community/Postfix/DKIM

Brian Armstrong
  • 1,557
  • 3
  • 18
  • 22
  • 1
    One thing the guide at ubuntu.com fail to mention is that once you got it working, change t=y to t=n in the TXT record to state that it is not a test. – 3molo Apr 04 '11 at 07:45
  • There are some good resources out there for using the SigningTable, etc. For example, http://blog.tjitjing.com/index.php/2012/03/guide-to-install-opendkim-for-multiple-domains-with-postfix-and-debian.html (excellent) and even the opendkim readme, http://www.opendkim.org/opendkim-README – rfay Feb 19 '13 at 17:26
  • @3molo well , it actually says "The selector used in the signature will be the filename portion of keypath" , in the documentation , http://www.opendkim.org/opendkim.conf.5.html – kommradHomer Jan 14 '15 at 11:04
  • Yeah, it also took me a long time to make it work. I ended up doing the same thing as you, however it could be interesting to generate a key for each domain and them store them in a MySQL DB and tune OpenDKIM to sign the emails from there... http://fossies.org/linux/opendkim/opendkim/README.SQL (of course we would need to ask our final clients to add the TXT to their domains...) – TCB13 Nov 22 '15 at 15:21
16

Inspired by Brian Armstrong's answer for dkim-filter here's how I did this for OpenDKIM.

/etc/opendkim.conf

Syslog          yes
UMask           002
KeyTable        /etc/mail/dkim_key_table
SigningTable    refile:/etc/mail/dkim_signing_table

Note that SigningTable has refile: in it's definition, this specifies that the file includes regular expressions; in our case the * wildcard.

/etc/mail/dkim_key_table

keyname  example.com:selector:/etc/mail/selector.key

Here keyname is used to match the key between this file and the dkim_signing_table file. In my real file I named this the same as my selector.

example.com and selector should be replaced which the domain and selector that you wish to be used in your signature's d= and s= respectively.

/etc/mail/dkim_signing_table

*   keyname

This file simple maps address found in the From: header to a key in the dkim_key_table. In this case we want all email's sent via this server to be signed with the same key, so a * wildcard is used.

Adam J. Forster
  • 263
  • 2
  • 7
  • for those who get "no signing table match in OpenDKIM " http://serverfault.com/q/569823/115907 – kommradHomer Jan 14 '15 at 14:08
  • If anyone gets to this answer (great answer, btw! taught me what I needed) and is looking to send from two different domains with different keys, that can be done like this: KeyTable file: "tagone._domainkey.firstdomain.com firstdomain.com:tagone:/etc/opendkim/keys/firstdomain.com/tagone tagtwo._domainkey.seconddomain.com seconddomain.com:tagtwo:/etc/opendkim/keys/seconddomain.com/tagtwo" SigningTable: "*@firstdomain.com tagone._domainkey.firstdomain.com *@seconddomain.com tagtwo._domainkey.seconddomain.com" Each file is 2 lines (comments don't save linebreaks here) – Sean Colombo Mar 15 '17 at 14:12
  • or: SigningTable csl:*=keyname KeyTable csl:keyname=example.com:selector:/etc/mail/selector.key – danblack Aug 19 '18 at 05:37
  • This is still not enough in cases where the SMTP session is not authenticated (opendkim checks `{auth_type}` milter macro before signing).—See [my answer](https://serverfault.com/a/1092776/123376). – Robert Siemer Feb 05 '22 at 16:30
3

Old thread but maybe someone else who finds this has a use to knowing the 2.x version of opendkim works with KeyTable instead of KeyList.

You can convert your KeyList file with the opendkim-convert-keylist tool (http://manpages.ubuntu.com/manpages/lucid/man8/opendkim-convert-keylist.8.html)

You can read more about the implementation of KeyTable on the opendkim man page: (http://www.opendkim.org/opendkim.conf.5.html)

user203421
  • 31
  • 1
2

I don't really understand why the name is set to "mail._domainkey" without a period

Documentation for DKIM filter is usually installed in thre unix man format. Only Google does know it :-) I also had a problem.

man dkim-filter.conf
man dkim-filter
man dkim-genkey

man dkim-stats
man dkim-testkey
man dkim-testssp

I tried it on Debian. If it is not not actually in your distibution, you can download source tarball and easy read doc.

man dkim-milter-2.8.3/dkim-filter/dkim-filter.conf.5

etc.

--

I don't really understand why the name is set to "mail._domainkey" without a period

So that you can use exacttly the same in both DNS records of different domains.

hynekcer
  • 203
  • 4
  • 8