2

I've been struggling to get Exim to sign my mails i'm sending with Zend2 Mailer class. The class has the option to send through SMTP; this is awesome since i have everything configured at MTA level.

However. Sending mail from a client (Thunderbird) will get signed. The mail send with Zend2's Mailing class will not. Let's start with my version of Exim.

Exim version 4.76 #1 built 19-Jul-2011 02:56:59
Copyright (c) University of Cambridge, 1995 - 2007
Berkeley DB: Berkeley DB 4.7.25: (November 12, 2010)
Support for: crypteq IPv6 Perl OpenSSL move_frozen_messages Content_Scanning DKIM Old_Demime
Lookups (built-in): lsearch wildlsearch nwildlsearch iplsearch cdb dbm dbmnz
Authenticators: cram_md5 plaintext
Routers: accept dnslookup ipliteral manualroute queryprogram redirect
Transports: appendfile/maildir/mailstore/mbx autoreply lmtp pipe smtp
Size of off_t: 8
Configuration file is /etc/exim.conf

Then there is the configuration of DKIM. I tried looking up the domain with the method beneath instead of using the $sender_address_domain variable. I saw in another serverfault post that the DATA command can malform the envelope resulting in a wierd sender address. That however was not the case with me. Both resolve to the actual sender/from adres.

[rob@server ~]$ exim -bP transports | grep dkim
dkim_canon = relaxed
dkim_domain = ${lc:${domain:$h_from:}}
dkim_private_key = ${if exists{/etc/virtual/$sender_address_domain/dkim.private.key}{/etc/virtual/$sender_address_domain/dkim.private.key}{0}}
dkim_selector = x
dkim_sign_headers = MIME-Version:Date:Message-ID:Subject:From:To
dkim_strict = 0

The keys are there. The configuration works, as verified with mail send with Thunderbird.

Then i asked myself, do these mails actually pass through the SMTP server? The result; yes they do. I checked the /var/log/exim/mainlog. Now i also noted that the mails from Thunderbird don't get that "recieving the mail" logline. I don't know why? Can someone elaborate on that if they know why? PHP connects using SMTP login method with the exact same SMTP information that Thunderbird uses. Same ports, domain, username, password.

https://framework.zend.com/manual/2.4/en/modules/zend.mail.smtp.options.html#zend-mail-smtp-options

# This is the mail recieved from the PHP code.
2016-11-15 08:28:52 1c6YAm-000154-6p <= mailbox@mydomain.com H=mydomain.com [ipv4.addr] P=esmtpa A=login:mailbox@mydomain.com S=22098 id=26412cc5accb22e5ce03925c7ac38a7c95c398cb19d5736fa41fb565c8dc1254@mydomain.com T="Another day at the office with DKIM..." from <mailbox@mydomain.com> for mygmail@gmail.com

# Here it is outbound for its destination. Not signed to be noted.
2016-11-15 08:28:52 1c6YAm-000154-6p => mygmail@gmail.com F=<mailbox@mydomain.com> R=lookuphost T=remote_smtp S=22157 H=gmail-smtp-in.l.google.com [ipv6.addr] X=UNKNOWN:ECDHE-RSA-AES128-GCM-SHA256:128 C="250 2.0.0 OK 1479194932 yr4si27147042wjc.210 - gsmtp"

# This is send with Thunderbird. This gets signed...
2016-11-15 08:31:47 1c6YDa-0001CM-UY => mygmail@gmail.com F=<mailbox@mydomain.com> R=lookuphost T=remote_smtp S=762 H=gmail-smtp-in.l.google.com [ipv6.addr] X=UNKNOWN:ECDHE-RSA-AES128-GCM-SHA256:128 C="250 2.0.0 OK 1479195107 s17si1915514wme.47 - gsmtp"

These mails also don't get rejected nor can be found in the panic log. They both get recieved by my gmail account:

# This is the mail send from thunderbird. With DKIM signing.

Delivered-To: mygmail@gmail.com
Received: by 10.80.186.18 with SMTP id g18csp1289759edc;
        Mon, 14 Nov 2016 23:31:47 -0800 (PST)
X-Received: by 10.194.248.5 with SMTP id yi5mr384988wjc.11.1479195107193;
        Mon, 14 Nov 2016 23:31:47 -0800 (PST)
Return-Path: <mailbox@mydomain.com>
Received: from myserver.com (myserver.com. [ipv6.addr])
        by mx.google.com with ESMTPS id s17si1915514wme.47.2016.11.14.23.31.47
        for <mygmail@gmail.com>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Mon, 14 Nov 2016 23:31:47 -0800 (PST)
