DKIM email signature and CakePHP

Setting up DKIM on your server

Sending email from your server is very easy. Sending email that actually arrive in your recipient's mailbox is much harder because email providers like Gmail are sometimes overzealous in their fight against SPAM. In order to have a chance to pass their tests, you have many things to set up like SPF record and DKIM signature.

I will not cover here how to sign your outgoing email with DKIM. Two very clear and helpful examples are available for Ubuntu servers: DKIM with Postfix for Ubuntu or Postifx/DKIM.

Testing your email

Fortunately, testing your email is not as painful as setting up your server, there is a variety of solutions, such as: mail-tester and brandonchecketts. They both allow you to send a test email to a random generated email address and get an in-depth analysis of your email: SPF records, DKIM signature, SpamAssasin score,... This allows you to know if your email configuration is right.

Results of my tests

After properly configuring my DKIM signature + DNS record, all my testing results where a disappointment : neither tests were successful. I tried setting up another DKIM signature, but still the tests would fail (after sometimes waiting 24 hours for DNS propagation). 

I was becoming desparate, when I had the idea to test the DKIM signature of outgoing email using a webmail installed on my server instead of my CakePHP application. I got the first good news: mails sent through the webmail were perfect and passed all tests. The bad news was that CakePHP is responsible. 

I then dove in the CakeEmail lib to understand what caused the problem. I manually disabled all headers set up by Cake and my mails passed all tests. I finally narrowed down the 'Content-Type' and 'Content-Transfer-Encoding' headers that caused the DKIM signature to fail. In the end I understood that in my case the problem was that my messages were encoded using 'UTF-8' (using 8bit) which causes CakePHP to add an additional header. However using a 7bit charset to encode my email caused no problem for the DKIM signature. As many of our outgoing mails are in French, we really need UTF-8 to encode them.

A solution

As mentioned before, if you are using a 7bit encoding, you should have no problems. However, if you are encoding your email in 'UTF-8' then the only solution i found at the moment, is to modify the _getContentTransferEncoding() function that is called in lib/Cake/Network/Email/CakeEmail.php to get it to always return '7bit'. This is hackish, but at least it works with minimal changes to CakePHP and none to OpenDkim, and my mails are properly displayed (no strange characters) and pass the DKIM test.

In order to modify the function you can either modify the CakeEmail.php directly in the lib (which is baaad), or declare a new DkimEmail class in your application's Lib folder. When you send an email, you will have to use:

$email = new DkimEmail(); instead of $email = new CakeEmail();

<?php

class DkimEmail extends CakeEmail {
	protected function _getContentTransferEncoding() {
		return '7bit';
	}
}

?>

Do you have a better solution?

You already encountered this problem and found a better solution ? Please share it with us !

This page belongs to the following categories: news , CakePHP.

Comments

neobie 03/03/2016 05:52:22

I tried, but the message is still not DKIM signed. Any idea?

Add a comment

5103
Petits fours baked