Local DNSSEC validation with OpenSSH
====================================
Tested with OpenSSH 6.0p1
(Previous versions tested with OpenSSH 4.5p1, 4.7p1, 5.0p1,5.3p1 and 5.6p1)

Introduction
------------

OpenSSH contains support for performing local DNSSEC validation for
all DNS lookups (including initial host to IP address and SSHFP key
fingerprint lookups). This document contains very brief instructions
on how to use this feature. Configuring DNS is out of the scope of this
document.


Background
----------

A detailed description of DNSSEC is out of scope for this document,
but a basic background is provided.

DNS response packets are fairly easy to spoof, so an attacker situated
in the network path between a ssh client and its configured DNS server
could possibly inject DSN response packets, causing the ssh client
to connect to another host.  For clients which have already
connected to the intended server, ssh already provides a warning that
the host key has changed. However, a new client might not check the
fingerprint presented upon connecting, simply accepting it.

The VerifyHostKeyDNS option can be used to check the key fingerprint
via DNS, but we've already established that DNS is too easy to spoof.

DNSSEC introduces cryptographic signing of DNS records, allowing a
resolver to verify that a response has not been spoofed. This is
done by configuring 'Trust Anchors', which are know good keys used to
sign a zone.

Rational for Local Validation
-----------------------------

As DNSSEC deployment grows, more ISPs are offering DNS servers which
are DNSSEC aware and perform DNSSEC validation. Also, OpenSSH already
has code to verify DNS key fingerprint records (SSHFP), so one might
wonder why they would want local validation. There are several reasons.

- Deployment of DNSSEC is progressing slowly, so end users might not
have DNS servers which are capable of, or configured for, DNSSEC processing.

- DNSSEC only guarantees the integrity of the DNS response to
the DNS server. The response from the DNS server to the local host
has no protection. Thus an attacker who can inject packets in the
path between a DNS server and a stub resolver can not only redirect
the client, but can make it belive a response was authentic!

- Even if a DNSSEC server is on a local and trusted network, an end
user might not have any influence over local policy. In other words,
they might not be able to get a new Trust Anchor configured for a
zone which they trust.

- A DNSSEC server will not return data to an application for a response
which cannot be validated. The means that, to the client, the DNS lookups
will appear to have failed, even if the DNS server did get a response.
With local validation, the application can distinguish between a non-
responsive domain and validation failure. And since ssh performs its own
validation of host keys upon connecting to a host, it may be an acceptable
risk to return the questionable response to the application, along with a
warning, and allow the end user to decide if they want to proceed.


Requirements
------------

This code requires that the DNSSEC-Tools resolver and validator
libraries and headers be installed. The DNSSEC-Tools package
can be obtained from:

	http://www.dnssec-tools.org/resources/download.html

Note that the Perl requirements are not needed if you only want
to install/use the resolver and validator libraries.

By default, the validator library will use the resolver specified
in /etc/resolv.conf when performing DNS queries. If the resolver(s)
configured in /etc/resolv.conf are not DNSSEC aware, the validator
won't be able to get the data is needs for local validation. In this
case, you may need to tweak the RESOLV_CONF definition in the
validator library header (dnssec-tools/validator/libval/validator.h)
before building and installing the libraries. You can specify an
alternate location (eg '/etc/resolv-dnssec.conf') which contains
a namesever which is DNSSEC aware. If there is not a DNSSEC aware
nameserver you can use, simply leave the file empty, and the library
will perform all validation itself, starting from the root
nameservers.


Using DNSSEC validation
-----------------------

The extra validation code in OpenSSH is optional, and must be enabled
by specifying --with-local-dnssec-validation when configuring
OpenSSH. You may also need to specify the path to the directory
where the libraries are installed using '--with-ldflags=-L/path'.

 # tar xvfz openssh-5.3p1.tar.gz
 # cd openssh-5.3p1
 # patch -p0 < ssh-dnssec.pat
 # autoconf
 # autoheader
 # ./configure --with-local-dnssec-validation --with-ldflags=-L/usr/local/lib/
 # make

Once configured and built, clients may specify a new option:
StrictDnssecChecking. Possible settings include yes, no and
ask. Any DNS response which is not trusted will always trigger
a warning. If StrictDnssecChecking.is yes, the command will
abort. If it is 'ask', they user will be prompted to continue.

An example invocation, which will perform validation on both the
host lookup and any key fingerprint lookups, would be:

  ssh -o VerifyHostKeyDNS=ask -o StrictDnssecChecking=ask ssh.example.com

Another new option, AutoAnswerValidatedKeys, is used in conjunction
with VerifyHostKeyDNS. If VerifyHostKeyDNS is set to 'ask', and
AutoAnswerValidatedKeys is set to yes, any time ssh would normally
prompt to accept a key, the prompt will be supressed and the key
will be accepted if a matching SSHFP host key was found and validated
by DNSSEC.


Robert Story
DNSSEC-Tools Dev
SPARTA, Inc.

