Phil Pennock has been working at the release of Exim 4.80 and one of the features he’s added to Exim is support for determining whether a sender host’s DNS is DNSSEC-secured. I thought I’d look at that feature a bit more closely.

Upon accepting a connection from a remote host, Exim performs a reverse lookup in the DNS for the sender’s IP address. If the boolean flag dns_use_dnssec is true in Exim’s configuration, Exim now sets a resolver flag (RES_USE_DNSSEC) asking the resolver to perform a DNSSEC query. If the resolver sees the AD flag (Authenticated Data) in the DNS response, Exim sets the $sender_host_dnssec variable to the value yes, else to no.

I can use this to expand my global received_header_text configuration:

dns_use_dnssec = 1

received_header_text = Received: \
      ${if def:sender_rcvhost {from $sender_rcvhost\n\t}\
      {${if def:sender_ident {from $sender_ident }}\
      ${if def:sender_helo_name {(helo=$sender_helo_name)\n\t}}}}\
      by $primary_hostname (Exim $version_number)\n\t\
      ${if eq {$sender_host_dnssec}{yes}{sender host verified by DNSSEC (AD)\n\t}{}}\
      ${if def:received_protocol {with $received_protocol}} \
      ${if def:authenticated_id  {($sender_host_authenticated:userid=$authenticated_id) }}\
      ${if def:tls_cipher {(tls_cipher: $tls_cipher)\n\t}}\
      ${if def:tls_peerdn {(dn = $tls_peerdn)\n\t}}\
      id $message_id \
      ${if def:received_for {\n\tfor $received_for}}

A test message to my newly built Exim server results in the variable being set, and the header being added to the message:

Looking at Exim’s debug output I see:

# exim -bd -d-all+resolver+dns
33108 Connection request from port 51040
33123 Coerced resolver DNSSEC support on.
;; res_nquerydomain(, <Nil>, 1, 12)
;; res_query(, 1, 12)
;; res_nmkquery(QUERY,, IN, PTR)
;; res_nopt()
;; res_opt()... ENDS0 DNSSEC
;; res_send()
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56244
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;;, type = PTR, class = IN
; EDNS: version: 0, udp=2048, flags=8000
;; Querying server (# 1) address =
;; new DG socket
;; got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56244
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 1
;;, type = PTR, class = IN
33123 DNS lookup of (PTR) succeeded
33123 Reverse DNS security status: DNSSEC verified (AD)

The last few lines of the log are in dig style: the flags show the ad (Authenticated Data) bit set.

(I’ve also verified, of course, that a message from localhost, which isn’t DNSSEC signed here at Casa Mens, indeed sets $sender_host_dnssec to the value of no.)

I can also disable Exim’s DNSSEC support by setting dns_use_dnssec = 0, in which case this feature is disabled: debugging then shows:

31873 Process 31873 is handling incoming connection from []
31873 Coerced resolver DNSSEC support off.

Phil mentioned this evening that he has outbound DNSSEC verification via a “dnssec” option on the SMTP transport mostly ready. The next step will be implementing Tony Finch’s draft-fanf-dane-smtp, which will allow the use of TLSA records in the DNS to be used for SMTP-server authentication. Exciting stuff.

On closing, let me note that the private IP addresses in above screen shot aren’t fake: here, in the west wing of Casa Mens, DNSSEC is enabled for This zone is of course not signed from the root, but with the help of a trust-anchor configured in my Unbound DNS resolvers, a query for an address in that zone is validated; that’s why Exim sets $sender_host_dnssec accordingly. It’s like Tony asked this evening: What can DNSSEC do, apart from provide full employment for DNS nerds? ;-)

Exim, Mail, and MTA :: 07 Jun 2012 :: e-mail