SSHFP records: DNS providing public ssh host keys
Introduction
I recently learnt (Thanks Jacomo!) that public parts of ssh host keys can be put in the DNS system, using SSHFP record.
Here are a few notes on this topic.
Having ssh-keygen propose SSHFP record content
ssh-keygen -r hostname [-f public-key-file]
 proposes a complete zone file line for hostname:
test -f /etc/ssh/ssh_host_rsa_key.pub && ssh-keygen -r www -f /etc/ssh/ssh_host_rsa_key.pub test -f /etc/ssh/ssh_host_dsa_key.pub && ssh-keygen -r www -f /etc/ssh/ssh_host_dsa_key.pub test -f /etc/ssh/ssh_host_ecdsa_key.pub && ssh-keygen -r www -f /etc/ssh/ssh_host_ecdsa_key.pub
Unfortunately, ssh-keygen -r is usually one algorithm behind ssh-keygen, therefore we usually use the openssl method shown in the next paragraph.
Manual extraction of SSHFP records contents from /etc/ssh/ssh_host_*_key.pub
To generate the values for the SSHFP records of a host, use these commands:
HN=$(hostname -s) I="1" for ALGO in rsa dsa ecdsa ; do if [ -f /etc/ssh/ssh_host_${ALGO}_key ] ; then echo -n "$HN SSHFP $I 1 " ; awk '{print $2}' /etc/ssh/ssh_host_${ALGO}_key.pub | openssl base64 -d -A | openssl sha1 |cut -f2 -d' ' echo -n "$HN SSHFP $I 2 " ; awk '{print $2}' /etc/ssh/ssh_host_${ALGO}_key.pub | openssl base64 -d -A | openssl sha256 |cut -f2 -d' ' fi I=$(($I+1)) done
Telling ssh to respect SSHFP records
In /etc/ssh/ssh_config
or ~/.ssh/config
or with -o set the VerifyHostKeyDNS option to yes
::
VerifyHostKeyDNS yes
Values are:
- yes: trust keys that match the SSHDS record
- ask: check the SSHDS record and display the result, but still ask whether the key is to be trusted
- no (default): do not check SSHDS records at all
Depending on the value of StrictHostKeyChecking
 untrusted keys are refused (yes), asked (ask), or accepted with a fat warning (no).
Retrieving records
To retrieve SSHFP records "raw", dig it:
dig www.clazzes.org SSHFP
OpenSSH Options to use SSHFP records
To turn on SSHFP activities, VerifyHostKeyDNS
must be set to ask
or yes
.
Consider setting StrictHostKeyChecking
 to ask
 or yes
, too.
Due to a lack of trust into the DNS system, and propably to avoid parsing OS-specifics like resolv.conf
, up until recently one had to use full canonical hostname for the SSHFP check to match. The following paragraph describes the solution introduced with OpenSSH 6.5.
OpenSSH 6.5 to allow using non-canonical hostnames
From OpenSSH 6.5 on (Debian: wheezy-backports) it's possible to enable canonicalization by the ssh client.
Here is a list of the Canonical*
options of OpenSSH 6.5, with default values leading the paragraphs and my example values afterwords:
#CanonicalDomains CanonicalDomains internal.site.mydomain.foo mydomain.foo partners.mydomain.foo # should comply with search list in /etc/resolv.conf, otherwise confusion might arise #CanonicalizeFallbackLocal no CanonicalizeFallbackLocal yes #CanonicalizeHostname no CanonicalizeHostname yes # do not use 'always' when using a IPv4 DNAT firewall to reach multiple hosts behind it, separated by port #CanonicalizeHostname always CanonicalizeMaxDots 1 CanonicalizePermittedCNAMEs *.mydomain.foo:*
This approach should only be used if the nameservers can be trusted, i.e. you only use your own well-managed DNSes or the domains are protected by DNSSEC.
Further reading
- How-To from Frillip's BLog:Â https://frillip.com/blog/2012/03/howto-dns-sshfp-records-and-ssh-fingerprints/
- RFCs: RFC4255 introduced SSHFP, RFC6594 added support for ECDSA keys
- German Wikipedia entry on SSHFP records
Â