Do you use let's encrypt?

4990 votes ~ 18 comments


XML logo

Adding Authentication-Results headers with Exim
Posted by lee on Mon 5 Sep 2011 at 00:21
Tags: ,

RFC 5451 describes the email header "Authentication-Results:" which contains the results of online email authentication tests that can be used by the mail receiver client and filtering software.

Exim doesn't, at this time, include native support for adding the Authentication-Results headers, but it's possible to add it using standard ACLs. (But there's a big caveat in doing this, see below.)

In /etc/exim4/conf.d/main/99_local_config :

AUTHSERV_ID = primary_hostname

In where ever your DATA ACL lives add the following:

warn  !condition = ${if def:acl_m_authresults {true}}
         set acl_m_authresults = ; none

warn add_header = :at_start:Authentication-Results: ${AUTHSERV_ID}${acl_m_authresults} 

Exim should now be adding a header like the following to incoming mails:

Authentication-Results:; none

Now to add some authentication checks. The easiest is the "iprev" policy which merely checks if the reverse DNS of the sending server has been properly configured. (The actual suitability and usefulness of rDNS checks is not covered here.)

Add the following to the RCPT ACL (or to the DATA ACL, above the entry listed above):

warn !condition = ${lookup dnsdb{ptr=$sender_host_address}{true}{}}
        set acl_c_iprev = permerror
        set acl_m_authresults = $acl_m_authresults; iprev=permerror (no ptr) \

warn verify = reverse_host_lookup
        set acl_m_authresults = $acl_m_authresults; iprev=pass \
           policy.iprev=$sender_host_address ($sender_host_name)

warn  !condition = ${if eq{$acl_c_iprev}{permerror}{true}}
       condition = ${if and{{def:sender_host_address}{!def:sender_host_name}} {yes}{no}}
       set acl_m_authresults = $acl_m_authresults; iprev=${if \
         eq{$host_lookup_failed}{1}{fail}{temperror}} \

The header on the incoming mail should now have rDNS details included:

Authentication-Results:; iprev=pass policy.iprev=

Adding another check is fairly straight forward. To add a DKIM check add something like the following to your DKIM ACL. (It might need to be slightly more comprehensive, but this example shows the basics)

warn dkim_status = invalid:fail
        set acl_m_authresults = $acl_m_authresults; dkim=neutral ($dkim_verify_reason) \
             header.${if eq{$dkim_identity}{}{d}{i}}=$dkim_cur_signer

warn dkim_status = pass
        set acl_m_authresults = $acl_m_authresults; dkim=pass \
            header.${if eq{$dkim_identity}{}{d}{i}}=$dkim_cur_signer

A DKIM signed message might now have the following in the header:

Authentication-Results:; iprev=pass policy.iprev=
    (; dkim=pass

Different authentication schemes are listed at IANA, and most of them can be incorporated using Exim ACLs.

Which is great, but unfortunately, while the header line seems correct, I can't configure Exim to be fully compliant with RFC5451. The issue is with Authentication-Results headers that already exist in the mail as it is delivered. For obvious reasons it is necessary to remove any Authentication-Results headers (where the remote server is not trusted) that contain the locally used auto-server ID. (Note this is not necessarily a forgery, as mails may legitimately have passed through a system using that ID, but can still not be trusted.)

Unfortunately there's no current way to remove any headers using Exim's ACLs, let alone selectively remove headers that match a specific criteria.

The only way I can think to do this, and it's not very elegant, is to change the generated header so that it consists of a secret string:

warn !condition = ${if def:acl_m_authresults {true}}
     set acl_m_authresults = ; none

warn add_header = :at_start:X-Authentication-Results: ${AUTHSERV_ID}${acl_m_authresults} 
warn add_header = :at_start:X-4354-2827: ${AUTHSERV_ID}${acl_m_authresults} 

And then ensure that all mail deliveries pass through a system filter that contains the following:

if $h_Authentication-Results is not "" then
  headers add "X-Orig-Authentication-Results: $h_Authentication-Results"
  headers remove Authentication-Results
headers add "Authentication-Results: $h_X-4354-2827"
headers remove X-4354-2827

The downside of this approach is that there's no way (I know) of specifying in system filters that headers should be added at the top (as a trace field). Which means it's still fails to meet the requirement of RFC 5451 which considers the header position significant.

Oh well.


Comments on this Entry

Re: Adding Authentication-Results headers with Exim
Posted by hoedlmoser (81.217.xx.xx) on Sat 12 Jul 2014 at 10:35

thanks for all the details on these special headers.

what I'd like to add is that the condition

warn hosts = !condition = ${lookup dnsdb{ptr=$sender_host_address}{true}{}}

will always evaluate to false and therefore I get entries like the follwoing

Authentication-Results:; iprev=permerror (no ptr) policy.iprev=; iprev=pass policy.iprev= (

either the "hosts = " should be removed? or the whole warn?

[ Parent | Reply to this comment ]

Re: Adding Authentication-Results headers with Exim
Posted by lee (86.184.xx.xx) on Sun 13 Jul 2014 at 16:26
[ View Weblogs ]
I think the "hosts =" wasn't supposed to be included. I've removed it.

[ Parent | Reply to this comment ]