.Ssh

SSH Known Hosts: Host Key Verification and Secure Server Identity

Learn how SSH known_hosts verifies server identity, handles first connections and changed keys, and supports safe host key management, automation, and rotation.

The SSH known_hosts file is a trust database used by an SSH client. It records public keys that identify SSH servers. It does not store your password, private login key, agent credentials, or other user authentication secrets.

When you connect, the server proves possession of a private host key by presenting the corresponding public key during SSH setup. Your client compares that key with trusted information in known_hosts. This helps detect impersonation and man-in-the-middle attacks, where an attacker attempts to stand between you and the real server.

How SSH host verification works

  1. The client resolves the hostname and opens a connection to the server.
  2. The server presents one of its host keys during connection setup.
  3. The client selects the relevant known-hosts records using the hostname, address, port, aliases, and configuration.
  4. The presented key is compared with the saved trusted key or trust rule.
  5. A matching key allows the connection to continue. An unknown key may cause a prompt. A changed key normally causes a warning and rejection.

A valid user password or private key does not override a host key mismatch. User authentication happens only after the client has established confidence in the server identity.

Host keys, algorithms, and fingerprints

A host key is a cryptographic identity key held by an SSH server. The server protects the private portion, while the public portion can be distributed to clients. During the connection, the server proves that it controls the private key without sending that private key to the client.

Common host key algorithms include ssh-ed25519, ECDSA, and RSA. Ed25519 is widely preferred for modern deployments because it provides strong security with compact keys and signatures. RSA remains common when configured with modern signature algorithms and adequate key sizes. DSA keys, usually identified as ssh-dss, are deprecated in modern OpenSSH because of weak design limits and are generally disabled.

A server can offer several host keys at the same time, such as an Ed25519 key and an RSA key. Therefore, one hostname can have multiple valid entries in known_hosts. Different clients or algorithm preferences may select different keys.

A host key fingerprint is a short digest of a public host key. It is easier to read over a phone call, ticket, console, or other trusted channel than the complete encoded key. A fingerprint is useful only when the value comes from a source independent of the connection being verified.

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

Known-hosts files and scope

The usual per-user database is ~/.ssh/known_hosts. SSH reads it for the account that starts the connection. On Linux and Unix systems, the home directory is represented by ~. On macOS, the same form normally refers to the user’s home directory. On Windows OpenSSH, the file is normally in the user’s profile, in a path equivalent to C:\Users\username\.ssh\known_hosts.

Some OpenSSH installations also recognize the older or additional per-user file ~/.ssh/known_hosts2. System-wide databases can include /etc/ssh/ssh_known_hosts and, where supported, /etc/ssh/ssh_known_hosts2.

Known Hosts Files by Scope

File | Scope | Typical purpose | Managed by

~/.ssh/known_hosts | One user | Hosts personally trusted by the user | User or user-specific tools

~/.ssh/known_hosts2 | One user | Legacy or additional per-user database | User or local policy

/etc/ssh/ssh_known_hosts | System-wide | Centrally trusted hosts for many accounts | System administrator

/etc/ssh/ssh_known_hosts2 | System-wide | Legacy or additional system database | System administrator

OpenSSH combines configured user and global sources during lookup. The exact files and order can be changed with UserKnownHostsFile and GlobalKnownHostsFile. A user file is useful for personal trust decisions. An organization may distribute a managed global file so that servers, bastions, build agents, or administrative workstations start with verified fleet keys.

The first connection and TOFU

If SSH has no matching record for a destination, it normally displays an authenticity prompt. The prompt identifies the host, the selected key type, and a fingerprint. You can reject the key, accept it, or pause and verify the fingerprint before accepting it.

Trust On First Use (TOFU) means that the first accepted key becomes the local baseline. Later connections are checked against that baseline. TOFU detects changes after the first connection, but it cannot prove that the first connection was safe. For important systems, obtain the fingerprint through a server console, a trusted administrator, provisioning records, or another authenticated channel before answering yes.

After acceptance, SSH writes the server’s public key to the applicable user known-hosts file, provided the directory and file are writable.

Entry format and interpretation

A typical entry contains a host pattern, a key algorithm, a base64-encoded public key, and an optional comment.

server.example.com,192.0.2.10 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... administrator-label

Known Hosts Entry Components

Component | Example form | Purpose | Notes

Optional marker | @cert-authority or @revoked | Changes how the key is interpreted | Used for advanced trust rules

Host patterns | server.example.com,192.0.2.10 | Names and addresses that identify the destination | Comma-separated aliases are allowed

Port-specific pattern | [server.example.com]:2222 | Identifies a non-default SSH port | The brackets and port are significant

Wildcard pattern | *.example.com | Matches a set of hostnames | May be combined with exclusions

Negated pattern | !test.example.com | Excludes a matching host | A matching negation prevents the line from applying

Key type | ssh-ed25519 | Identifies the public-key algorithm | Other examples include RSA and ECDSA

Public key | Base64 text | Contains the encoded public key | It is not normally secret

Comment | administrator-label | Helps humans identify the record | Comments do not determine trust