Received-SPF: pass (google.com: domain of mailbox@mydomain.com designates ipv6.addr as permitted sender) client-ip=ipv6.addr;
Authentication-Results: mx.google.com;
       dkim=pass header.i=@mydomain.com;
       spf=pass (google.com: domain of mailbox@mydomain.com designates ipv6.addr as permitted sender) smtp.mailfrom=mailbox@mydomain.com;
       dmarc=pass (p=NONE dis=NONE) header.from=mydomain.com
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mydomain.com; s=x;
    h=Content-Transfer-Encoding:Content-Type:MIME-Version:Date:Message-ID:Subject:From:To; bh=zaNQl8a2eAEHfPVmKMA7RmtMqJ/6huDk4u6pr/tWrqQ=;
    b=xcDHIzzTWS8hPMxjqbZM0I6b/act/LlweTuNcnZJ9ttEF1dAm37Lzy8zOJz2E2aDTkcQOdCQuC+VyIaXTRzTMJXyzJTUXTgPUPOePsR5XYqqsE0iQRMkDl/Ah650kBHD5drqIrFJwCw5g0aL9OECqTyRO9kwL0DQJX/mKcTkLtiiIs7Z7G77ZwWhJpFm/duoQARtZZ1UZFu42/Vbl+V8vSoWbXoZBpg+WBGucWJoGq+hb5zILxwsMPcbrIu+avBjjoUdLVP9YMFiPC3nK+7zOGBWOO7x6QoHQmO8uo0P88E52Sm9ZJGgLQOCfFCMjCnv4IMemj/GSe25Sf8PKah/Xg==;
Received: from 159-032-128-083.dynamic.caiway.nl ([83.128.32.159] helo=[192.168.1.108])
    by myserver.com with esmtpsa (UNKNOWN:AES128-SHA:128)
    (Exim 4.76)
    (envelope-from <mailbox@mydomain.com>)
    id 1c6YDa-0001CM-UY
    for mygmail@gmail.com; Tue, 15 Nov 2016 08:31:46 +0100
To: Rob van der Lee <mygmail@gmail.com>
From: Rob van der Lee <mailbox@mydomain.com>
Subject: Dit is een verzonden mail via account
Message-ID: <2ccd7be7-bbd1-0fdc-a8d4-a4f6f652bfc2@mydomain.com>
Date: Tue, 15 Nov 2016 08:31:46 +0100
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
 Thunderbird/45.4.0
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit

Dit is echt een test.

And here the mail that gets send from PHP that doesn't get signed.

Delivered-To: mygmail@gmail.com
Received: by 10.80.186.18 with SMTP id g18csp1288906edc;
        Mon, 14 Nov 2016 23:28:52 -0800 (PST)
X-Received: by 10.28.170.134 with SMTP id t128mr2009669wme.29.1479194932632;
        Mon, 14 Nov 2016 23:28:52 -0800 (PST)
Return-Path: <mailbox@mydomain.com>
Received: from myserver.com (myserver.com. [ipv6.addr])
        by mx.google.com with ESMTPS id yr4si27147042wjc.210.2016.11.14.23.28.52
        for <mygmail@gmail.com>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Mon, 14 Nov 2016 23:28:52 -0800 (PST)
Received-SPF: pass (google.com: domain of mailbox@mydomain.com designates ipv6.addr as permitted sender) client-ip=ipv6.addr;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of mailbox@mydomain.com designates ipv6.addr as permitted sender) smtp.mailfrom=mailbox@mydomain.com;
       dmarc=pass (p=NONE dis=NONE) header.from=mydomain.com
Received: from mydomain.com ([37.97.128.104])
    by myserver.com with esmtpa (Exim 4.76)
    (envelope-from <mailbox@mydomain.com>)
    id 1c6YAm-000154-6p
    for mygmail@gmail.com; Tue, 15 Nov 2016 08:28:52 +0100
Date: Tue, 15 Nov 2016 07:28:52 +0000
To: mygmail@gmail.com
From: Rob van der Lee <mailbox@mydomain.com>
Sender: Rob van der Lee <mailbox@mydomain.com>
Subject: Another day at the office with DKIM...
MIME-Version: 1.0
Content-Type: multipart/alternative;
 boundary="=_7ebb8a8d12984c5cc3f5fbf995b1b4ad"
Message-ID: <26412cc5accb22e5ce03925c7ac38a7c95c398cb19d5736fa41fb565c8dc1254@mydomain.com>

