Cyber Security

SSH Host Keys - What That First-Connection Warning Actually Protects

SSH Host Keys - What That First-Connection Warning Actually Protects

The first SSH connection to a server often pauses before asking for a password or using a user key. It shows a fingerprint and asks whether the host should be trusted. The prompt is easy to treat as a speed bump: type yes, continue, and forget it. But what decision is being made at that moment?

The question is not whether the connection will be encrypted. It is whether the machine answering at that address is the machine we intended to reach. That distinction matters on a home server as much as it does on a large network. A strongly encrypted conversation with an impostor is still a conversation with an impostor.

One SSH Connection, Two Directions of Trust

SSH commonly performs two authentications that are easy to mix up. The server authenticates itself to the client with a host key. Later, the client authenticates the user to the server, perhaps with a password or a user key stored in ~/.ssh/id_ed25519. The SSH protocol architecture in RFC 4251 places server authentication in the transport layer and user authentication in a separate protocol above it.

These checks answer different questions:

  • Host authentication: Is this the expected server?
  • User authentication: Is this user allowed to enter that server?

Installing a user public key in authorized_keys does not answer the first question. Likewise, recognizing a server's host key does not grant a user permission to log in. Both directions matter.

What the Fingerprint Represents

An SSH server holds one or more host-key pairs. The private part stays on the server; the public part can be presented to clients. During key exchange, the server proves that it controls the corresponding private key. A fingerprint is a shorter hash representation of that public key, designed to be compared more easily than a long encoded key.

Current OpenSSH displays fingerprints using SHA-256 by default, according to its client configuration manual. A matching fingerprint supports a precise but limited conclusion: the endpoint can use the private key corresponding to the expected public host key. It does not prove that the operating system is uncompromised, that every service is configured safely, or that the person operating the server is trustworthy.

The missing piece is the association between a name and a key. Cryptography can show that the same private key is present, but the client still needs a trustworthy reason to believe that the key belongs to server.example.net.

The First Connection Has a Bootstrap Problem

On a later connection, the SSH client can compare the presented key with one it has already stored. On the first connection, there may be no stored value to compare. This is a trust bootstrap problem: where does the initial trusted fingerprint come from?

RFC 4251 describes a practical strategy often called trust on first use, or TOFU: accept a host key on the first connection, save it locally, and reject or warn about unexpected changes later. This is useful because it detects an attacker who appears after the first trusted connection. It cannot, by itself, detect an attacker who was already in the middle of the very first unverified connection. The RFC states that such a connection can still resist passive eavesdropping while remaining vulnerable to an active man-in-the-middle attack.

TOFU is therefore a tradeoff, not nonsense and not proof. On an isolated network whose path and address assignment are under one administrator's control, that tradeoff may be consciously accepted. Across an airport network, an unfamiliar provider, or any path where interception is plausible, independent verification is more valuable.

A Better First-Connection Workflow

The expected fingerprint should arrive through a channel independent of the SSH connection being checked. Depending on who controls the server, that might mean:

  • reading the host-key fingerprint directly from the server's physical or provider console;
  • asking the administrator through an already authenticated communication channel; or
  • checking an operator's fingerprint page delivered through an independently trusted HTTPS connection.

For example, GitHub publishes its SSH host-key fingerprints so users can compare the value shown by their SSH client. The important pattern is not GitHub's current fingerprint value, which can change, but the separation between the SSH connection and the channel publishing the expected identity.

On a server console, an administrator can display the fingerprint of an Ed25519 public host key with:

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

The sudo may not be necessary if the public file is readable. The key point is to run the command through a console or administrative path already trusted, not through the unverified SSH session whose identity is in question. Compare the complete algorithm and fingerprint shown there with the client prompt before accepting it.

What known_hosts Remembers

After acceptance, OpenSSH normally records the association in ~/.ssh/known_hosts. The OpenSSH client manual explains that the client checks this database on future connections and warns when a host's identification changes. A system administrator can also maintain a system-wide file at /etc/ssh/ssh_known_hosts.