For a connection to port 22, a hostname may appear in its ordinary form. For a custom port, SSH uses the bracketed form because the port is part of the server identity:

[example.com]:2222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...

An address, hostname, alias, and custom port can all select different records. Connecting with an IP address does not necessarily use the entry saved for the DNS name unless both identities are present in the same entry or otherwise configured to share an identity.

Hashed hostnames

With HashKnownHosts yes, OpenSSH can store host identifiers in hashed form. This makes it harder for someone who reads the file to learn which systems the user has contacted. Normal SSH lookups still work because the client can hash a candidate hostname and compare it with the stored value.

Hashing obscures host names; it does not encrypt the public key, protect the file from modification, or replace operating-system access controls. It also makes manual inspection less convenient.

Host *
    HashKnownHosts yes
    StrictHostKeyChecking ask

The ssh-keygen lookup and removal operations also support hashed entries:

ssh-keygen -F example.com -f ~/.ssh/known_hosts
ssh-keygen -F '[example.com]:2222' -f ~/.ssh/known_hosts

Verification outcomes

SSH Host Verification Outcomes

Observed condition | Meaning | Security risk | Recommended action

Matching saved key | The presented server key matches a trusted record | Low, assuming the original record was trusted | Continue and monitor normal authentication

No saved key | The destination is unknown to this client | First-use interception is possible | Verify the fingerprint independently before accepting

Changed saved key | The destination presented a different key | Could be an attack or a legitimate change | Stop and investigate before modifying the file

Revoked key | A matching key is marked as revoked | The key must not be trusted | Do not bypass the rejection; investigate replacement

Certificate signed by trusted CA | The host key is authorized by a configured certificate authority | Depends on CA protection and policy | Validate the CA distribution and certificate scope

Changed host key warnings

A message such as REMOTE HOST IDENTIFICATION HAS CHANGED is security-significant. Do not solve it by blindly deleting the line or disabling checking.

Legitimate explanations include a host rebuild, operating system reinstall, replacement or restored backup, intentional key rotation, DNS reassignment, a changed load-balancer backend, or reuse of an IP address. Suspicious explanations include DNS poisoning, network interception, a compromised server, or connecting to the wrong machine.

  1. Stop the connection and note the hostname, address, port, and line or file reported by SSH.
  2. Confirm which system you intended to reach and whether maintenance, migration, or key rotation occurred.
  3. Obtain the current fingerprint from a trusted administrator, server console, provisioning system, or other independent channel.
  4. Locate the old record with ssh-keygen -F.
  5. Remove only the confirmed obsolete host-and-port identity with ssh-keygen -R.
  6. Reconnect and verify the newly presented fingerprint before accepting it.
ssh-keygen -F example.com -f ~/.ssh/known_hosts
ssh-keygen -R example.com -f ~/.ssh/known_hosts
ssh-keygen -R '[example.com]:2222' -f ~/.ssh/known_hosts

If the same logical service is behind several backends, all legitimate keys must be accounted for. Inconsistent backend keys can produce warnings even when no attacker is present.

Managing entries safely

Host Key Management Commands

Task | Command pattern | When to use it | Caution

Find a hostname | ssh-keygen -F example.com -f ~/.ssh/known_hosts | Inspect plain or hashed matches | Use the exact identity used by SSH

Find a custom port | ssh-keygen -F '[example.com]:2222' -f ~/.ssh/known_hosts | Inspect a non-default port | Brackets and port are required

Remove a hostname | ssh-keygen -R example.com -f ~/.ssh/known_hosts | Remove a verified-obsolete record | Investigate before removing

Remove a custom port | ssh-keygen -R '[example.com]:2222' -f ~/.ssh/known_hosts | Remove only that host-and-port record | Do not remove the bare hostname accidentally

Display a key fingerprint | ssh-keygen -lf host-key.pub | Compare a public key with a trusted fingerprint | The source of the key must be trusted

Collect advertised keys | ssh-keyscan -t ed25519,rsa example.com | Controlled provisioning or comparison | Output is not proof of identity by itself

ssh-keyscan retrieves keys offered by a server, but it does not authenticate the server. An attacker can answer a scan just as an attacker can answer an SSH connection. Add its output only after comparing it with an independently obtained key or fingerprint.

Back up the file before substantial changes. Manual editing can be appropriate for carefully reviewed, centrally managed data, but preserve line structure, ownership, and permissions. Deleting the entire file is usually an unsafe and overly broad response because it removes trust records for every server and causes many future first-use decisions.

Important SSH configuration options

Key SSH Configuration Options

Option | Default behavior or common values | Use case | Security impact

UserKnownHostsFile | User known-hosts file; can specify one or more files | Select a personal or dedicated automation database | A wrong or writable-by-others path can weaken or confuse trust decisions

GlobalKnownHostsFile | System-wide database paths | Centrally distribute trusted fleet keys | Managed files improve consistency; protect them from unwanted changes

StrictHostKeyChecking | Common values are yes, ask, and no | Control unknown and changed key behavior | yes rejects unknown keys; ask prompts; no permits risky automatic acceptance

