Kohei Nozaki's blog 

Entries tagged [dkim]

Configuring James to sign DKIM for outbound mails


Posted on Saturday Feb 07, 2015 at 01:20PM in Technology


Environment

  • Apache jDKIM 0.3-SNAPSHOT

  • Apache James 3.0.0-beta5-SNAPSHOT

  • Oracle JDK7u51

Obtaining and building jDKIM

svn co http://svn.apache.org/repos/asf/james/jdkim/trunk jdkim
cd jdkim
mvn clean install

Put jars of jDKIM into James

Put following files packed in $JDKIM_HOME/assemble/target/apache-jdkim-0.3-SNAPSHOT-bin.tar.gz into $JAMES_HOME/conf/lib of your James server:

  1. apache-jdkim-library-0.3-SNAPSHOT.jar

  2. apache-jdkim-mailets-0.3-SNAPSHOT.jar

  3. lib/not-yet-commons-ssl-0.3.11.jar

Creating key pair

openssl genrsa -out dkim-private.pem 1024 -outform PEM
openssl rsa -in dkim-private.pem -out dkim-public.pem -pubout -outform PEM

Registering public key into DNS

20150207._domainkey IN TXT "k=rsa; p=[YOUR PUBLIC KEY HERE EXCLUDE THE HEADER AND FOOTER];"

20150207 is a selector and which identifies the key. it’s recommended to rotate periodically so timestamp manner like YYYYMMDD is reasonable. GMail is used this way too.

Following command is useful if you don’t want to concatenate and strip the header and footer by hand:

awk 'NR>1{a[++k]=$0}END{for(i=1;i<k;i++){printf("%s", a[i])}; printf("\n")}' dkim-public.pem

You can test whether the key is successfully registered as follows:

host -t txt 20150207._domainkey.example.com

Defining Mailets

Put following definition to $JAMES_HOME/conf/mailetcontainer.xml. make sure to put the value of s (selector) that is the same as one which you just have registered in DNS. and you have to replace d (domain) with your domain. note that you should put following definition to place just before <mailet match="All" class="RemoteDelivery"> element to prevent altering mails after signing.

<mailet match="All" class="org.apache.james.jdkim.mailets.ConvertTo7Bit"/>

<mailet match="All" class="org.apache.james.jdkim.mailets.DKIMSign">
  <signatureTemplate>v=1; s=20150207; d=example.com; c=relaxed/relaxed; h=Message-ID:Date:Subject:From:To:MIME-Version:Content-Type; a=rsa-sha256; bh=; b=;</signatureTemplate>
  <privateKey>
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
  </privateKey>
</mailet>

If you have passphrase in your key, you need to put it here as privateKeyPassword argument.

Testing DKIM signature

Go https://www.mail-tester.com and send a mail from your James server.

Invalid signature on Quoted-Printable mails

It works fine with 7bit plain text mails but when I send a long-line mail with Apple Mail which will be converted to Quoted-Printable, James creates invalid signature. I’m investing this problem now but not unsure at present time. maybe investigation in DKIMSign, CRLFOutputStream, RemoteDelivery and SMTPTransport are needed because they have many code of manipulating content.

UPDATE I found the cause. you need to put following definition inside the mailet named RemoteDelivery. JavaMail automatically converts quoted-printable mails to 8bit plain-text mail because RemoteDelivery class sets it to true at its run() method.

<mail.smtp.allow8bitmime>false</mail.smtp.allow8bitmime>