Verify SSH Host Keys and Manage known_hosts

An SSH client must know which server it is talking to before a login is meaningful. Host keys provide that identity. OpenSSH stores accepted host keys in ~/.ssh/known_hosts by default, with optional system-wide files configured by the client policy. The file is not a password store and it is not safe to treat a warning as an invitation to delete an entry.

Understand TOFU and fingerprints

On a first connection, OpenSSH may display a host-key fingerprint and ask whether to continue. This is trust on first use (TOFU): it records the first key observed, then detects a later change. TOFU does not defeat an attacker who controls the first network path. For a production server, obtain the expected fingerprint from an independent trusted channel before accepting it. A console or a previously authenticated management system is better than a fingerprint sent through the same untrusted network.

Fingerprints are short displays of a full public host key. They are not secrets, and this article intentionally uses no live fingerprint. Ask the system owner which fingerprint hash and display format their inventory uses, then compare the same representation on both sides. Do not compare a screenshot, hostname, or key comment as if it were a fingerprint.

Inspect entries safely

# Find the entries that match a host and optional port.
ssh-keygen -F server.example
ssh-keygen -F '[server.example]:2222'

# Display fingerprints for a known-hosts file without connecting.
ssh-keygen -lf ~/.ssh/known_hosts

Use the exact host spelling and port that the client uses. An entry for server.example is different from an entry for [server.example]:2222, and an address may have its own entry. If the file is hashed, ssh-keygen -F can still search it by the supplied host on OpenSSH versions that support hashed lookup. A failed lookup is not evidence that a new key is trustworthy.

ssh-keyscan can retrieve public keys without authenticating, which is useful for collecting candidates during controlled provisioning:

ssh-keyscan -T 5 -t ed25519,ecdsa -p 22 server.example 2>/dev/null

Never pipe that output directly into known_hosts as a trust decision. Compare each key or fingerprint with an out-of-band source first. The command’s network result is unauthenticated and can be changed by an active intermediary.

Handle a changed key deliberately

“REMOTE HOST IDENTIFICATION HAS CHANGED” is a security event until explained. Stop and determine whether the host was rebuilt, its host key was intentionally rotated, its name or address was reassigned, or traffic is being intercepted. Confirm the new fingerprint through the independent channel, check the deployment and change records, and verify that you are using the intended hostname and port. A warning is not fixed by retrying with a different username.

Before editing, preserve the evidence and make a timestamped backup with permissions that do not expose the file to other users:

cp -p ~/.ssh/known_hosts ~/.ssh/known_hosts.before-change
chmod 600 ~/.ssh/known_hosts.before-change

Only after the replacement has been independently verified should an administrator remove the precise stale entry. On OpenSSH versions that provide it, ssh-keygen -R can remove matching entries for one host; specify the exact hostname or bracketed host-and-port, inspect the result, and retain the backup:

ssh-keygen -R server.example -f ~/.ssh/known_hosts
ssh-keygen -R '[server.example]:2222' -f ~/.ssh/known_hosts

Do not use ssh-keygen -R as a reflexive workaround, do not remove the whole file, and do not use StrictHostKeyChecking=no to suppress evidence. If this OpenSSH release lacks -R, edit only the verified matching line with a reviewable tool or replace the file from a trusted configuration-management source. Keep the old entry and the reason for the change in the change record.

Hashing and maintaining known_hosts

Hashed hostnames reduce the value of a stolen known_hosts file by hiding names from casual inspection; they do not encrypt keys, authenticate a server, or hide a host from a determined analysis. New entries can be written in hashed form by the client policy:

Host *
    HashKnownHosts yes

To hash existing cleartext hostnames, first make a protected backup and review the change. On OpenSSH versions supporting it, ssh-keygen -H -f ~/.ssh/known_hosts rewrites the file and leaves a file with a .old suffix. Confirm that the resulting file is readable by the intended account and that expected lookups still work. Do not hash a file in place without a backup, and remember that hashing is privacy housekeeping—not host verification.

Keep host-key files owned by the account that uses them, writable only by that account (normally mode 600), and backed up according to the organization’s recovery policy. A system-wide known-hosts file should be managed by the operating system or configuration management, not casually edited by individual users.

Continue through the sequence

Return to How SSH Establishes a Secure Connection for the protocol context. Continue with Create and Protect SSH Keys, then learn about ssh-agent and hardware-backed keys.

References