This is a message in Mime Format.  If you see this, your mail reader does not support this format.

--=_7ebb8a8d12984c5cc3f5fbf995b1b4ad
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

... content of mail in text and then html, left it out since not relevant.

It just doesn't make sense to me why Exim won't sign this mail. As seen in the log file both mails get send via T=remote_smtp and according to my MTA configuration all outbound mails that get send via remote_smtp should be signed.

Apart from the fact that the mail actually does get send and reaches the mailbox. Hopefully i can learn from this.

Update:

As per suggestion of Daniel i tried resolving the domain, handling the SMTP request, internally as opposed to letting my provider handle this for me. This does not help, the message is still sent unsigned.

The logs also look the same as mentioned above.

Dig Request of old situation:

;; QUESTION SECTION:
;mydomain.com.      IN  NS

;; ANSWER SECTION:
mydomain.com.   86400   IN  NS  ns1.transip.nl.
mydomain.com.   86400   IN  NS  ns2.transip.eu.
mydomain.com.   86400   IN  NS  ns0.transip.net.

Dig Request of new situation:

;; QUESTION SECTION:
;mydomain.com.      IN  NS

;; ANSWER SECTION:
mydomain.com.   14400   IN  NS  ns2.myserver.com.
mydomain.com.   14400   IN  NS  ns1.myserver.com.

Update to Answer:

I've also make a bug ticket over at the Exim Bug tracker. Thought to get some help over the experts; Jeremy Harris pointed me in the right direction.

Jeremy Harris 2016-11-15 14:58:55 GMT

First, if you're running Exim 4.76 - update it.

Then, assuming the problem still exists:  restart your daemon with a commandline
debug option, collecting output.  Feed it a test mail.  Examine the debug output,
which shows the processing flow for the message.  Compare with your config and
work out where it differs from what you expected.

I did what he told me. Updated, then found out the problem still persisted. Fed the debug modus 2 mails. One signed, the other unsigned.

I started closely comparing and noticed that the body on both mails started getting fed to PDKIM (the dkim lib for Exim). Then i noticed my unsigned mail didn't had closure after the body like the signed message did.

I figured it had to do with the content; so from the PHP side i send a mail with just a line of text. This was getting signed...

Solution? Wordwrapping! That i didn't thought of this earlier! I really don't feel all that smart now. This because i knew about this at forehand. The RFC 2646 spec tells us all about it.

Hope this post will help somebody else. It was a good journey and stupid enough the problem was my implementation.

  • Just a shot in the dark, try this: `dkim_sign_headers = MIME-Version:Date:Message-ID:Subject:From:To` Maybe you hit some weird bug with Content-Type or Content-Transfer-Encoding. – kubanczyk Nov 15 '16 at 09:05
  • Changed the config. Restarted Exim. Send mail, yet without being signed. I will leave that in nonetheless as it doesn't hurt. Thanks for the suggestion. Also updated the main post with this change. – Rob van der Lee Nov 15 '16 at 09:18
  • check that the value of `$sender_domain` is as expected. Perhaps you can use `headers_add` to do this, – Jasen Nov 15 '16 at 19:03
  • `message-id` seems kind of long, but probably not related. – Jasen Nov 15 '16 at 19:05
  • The message id in the PHP generated mail was added there by me. That is indeed long. How can i check what the sender domain at MTA level is? Can i add a print to log or debug? – Rob van der Lee Nov 15 '16 at 19:32

1 Answers1

0

(I can't comment, so this isn't meant as an answer, but I hope it helps)

A while back I worked on the same issue and it gave me a real headache, in my case I had two nameservers, one on the oustite at the hosting company, and one was also running on the server itself, to handle internal naming. (As you seem Dutch; TransIP VPS with Cpanel and the domains where handled on the TransIP side.)

Now on the external DNS I had set the DKIM, so that worked for most of the situations, but not for my PHP mail function, therefor I needed to als set it on the internal (Cpanel) DNS to get it working for PHP.

(Also while I was searching for this issue there was something with 7bit and 8bit Content-Transfer-Encoding, but that didn't make a difference in my case)

  • Yes. I'm using TransIP's servers. I'm using the same setup it seems. I will try to handle the domain internally to see if it makes any difference. Thanks for the tip so far! I will also try to set the encoding to 7bit to see if it makes a difference in my case. – Rob van der Lee Nov 15 '16 at 09:06
  • Changing to 7bit didn't help. Thanks nonetheless for the suggestion. I will still try sending from an internal domain later today (when the dns is fully resolved) – Rob van der Lee Nov 15 '16 at 09:26