All,

I haven't put in much of an appearance here for a couple of years, but a long time ago Peter Bowyer and myself built a mail relay system, its been running Exim 4.63 for years on Fedora 6 and I've just come to do a major upgrade on it and replace it with Exim 4.77 and Ubuntu 12.4 LTS server.

We had experimental DomainKeys on the old system and I've replaced it with Exim's in-built DKIM and I'm having some trouble getting my head around the way it works, or more precisely, the way it confuses me...

What I am trying to do:

    a) accept messages that are correctly signed
    b) reject (deny) messages that are incorrectly signed
c) defer for messages that are signed but we can't verify them for a transient reason (eg. can't reach their DNS)
    d) accept all messages that have no signature
e) maintain sufficient information in the logs so that I can understand what is going on


What I have:

    * Pentuim 4 2.8GHz server, 1Gb RAM, 250Gb HDD
    * Ubuntu 12.4 LTS Server (Beta2)
* Exim-4.77 built from source with experimental SPF, SRS, DKIM, MySQL and a few other bits and pieces
    * latest ClamAV, SpamAssassin, etc.



Here is my current config pertaining to the DKIM parts:


# mysql table with things like paypal.com, ebay.com, google.com etc.
SELECT_DKIM_KNOWN_SIGNERS = select domain from dkim_known_signers where active=1; DKIM_KNOWN_SIGNERS = ${lookup mysql{SELECT_DKIM_KNOWN_SIGNERS}{${sg{$value}{\\n}{ : }} }}

# list of signers we should attempt to verify
dkim_verify_signers = $dkim_signers : $sender_address_domain : DKIM_KNOWN_SIGNERS


acl_check_dkim:

        #
        # debugging
        #
warn logwrite = DKIM TEST: domain=$sender_address_domain possible_signer=$dkim_cur_signer status=$dkim_verify_status reason=$dkim_verify_reason

        #
# skip DKIM if domain whitelisted for DKIM, i.e. known good domain that has broken DKIM
        #
        accept  sender_domains = +dkim_whitelist_domains
logwrite = DKIM SKIP: Skipping DKIM checks for whitelisted domain: $sender_address_domain

        #
        # skip DKIM checks on hosts we relay for
        #
        accept  hosts = +relay_from_hosts
logwrite = DKIM SKIP: Skipping DKIM checks for relay host: $sender_fullhost

        #
        # skip DKIM checks on authenticated hosts (that we also relay for)
        #
        accept  authenticated = *
logwrite = DKIM SKIP: Skipping DKIM checks for authenticated host: $sender_fullhost

        #
        # defer when message not testable, e.g. can't get public key, etc.
        #
        defer   dkim_status = invalid
message = Message from $sender_address_domain cannot be verified
                logwrite = DKIM DEFER: domain=$sender_address_domain

        #
        # deny when message fails signature test
        #
        deny    dkim_status = fail
message = Message from $sender_address_domain has invalid DKIM signature
                logwrite = DKIM DENY: domain=$sender_address_domain

        #
        # accept the message (correctly signed)
        #
        accept
                sender_domains = $sender_address_domain
                dkim_signers = $sender_address_domain
                dkim_status = pass
logwrite = DKIM MATCH: domain=$sender_address_domain signer=$dkim_cur_signer status=$dkim_verify_status add_header = :after_received:X-DKIM-Result: domain=$sender_address_domain result=signature ok

        #
        # accept anything else
        #
        accept
                # debugging
logwrite = DKIM DEFAULT: Accept at end of ACL: domain=$sender_address_domain



I see some discrepancies between documented and actual behaviour (and what I expected or would like to see :-)

Exim's documentation (Chapter 54 section 2) states: "Verification of DKIM signatures in incoming email is implemented via the acl_smtp_dkim ACL. By default, this ACL is called once for each syntactically(!) correct signature in the incoming message."

If I leave $dkim_verify_signers set to default ($dkim_signers) and I receive a signed mail message then I see what I would expect:

