SSHFP offers structural solution to SSH key distribution problem

DNSSEC provides cryptographic anchorage

Pattern of various antique keys on a turquoise background

If you use SSH, you're almost certainly familiar with the SSH server key distribution problem: the first time you connect to a server, the client asks you to confirm the fingerprint of the server's public key. Although most people click to confirm without further verification, that does leave you theoretically vulnerable to a man-in-the-middle (MITM) attack. To exclude that risk, you should really compare the fingerprint offered at the time of connection with the public key published on the server in question.

SSHFP is a security standard that builds on DNSSEC to offer a structural solution to that problem. It provides a mechanism for recording the fingerprint in the DNS (digitally signed using DNSSEC) and making it available to clients.

Public keys

The SSH protocol operates on the basis of asymmetric cryptography. The advantage of asymmetric technology over symmetric cryptography is that there is no need for the two parties to exchange a private key beforehand. The disadvantage is that the public keys have to be published via a trusted and well-known online medium. For the encryption of e-mail, for example, we use a number of well-known OpenPGP Key Servers. However, there are no such key servers for SSH. Instead, the client shows you a fingerprint (digital summary) of the public key offered by the SSH server, and asks whether you want to accept it. If you do, the public key is saved by the client (in the file '~/.ssh/known_hosts'). Then, the next time you connect to that same server, the client knows what public key the server should offer, enabling you to proceed straight to authentication.

The SSHFP record

SSHFP resolves that key distribution problem, as it's known, by publishing the SSH server's public key fingerprint in the DNS. To that end, RFC 4255 defines a dedicated DNS record type: the SSHFP record. An SSHFP record is generated using the 'ssh-keyscan -D' command. Note, however, that the command should (strictly speaking) be run only on the server itself, in order to avoid the risk of a MITM attack.

[user@server ~]$ ssh-keyscan -D example.nl.
; example.nl.:22 SSH-2.0-OpenSSH_8.0
example.nl.  IN  SSHFP 1 1 827381207b4e350996d2f0b32fabc1da72d7c870
example.nl.  IN  SSHFP 1 2 9b382aef6550da23e4844ca60f0c5efd206a868aa914ecb71ba95f5c9257f6aa
; example.nl.:22 SSH-2.0-OpenSSH_8.0
example.nl.  IN  SSHFP 3 1 9d6554b55f82de976d7f94282441771abcc110d4
example.nl.  IN  SSHFP 3 2 87bc585d085c05507780c13b066c0b7d42fde5ec1e9d72ffde91a89c892f9a3d
; example.nl.:22 SSH-2.0-OpenSSH_8.0
example.nl.  IN  SSHFP 4 1 5c87b3e44c9c857d25b4c01b3232868f71b2697b
example.nl.  IN  SSHFP 4 2 4f6f2d6c8fbc1aa3da30ea8fe325e69c9e93e8b175f1ffba577602ccdf8eac94

When you run the command, you get back no fewer than six SSHFP records: two different fingerprints (based on the SHA-256 and SHA-1 hashes) for three different cryptographic algorithms (RSA, ECDSA and Ed25519). For details of the SSHFP record, see RFC 4255. Extensions for the use of SHA-256 and Ed25519 are provided by RFCs 6594 and 7479, respectively. The IANA-assigned parameter values for the cryptographic algorithms are available here. Note that older versions of ssh-keyscan don't support the '-D' option. If you are running an older version, you should use the command 'ssh-keygen -r example.nl' instead. Note that the ssh-keygen does not establish a network connection, but only reads the local key files in the /etc/ssh/ directory. The hostname is only used here to generate the SSHFP records. Another thing to bear in mind is that SSHFP records are not defined by port or service, but by host name. Therefore, all the SSHFP records for a given host are included in a single resource record set (RRset), regardless of what port number is used.

Validation

Once the appropriate records have been added to the zone and the 'VerifyHostKeyDNS yes' setting has been added to your SSH client configuration (in the directory '/etc/ssh/' of '~/.ssh/config'"), your client will validate the fingerprint when connecting to the SSH server. In other words, it will compare the public key fingerprint offered by the server with the fingerprint published in the DNS. If they match, the client will proceed to authentication. If they don't match, the client will fall back on the traditional, manual confirmation:

[user@client ~]$ ssh example.nl
The authenticity of host 'example.nl (192.0.2.162)' can't be established.
ED25519 key fingerprint is SHA256:T29tbI+6HqPaMOqP1yG2nJ6T6LF48f+6V3YDvN+OvJQ.
No matching host key fingerprint found in DNS.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Interestingly, we didn't actually need to enable the 'VerifyHostKeyDNS' option on our Fedora (version 34) Linux system. It was already installed (in the file '/etc/ssh/ssh_config.d/10-dnssec-trigger.conf') as part of the DNSSEC-Trigger.

However, the popular terminal emulator PuTTY doesn't support SSHFP validation.

Cryptographic anchor

SSHFP is an example of a new security application made possible by DNSSEC. Inclusion of the fingerprint in the DNSSEC-secured DNS system provides a cryptographic anchor, and thus a structural solution to the SSH server key distribution problem. Comprehensive information about setting up DNSSEC – which you need to do in order to use SSHFP – is available from this overview page. In our maturity model for modern internet standards, we classified SSHFP as 'State of the art'. Nevertheless, its implementation is so straightforward that we would encourage anyone who has implemented DNSSEC to add SSHFP records to the DNS immediately.

Maturity model for internet standards
https://images.ctfassets.net/yj8364fopk6s/6FIuaWspeZU5hao4Vc4d2F/730d83dd8825ff72f6072e7be4337a32/SIDN__AOC-MaturityModel3b_ol_251022.svg