Server — DNS — SSH Server Keys

Posted on 7 2026

Every time you connect to an SSH server for the first time, OpenSSH presents you with a fingerprint and asks whether you trust it. The honest answer, almost always, is that you have no idea. You accept it anyway, it gets written to ~/.ssh/known_hosts, and from that point on OpenSSH trusts that server silently. This is the leap-of-faith model, and it works well enough in practice, but it is not verification in any meaningful sense. You are trusting whatever key happened to respond on that IP when you first connected.

SSHFP records are the DNS-based alternative. The server publishes its SSH host key fingerprints as DNS records. When a client connects, it queries DNS for those records and compares them against the key the server presents. If they match and the DNS response is DNSSEC-validated, the client can connect without prompting and without a leap of faith. If they do not match, it refuses and warns you loudly.

February already has the prerequisites: a PowerDNS Authoritative Server managing home.arpa, and DNSSEC enabled on that zone. Adding SSHFP records is a small amount of work that makes every subsequent SSH connection to February verifiably correct rather than merely assumed correct.

What an SSHFP record contains

An SSHFP record has three fields beyond the standard DNS record header:

The algorithm number identifies the key type: 1 for RSA, 2 for DSA, 3 for ECDSA, 4 for Ed25519. Since February was set up following the SSH hardening guidance in this series, it uses Ed25519 host keys, so algorithm 4 is the one that matters.

The fingerprint type identifies the hash algorithm used: 1 for SHA-1, 2 for SHA-256. SHA-1 is legacy; only SHA-256 records are worth publishing now.

The fingerprint is the hex-encoded hash of the server’s public key.

A complete SSHFP record for an Ed25519 key looks like this in zone file syntax:

february.home.arpa. IN SSHFP 4 2 7cae4ff942899f8e155bfc675e72e4146a1bf4107977fe73c6cffa8f3fda8fc3

Generating the records from February’s host keys

ssh-keygen has a built-in flag to generate SSHFP records from a server’s existing host keys. Run this on February:

ssh-keygen -r february.home.arpa

The output will include one line per key type per hash algorithm. On a standard Ubuntu install you will see records for RSA, ECDSA, and Ed25519, each with both SHA-1 and SHA-256 variants:

february.home.arpa IN SSHFP 1 1 ...
february.home.arpa IN SSHFP 1 2 ...
february.home.arpa IN SSHFP 3 1 ...
february.home.arpa IN SSHFP 3 2 ...
february.home.arpa IN SSHFP 4 1 ...
february.home.arpa IN SSHFP 4 2 ...

You only need to publish the records for key types you actually use and for SHA-256 only. At minimum, publish the Ed25519 SHA-256 record (algorithm 4, fingerprint type 2). Including RSA and ECDSA SHA-256 records as well does no harm and gives clients that do not support Ed25519 something to validate against.

Omit all SHA-1 records (fingerprint type 1). They are retained for compatibility with very old clients and there is no reason to publish them for a homelab where you control both ends.

Adding the records to PowerDNS

For each record you want to publish, use pdnsutil add-record. The record type is SSHFP and the content is the three fields space-separated:

# Ed25519 SHA-256
sudo pdnsutil add-record home.arpa february SSHFP "4 2 7cae4ff942899f8e155bfc675e72e4146a1bf4107977fe73c6cffa8f3fda8fc3"

# RSA SHA-256
sudo pdnsutil add-record home.arpa february SSHFP "1 2 a61db02b9b26ca48663c3272821b451773c7cd1e9a412f5a09994ec8f8738c79"

# ECDSA SHA-256
sudo pdnsutil add-record home.arpa february SSHFP "3 2 cb6493b10e1103ff1dbab86989cfa96fa52370ac33efe6d468a5f70b8d323869"

Replace the fingerprint hex strings with the actual output from ssh-keygen -r on February. The content field is quoted because it contains spaces.

Rectify the zone after adding records to update the DNSSEC signatures:

sudo pdnsutil zone rectify home.arpa

Verify the records are present and being served:

dig SSHFP february.home.arpa @127.0.0.1

The response should list the SSHFP records with the ad flag set, confirming DNSSEC validation is in place. Without the ad flag, the client will find the records but cannot trust them cryptographically, and will still prompt for manual confirmation.

Configuring SSH clients to use SSHFP

On each machine you SSH to February from, tell OpenSSH to look up and verify SSHFP records. Add this to ~/.ssh/config:

Host february.home.arpa
    VerifyHostKeyDNS yes

Or globally for all hosts on your internal domain:

Host *.home.arpa
    VerifyHostKeyDNS yes

VerifyHostKeyDNS yes means: if a DNSSEC-validated SSHFP record is found and matches, connect silently. If an SSHFP record is found but DNS is not DNSSEC-validated, prompt anyway. If no record is found, fall back to normal known_hosts behaviour.

The alternative value VerifyHostKeyDNS ask always prompts, but adds a note that the fingerprint was found in DNS. This is useful during testing: you can confirm the lookup is working without fully trusting it yet.

For the full benefit, the client must be resolving DNS through a DNSSEC-validating resolver. If the client is on the LAN or connected via WireGuard and using February’s Recursor as its DNS server, and February’s Recursor has DNSSEC validation enabled as configured in the DNSSEC article, this is already the case.

Testing it end to end

Remove February from your known_hosts file so OpenSSH treats it as a new connection:

ssh-keygen -R february.home.arpa

Connect with verbose output:

ssh -v february.home.arpa 2>&1 | grep -i sshfp

With everything working correctly you should see:

debug1: found 3 secure fingerprints in DNS
debug1: matching host key fingerprint found in DNS

And the connection proceeds without a prompt. If you see found X insecure fingerprints in DNS, the records are present but DNSSEC validation is not working. Check that the Recursor has dnssec=validate set and that the zone has valid signatures via pdnsutil zone check.

If you see no SSHFP-related lines at all, the client is not finding the records. Check VerifyHostKeyDNS is set in ssh_config and that the hostname you are connecting with exactly matches the DNS name you published records for.

What to do when host keys change

If February’s SSH host keys are ever regenerated (after a reinstall, or as part of deliberate rotation), the SSHFP records in PowerDNS must be updated immediately. An SSH client with VerifyHostKeyDNS yes that finds a mismatched SSHFP record will refuse to connect and display the same alarming warning as a detected man-in-the-middle attack. That is the correct behaviour, but it is alarming if you caused it yourself.

The update procedure is:

# Remove old records
sudo pdnsutil delete-rrset home.arpa february SSHFP

# Generate new records from the updated keys
ssh-keygen -r february.home.arpa

# Add new records (paste output from above)
sudo pdnsutil add-record home.arpa february SSHFP "4 2 <new-fingerprint>"

# Rectify
sudo pdnsutil zone rectify home.arpa

Do this before attempting to reconnect from any client that has VerifyHostKeyDNS yes configured. The propagation delay is effectively zero since the Authoritative Server updates immediately and the Recursor cache TTL on SSHFP records is short.

The bigger picture

SSHFP is one of those features that is easy to set up, adds genuine security value, and then disappears completely from your awareness. Once the records are published and VerifyHostKeyDNS yes is in your SSH config, every connection to February is cryptographically verified without any additional thought or action. The known_hosts file becomes a secondary fallback rather than the primary trust mechanism.

It also means that any new machine you add to the network, once its SSHFP records are in PowerDNS, is immediately verifiable from any client on the LAN or VPN without the first-connection fingerprint dance. That compounds as the network grows.