2012-04-14 07:18:07 1SIwJD-0000k1-3k DKIM: d=mail.dealcloud.co.uk s=key1 c=relaxed/relaxed a=rsa-sha1 [email protected] [verification succeeded] 2012-04-14 07:18:07 1SIwJD-0000k1-3k DKIM START: domain=xpressus.emarsys.net signer=mail.dealcloud.co.uk status=pass reason= 2012-04-14 07:18:07 1SIwJD-0000k1-3k DKIM ACCEPT: domain=xpressus.emarsys.net signer=mail.dealcloud.co.uk status=pass 2012-04-14 07:18:07 1SIwJD-0000k1-3k DKIM START: domain=xpressus.emarsys.net [email protected] status=pass reason= 2012-04-14 07:18:07 1SIwJD-0000k1-3k DKIM ACCEPT: domain=xpressus.emarsys.net [email protected] status=pass

the above example appears to have two signatures and the ACL is called twice, both signers pass and on both occasions the ACL returns accept before reaching the bottom.


However, if I set $dkim_verify_signers to the compound list (dkim_verify_signers = $dkim_signers : $sender_address_domain : DKIM_KNOWN_SIGNERS) then the DKIM ACL gets called even when Exim has not generated its initial "DKIM: d= s= c= a= i= [status]" message (that it generates when it detects a signature) - here it is doing it:

2012-04-14 21:08:51 CONNECT: New connection from 194.25.134.18:38422 -> 25
2012-04-14 21:08:53 CONNECT: Accepting connection from: 194.25.134.18 as not blocked by any DNSRBL 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM TEST: domain=t-online.de possible_signer=t-online.de status=none reason= 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM DEFAULT: Accecpt at end of ACL: domain=t-online.de 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM TEST: domain=t-online.de possible_signer=ebay.com status=none reason= 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM DEFAULT: Accecpt at end of ACL: domain=t-online.de 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM TEST: domain=t-online.de possible_signer=paypal.com status=none reason= 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM DEFAULT: Accecpt at end of ACL: domain=t-online.de 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM TEST: domain=t-online.de possible_signer=paypal.co.uk status=none reason= 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM DEFAULT: Accecpt at end of ACL: domain=t-online.de 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM TEST: domain=t-online.de possible_signer=ebay.co.uk status=none reason= 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM DEFAULT: Accecpt at end of ACL: domain=t-online.de 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM TEST: domain=t-online.de possible_signer=yahoo.com status=none reason= 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM DEFAULT: Accecpt at end of ACL: domain=t-online.de 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM TEST: domain=t-online.de possible_signer=yahoo.co.uk status=none reason= 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM DEFAULT: Accecpt at end of ACL: domain=t-online.de 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM TEST: domain=t-online.de possible_signer=gmail.com status=none reason= 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM DEFAULT: Accecpt at end of ACL: domain=t-online.de 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM TEST: domain=t-online.de possible_signer=googlemail.com status=none reason= 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM DEFAULT: Accecpt at end of ACL: domain=t-online.de 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM TEST: domain=t-online.de possible_signer=google.com status=none reason= 2012-04-14 21:08:53 1SJ9HB-0003S3-CZ DKIM DEFAULT: Accecpt at end of ACL: domain=t-online.de
2012-04-14 21:08:53 1SJ9HB-0003S3-CZ MIME: Checking status: 1

so, it iterates over all of the entries in $dkim_verify_signers and *not* all of the signatures in the email (since there are none) - is this not a bug - I can't see the point of the ACL being called for the contents of $dkim_verify_signers ?

Next, for the testing that I think that I want to do I'm trying to find the first definite 'accept' (good signature) or 'deny' (bad signature) and bail out of the ACL checking for the message at that point. I can't see the point in carrying on calling the ACL when we know we want to bail out - I think what is needed is a bit like a "no_more" when routing, for example:

        deny    dkim_status = fail
message = Message from $sender_address_domain has invalid DKIM signature
                logwrite = DKIM DENY: domain=$sender_address_domain
no_more // return 'deny' and exit the DKIM ACL altogether


One of the conditions that I'm not sure how we resolve (or even it it ever happens) is what we do if there are two signatures on an incoming message and one is good (pass) and one is bad (fail) - but I guess this is down to the ACL creator ;-)



Mike


--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Reply via email to