A record can be inspected without manually searching long or hashed lines:

ssh-keygen -F server.example.net

For a service on a non-default port, use the bracketed host-and-port form:

ssh-keygen -F '[server.example.net]:2222'

The official ssh-keygen manual documents -F for finding entries, including hashed host names. Hashing the names in known_hosts can reduce the information revealed if that file is copied, but it does not change the underlying host-authentication decision.

A Changed Key Is a Signal, Not a Verdict

A prominent changed-key warning is designed to interrupt the connection. It may indicate an impersonation attempt, DNS or routing interference, or another path to the wrong machine. It may also follow a legitimate server reinstall, replacement, restored image, or intentional host-key rotation. The warning alone cannot identify which explanation is correct.

A cautious response is a short investigation:

  1. Stop the connection. Do not enter a password or send sensitive commands while the identity is unresolved.
  2. Confirm the destination. Check the hostname, IP address, port, SSH configuration alias, and any jump host involved.
  3. Ask what changed. Look for a documented rebuild or rotation, or contact the administrator through a separate trusted channel.
  4. Obtain the new fingerprint independently. Use the trusted console or another authenticated source.
  5. Compare before replacing. Only remove the old association after the new identity and the reason for the change make sense together.

Once verification is complete, OpenSSH can remove the old record safely even when the host name is hashed:

ssh-keygen -R server.example.net

For a custom port:

ssh-keygen -R '[server.example.net]:2222'

Running -R first and investigating later reverses the safety mechanism. It makes the warning disappear without resolving why it appeared.

Why ssh-keyscan Is Not Verification

ssh-keyscan is useful for collecting public host keys, especially when preparing a known-hosts file for many machines:

ssh-keyscan server.example.net

However, collecting a key from the same network path does not authenticate it. The ssh-keyscan manual explicitly says that the tool cannot verify the authenticity of the keys it obtains. An attacker able to intercept the scan can substitute a key just as they could during an unverified SSH connection.

This makes the common pattern ssh-keyscan ... >> ~/.ssh/known_hosts incomplete as a security bootstrap. It automates collection, not trust. The collected key still needs independent verification, unless the operator has consciously chosen a model in which that network path is already trusted.

Automation Should Fail Clearly

Interactive prompts are inconvenient in deployment jobs, containers, and scheduled scripts. Disabling checking may make a pipeline run, but it also removes the endpoint identity check that caused the prompt. A stronger pattern is to provision a verified known_hosts file or a trusted host certificate authority before the job starts, then make unknown or changed identities fail rather than pass silently.

For a small home lab, individually pinned host keys may be understandable and manageable. For a larger or frequently rebuilt fleet, RFC 4251 and the OpenSSH manuals describe another model: trust a host certificate authority, then let servers present host certificates signed by that CA. This reduces the number of individual keys clients must pin, but moves substantial trust to the CA and its operational security. It is an alternative architecture, not a free upgrade.

The Limits of a Correct Match

Host-key verification narrows one risk: connecting to an unexpected endpoint. It does not replace patching, access control, user-key protection, logging, or careful server administration. It also does not make a compromised server safe; an attacker controlling the legitimate server may be able to use its legitimate host key.

There is also a human limit. Long fingerprints are easy to skim badly, and an independent channel may itself be compromised. The realistic goal is not perfect certainty from one prompt. It is to avoid turning a meaningful identity check into a reflex.

Conclusion

The SSH fingerprint prompt asks a modest but essential question: which server are we about to trust? On the first connection, the strongest answer comes from comparing the fingerprint through an independent channel. On later connections, known_hosts turns that initial decision into a continuity check.

When a key changes, neither panic nor automatic deletion is a good diagnosis. Stop, verify the destination and the reason, obtain the new fingerprint separately, and only then update the stored record. That small pause preserves the part of SSH that encryption alone cannot provide: confidence about who is at the other end.

References