Populate known_hosts for a new server
-H hashes the hostname in the file — the same thing ssh itself does on a
first connection (see ssh-client).
Pre-populate known_hosts with server keys — skip the interactive "yes" on first ssh.
ssh-keyscan server.example.com
the host's public keys (to stdout)
ssh-keyscan -H server.example.com >> ~/.ssh/known_hosts
add, hashing the hostname
ssh-keyscan -t ed25519 server.example.com
only one key type
ssh-keyscan -p 2222 server.example.com
non-standard port
ssh-keyscan -f hosts.txt
a list of hosts from a file
ssh-keygen -lf <(ssh-keyscan server.example.com 2>/dev/null)
fingerprints to verify
ssh-keyscan queries one or more servers and prints their public host
keys — the same thing ssh fetches on a first connection when it asks "The
authenticity of host … can't be established, continue connecting?".
ssh-keyscan does this without the interactive prompt and without any
verification: it cannot confirm the key really belongs to that server
(see "Danger zone") — it only collects it for a later check or for
populating known_hosts.
The typical use is automation: preparing known_hosts ahead of time (for CI,
cloud-init, freshly created lab VMs) so the first ssh/scp/rsync in a
non-interactive script doesn't get stuck on the new-host prompt.
Below are the main flags; the full list is in man ssh-keyscan.
| Option | What it does | Example |
|---|---|---|
-H |
Hash hostnames in the output — the same way known_hosts stores them by default. | ssh-keyscan -H server.example.com >> ~/.ssh/known_hosts |
-t TYPE |
Query only the given key type (ed25519, rsa, ecdsa). | ssh-keyscan -t ed25519 server.example.com |
-p PORT |
SSH port, when the server doesn't listen on 22. | ssh-keyscan -p 2222 server.example.com |
-f FILE |
Read the list of hosts from a file (one per line) instead of arguments. | ssh-keyscan -f hosts.txt |
-4 |
Query over IPv4 only. | ssh-keyscan -4 server.example.com |
Nothing found. Try a shorter query.
-H hashes the hostname in the file — the same thing ssh itself does on a
first connection (see ssh-client).
Handy before rolling out a group of VMs, or in cloud-init/an Ansible
playbook, when known_hosts is built in one step for a whole fleet.
A hashed name (-H) in known_hosts won't match if you connect using a
different name/alias or port — known_hosts entries are tied to a specific
host:port pair. Add the key under the name you actually connect with.
Expected: the server now has a new host key. Remove the old line
(ssh-keygen -R server.example.com) and add the new one with
ssh-keyscan — but only after confirming the server was really reinstalled
and not impersonated (see "Danger zone").
The host isn't reachable on the SSH port (down, firewalled, wrong port —
check -p), or DNS doesn't resolve the name. Try ssh -v to the same host
for diagnostics.
The command simply asks the server "show me your key" — with no check that
it's really the server it claims to be. Blindly running ssh-keyscan ... >>
known_hosts in a script disables SSH's main defense against MITM (server
impersonation): from then on, ssh trusts whatever key was collected, even
a forged one. It's safe only when the path to the server is trusted (same
data center, private network) or the fingerprint is verified separately (a
phone call, the provider's console, cloud-init output at VM creation).
Found an inaccuracy? Report an error in the article