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 192.168.1.145 port 51040
33123 Coerced resolver DNSSEC support on.
;; res_nquerydomain(145.1.168.192.in-addr.arpa, <Nil>, 1, 12)
;; res_query(145.1.168.192.in-addr.arpa, 1, 12)
;; res_nmkquery(QUERY, 145.1.168.192.in-addr.arpa, 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
;; 145.1.168.192.in-addr.arpa, type = PTR, class = IN
; EDNS: version: 0, udp=2048, flags=8000
;; Querying server (# 1) address = 127.0.0.1
;; 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
;; 145.1.168.192.in-addr.arpa, type = PTR, class = IN
...
33123 DNS lookup of 145.1.168.192.in-addr.arpa (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 [192.168.1.145]
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 1.168.192.in-addr.arpa
.
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? ;-)