We've have experienced in some cases on emails sent from CiviCRM the DKIM signatures were getting invalid. We use a self-managed email server for this, and usually DKIM is fine.
After some research I found out the reason why was DKIM broken (and why not always) is that if we send an email with a line containing more than 998 characters - which can happen easily by using email template editors (Mosaico in our case) - first the message is signed by OpenDKIM, then Postfix break lines longer than 998 chars (number of chars can be configured) to conform with SMTP protocol, which doesn't allow more than 1000 chars (998 chars +
\r\n) in a single line. Then DKIM verification will fail as there are extra characters (line breaks) in the email body.
It would be best if the order could be changed (first line breaking then signing), but as far I as know milter applications (like OpenDKIM) can be plugged into Postfix only to the early stages of processing (
cleanup) and line breaking happens at the last stage (
Further testing showed, if I send a mail with this long lines from another email client (Roundcube) to the same server, long lines are already wrapped before signature. Also tested traditional CiviMail and Flexmailer and they gave the same results as with Mosaico.
This led me to think that wrapping long lines should be handled by clients (CiviCRM in this setup). So we wrote a simple extension to handle this (https://github.com/reflexive-communications/civalpa) and the issue seems solved.
My questions would be:
- Has anybody run into this issue? One thing that is very strange for me, I've not found too much material but one which seemed quite relevant (https://www.virtualmin.com/node/37021), and that also suggested line wapping should happen before sending to the SMTP server.
- Lien wrapping should really be handled by clients or is this a configuration issue on the mail-server?
- CiviCRM: 5.29.1
- Mosaico form CiviCRM: 2.5
- Postfix: 3.4.13
- OpenDKIM: 2.11.0
UPDATE: there is now an issue in Civi core regarding this.
UPDATE2: it turned out, this is already fixed in core (as a patch). On Drupal 8 you need to enable patching for this to work. (put
"enable-patching": true to the extra section of
composer.json and install the