How do I generate SSHFP records?
What are SSHFP records?
SSHFP records are DNS records that contain fingerprints for public keys used for SSH. They're mostly used with DNSSEC enabled domains. When an SSH client connects to a server it checks the corresponding SSHFP record. If the records fingerprint matches the servers, the server is legit and it's safe to connect.
What does SSHFP records look like?
SSHFP records consist of three things:
- Algorithm
- Fingerprint type
- Fingerprint (in hex)
Algorithm
There are four different algorithms defined in SSHFP as of 2015. Each algorithm is represented by an integer. The algorithms are:
- 1 - RSA
- 2 - DSA
- 3 - ECDSA
- 4 - Ed25519
Fingerprint type
Two fingerprint types are defined in SSHFP as of 2012. Each fingerprint type is represented by an integer. These are:
- 1 - SHA-1
- 2 - SHA-256
How do I generate SSHFP records?
You can use ssh-keygen to generate the records using the -r
parameter, followed by the hostname (which does not effect the fingerprints so you can specify whatever you like instead)
Example
Using ssh-keygen
and CentOS:
[root@localhost ~]# ssh-keygen -r my.domain.com
my.domain.com IN SSHFP 1 1 450c7d19d5da9a3a5b7c19992d1fbde15d8dad34
my.domain.com IN SSHFP 2 1 72d30d211ce8c464de2811e534de23b9be9b4dc4
Note
Sometimes ssh-keygen
will ask for the location of the public certificate. If it asks, you will have to run ssh-keygen
multiple times and every time specify a different certificate to make sure that you generate all necessary SSHFP records. Your public keys are usually located in /etc/ssh
.
I'm not sure if ssh-keygen
works with existing keys. If not you still can easily assemble them in your shell (which I prefer), and without fancy software or remote interfaces.
A records such as mentioned...
my.domain.com IN SSHFP 2 1 72d30d211ce8c464de2811e534de23b9be9b4dc4
...exist of 6 parts:
part 1: hostname
part 2: Usually "IN" for internet
part 3: "SSHFP", the RR name for type 44
part 4: RSA keys = "1"
DSA keys = "2"
ECDSA keys = "3"
ED25519 keys = "4"
part 5: The algorithm type:
SHA-1 = "1"
SHA-256 = "2"
part 6: You can generate, for example:
$ awk '{print $2}' /etc/ssh/ssh_host_dsa_key.pub | \
openssl base64 -d -A | openssl sha1
To make use of it, put VerifyHostKeyDNS ask
in your SSH client's config, usually ~/.ssh/config
.
Older versions of ssh-keygen don't generate all the available keys (eg. no support for ecdsa and sha256). This script does creates all the records for all available keys in /etc/ssh/
:
#!/bin/bash
#
# Creates SSHFP Records for all available keys
#
HOST="${1-$(hostname -f)}"
if [[ "$1" == "-h" || "$1" == "--help" ]]
then
echo "Usage: sshfpgen <hostname>"
fi
if which openssl >/dev/null 2>&1
then
if ! which sha1sum >/dev/null 2>&1
then
sha1sum() {
openssl dgst -sha1 | grep -E -o "[0-9a-f]{40}"
}
fi
if ! which sha256sum >/dev/null 2>&1
then
sha256sum() {
openssl dgst -sha256 | grep -E -o "[0-9a-f]{64}"
}
fi
fi
for pubkey in /etc/ssh/ssh_host_*_key.pub /etc/ssh_host_*_key.pub
do
case "$(cut -d _ -f3 <<< "$pubkey")"
in
rsa)
echo "$HOST IN SSHFP 1 1 $(cut -f2 -d ' ' "$pubkey" | base64 --decode | sha1sum | cut -f 1 -d ' ')"
echo "$HOST IN SSHFP 1 2 $(cut -f2 -d ' ' "$pubkey" | base64 --decode | sha256sum | cut -f 1 -d ' ')"
;;
dsa)
echo "$HOST IN SSHFP 2 1 $(cut -f2 -d ' ' "$pubkey" | base64 --decode | sha1sum | cut -f 1 -d ' ')"
echo "$HOST IN SSHFP 2 2 $(cut -f2 -d ' ' "$pubkey" | base64 --decode | sha256sum | cut -f 1 -d ' ')"
;;
ecdsa)
echo "$HOST IN SSHFP 3 1 $(cut -f2 -d ' ' "$pubkey" | base64 --decode | sha1sum | cut -f 1 -d ' ')"
echo "$HOST IN SSHFP 3 2 $(cut -f2 -d ' ' "$pubkey" | base64 --decode | sha256sum | cut -f 1 -d ' ')"
;;
ed25519)
echo "$HOST IN SSHFP 4 1 $(cut -f2 -d ' ' "$pubkey" | base64 --decode | sha1sum | cut -f 1 -d ' ')"
echo "$HOST IN SSHFP 4 2 $(cut -f2 -d ' ' "$pubkey" | base64 --decode | sha256sum | cut -f 1 -d ' ')"
;;
esac
done
Edit: New Version with PR from alex-dupuy with *BSD support.
https://github.com/mindfuckup/Scripts/blob/master/sshfpgen