UpdateHostKeys | Controls whether a trusted server may advertise additional keys | Plan gradual host key rotation | Useful after an existing key is trusted; it does not make an untrusted first connection safe

HashKnownHosts | Often disabled unless enabled by policy | Reduce disclosure of contacted hostnames | Improves privacy but reduces manual readability

VerifyHostKeyDNS | Usually disabled or policy-dependent | Use DNS SSHFP records as supporting verification | Useful only with trustworthy DNS validation and correctly maintained records

HostKeyAlias | Uses the connection hostname by default | Give a changing endpoint a stable logical lookup identity | Prevents accidental identity mixing only when the alias is deliberately chosen

For a stable logical identity reached through a temporary address, a configuration entry might look like this:

Host app-through-bastion
    HostName 192.0.2.25
    HostKeyAlias app-production

Here, app-production is used for known-hosts lookup rather than the endpoint address. Use this only when the alias truly represents the intended server identity; otherwise it can hide a mistaken endpoint.

VerifyHostKeyDNS can use SSHFP records published in DNS. This is most useful when DNS data is protected by DNSSEC and the organization maintains the records accurately. An ordinary unsigned DNS response should not automatically be treated as an authoritative replacement for an independent fingerprint check.

Automation and fleet administration

Noninteractive SSH cannot answer an authenticity prompt. If a host is not already trusted, a deployment or CI job may fail. Automatically accepting any new key, for example with an unrestricted equivalent of “accept all,” allows an interception to become the stored baseline.

Safer approaches include pre-seeding verified keys during provisioning, using a dedicated known-hosts file, distributing a protected system-wide database through configuration management, or using SSH host certificates. Keep strict checking enabled:

ssh -o UserKnownHostsFile=/path/to/verified_known_hosts -o StrictHostKeyChecking=yes user@example.com

For large environments, plan host key rotation. Publish replacement keys before retiring old ones, use UpdateHostKeys where appropriate, update managed databases, test every client class, and define a process for emergency revocation. Load balancers and autoscaling groups should present a consistent identity strategy or use host certificates.

Advanced trust models

SSH host certificates are public host keys signed by an SSH certificate authority, usually called a host CA. Instead of distributing every server key separately, clients trust the CA public key and verify certificates issued for permitted host names.

@cert-authority *.example.internal ssh-ed25519 AAAA...trusted-ca-public-key

The abbreviated key above is illustrative. A real CA public key must be securely distributed and carefully protected. The host certificate’s names, validity, and signing authority must match organizational policy.

An @revoked entry marks a host key that must not be trusted. Revocation rules are useful when a private host key may have been exposed or when a key must be retired urgently.

@revoked server.example.com ssh-ed25519 AAAA...revoked-public-key

CA-based trust and centrally managed key databases reduce per-host administration, but they move responsibility to CA key protection, policy, distribution, and timely revocation.

Permissions and file safety

Known-hosts entries normally contain public information, but the file must still be protected from unwanted modification. An attacker who can alter it may be able to cause the client to trust a malicious key on a future connection.

Review ownership and permissions on the home directory, ~/.ssh, the known-hosts file, and any SSH configuration files. The SSH client must be able to read trusted files and usually write the user file when accepting a new key. If it cannot write, you may receive the prompt repeatedly.

When behavior is unexpected, inspect the effective configuration:

ssh -G example.com

Check which account launches SSH, which home directory it uses, whether UserKnownHostsFile points to a temporary or inaccessible location, and whether file ownership permits the intended account to read or update the database. Related client identity files include SSH client configuration, Ed25519 user keys, RSA user keys, and ECDSA user keys.

Troubleshooting examples

Changed host identification warning

Verify the new fingerprint independently, find the exact old record with ssh-keygen -F, remove only the confirmed obsolete identity with ssh-keygen -R, and reconnect only after verification.

Host key verification failed in a script

The key may never have been preloaded, the script may use another account or file, or the host key may have changed. Use a dedicated verified file and set UserKnownHostsFile explicitly. Keep StrictHostKeyChecking=yes.

Custom-port entry cannot be found

Use [hostname]:port in both the lookup and removal command. This syntax also works when the hostname is hashed.

SSH asks every time

Use ssh -G to inspect effective settings. Then check the home directory, .ssh directory, file ownership, write access, and any configured known-hosts path.

Legitimate server has an unexpected key

Check whether the server selected another supported algorithm, whether a load-balanced backend differs, or whether an alias, IP address, or port selects another identity. Consider managed records, a deliberate HostKeyAlias, or host certificates.

Exam-relevant summary

  • known_hosts verifies server identity; it is not a user credential store.
  • TOFU records the first accepted key but does not prove that the first connection was safe.
  • A changed-key warning may indicate maintenance or an attack. Verify independently before changing the file.
  • Custom ports use [hostname]:port.
  • ssh-keyscan collects keys but does not independently authenticate them.
  • ssh-keygen -F finds records, and ssh-keygen -R removes a verified-obsolete identity.
  • Keep strict host checking enabled in automation and preload verified keys.
  • Host certificates, @cert-authority, @revoked, and DNS SSHFP records support larger or more advanced trust models.