known_hosts
known_hosts is the file where the SSH client stores the public host keys of servers it has connected to, usually ~/.ssh/known_hosts. On every connection ssh compares the key the server presents with the saved one, which is how it detects a replaced server or a man-in-the-middle attack. A system-wide copy lives at /etc/ssh/ssh_known_hosts.
What known_hosts is and how host key verification works
On the first connection to a server, ssh shows the fingerprint of its host key and asks whether to trust it. The answer is saved in ~/.ssh/known_hosts. On every later connection ssh compares the key the server presents with the saved one, so a different machine cannot quietly take the server's place. The sshd(8) manual describes the format: an optional marker (@cert-authority or @revoked), a comma-separated list of host patterns, the key type, the base64 key and an optional comment. A non-standard port is written as [host]:port.
web1.example.com,203.0.113.7 ssh-ed25519 AAAAC3Nza...
[web1.example.com]:2222 ssh-ed25519 AAAAC3Nza...
The administrator can prepare a system-wide /etc/ssh/ssh_known_hosts for all users, while the per-user file is updated automatically. Both are checked. This is the client side of the trust relationship: it proves the server is the one you meant, while your own keys, described under key-based authentication, prove who you are.
Reading and managing the file
Entries are managed with ssh-keygen(1) and ssh-keyscan(1). The -F option finds a host (useful when names are hashed), -R removes every key stored for it, and -H converts names to hashed form, moving the original to a file with an .old suffix.
ssh-keygen -F web1.example.com
ssh-keygen -R web1.example.com
ssh-keygen -R "[web1.example.com]:2222"
ssh-keygen -H
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
The last command, run on the server, prints the fingerprint to compare with the one ssh shows on first connection. Hashed entries still work but reveal no host names if the file leaks. The HashKnownHosts option, no by default, hashes new entries only. To test safely, point ssh at a throwaway file with ssh -o UserKnownHostsFile=/tmp/kh-test web1.example.com, and your real file stays untouched. Treat ssh-keyscan output as unverified: the manual says it cannot confirm that the keys are authentic.
StrictHostKeyChecking and the changed host key warning
The StrictHostKeyChecking option in ssh_config(5) controls unknown and changed keys. The default is ask: new keys are added after you confirm, changed keys are refused. yes never adds keys automatically and refuses changed ones. accept-new adds new keys silently but still refuses changed ones, a sensible middle ground for scripts. no (or off) adds new keys and lets connections to changed-key hosts proceed.
When a saved key no longer matches, ssh prints WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! and names the file and line of the offending key. Typical harmless causes are a rebuilt or reinstalled server, or a new machine that reused an IP address. Verify the new fingerprint through the provider console or another trusted channel, then run ssh-keygen -R for that host. Never reflexively delete the line: a changed key is exactly what a man-in-the-middle attack looks like. Even with no, OpenSSH restricts the session after a key mismatch (its source disables password authentication and forwarding), but do not rely on that.
known_hosts in a hardened setup
Trust on first use is the weak moment: whoever answers first is trusted. For servers you care about, compare the fingerprint with the one in your provider console before typing yes, as covered in the SSH hardening guide. For automation and CI, ship a verified host key in ssh_known_hosts and use StrictHostKeyChecking yes instead of no, which turns a one-time check into a guarantee.
Larger fleets can mark a certificate authority with @cert-authority so that signed host keys are trusted without per-host entries, and @revoked blocks a key outright. The VerifyHostKeyDNS option (default no) can check SSHFP records in secure DNS. Behind a bastion host, remember that each internal server has its own entry. After a suspected compromise, treat the old host keys as exposed and follow the incident response guide. A related day-to-day failure is covered in the Permission denied (publickey) guide.
Related terms: SSH, ssh-keygen, sshd_config, Bastion host, Key-based authentication.
Frequently asked questions
What is the known_hosts file?
It is the file where the SSH client records the public host keys of servers it has connected to, normally ~/.ssh/known_hosts. ssh uses it to check that a server is the same one you trusted before.
What does REMOTE HOST IDENTIFICATION HAS CHANGED mean?
The key the server presents differs from the one saved in known_hosts. Common causes are a rebuilt server or a reused IP address, but it can also be a man-in-the-middle attack, so verify the new fingerprint before removing the old entry.
How do I remove a host from known_hosts?
Run ssh-keygen -R followed by the host name, or [host]:port for a non-standard port. It removes all keys stored for that host, including hashed entries.
Is it safe to set StrictHostKeyChecking no?
No. It lets connections to hosts with a changed key proceed, which defeats the protection against spoofing. Use accept-new for automation if you must auto-add first-time keys.
What are hashed entries in known_hosts?
They are lines where the host name is replaced by a hash starting with a pipe character, so a leaked file does not list the servers you use. ssh still matches them, and ssh-keygen -H converts an existing file.
Want to see where your own server stands?
Run the free, read-only server check, or open the Security Lab and watch the detect, contain, recover, verify loop in action.
Get your free server checkOpen the Security Lab