ssh-keyscan: Prebuild known_hosts in CI
ssh-keyscan connects to a host and prints its public host keys in known_hosts format so you can trust it ahead of time.
This is the right way to make SSH non-interactive in CI: scan the host key into known_hosts so StrictHostKeyChecking can stay on. The one caveat is verifying that key out of band.
What it does
ssh-keyscan opens a connection to each named host and collects its public host keys, printing lines ready to append to known_hosts. It does no authentication, so it gathers keys without credentials. -t limits the key types, -p sets the port, -H hashes the hostnames.
Common usage
# append host keys to known_hosts before deploying
ssh-keyscan host >> ~/.ssh/known_hosts
# specific key types and a custom port, hashed
ssh-keyscan -H -p 2222 -t ed25519,rsa host >> ~/.ssh/known_hosts
# GitHub example for cloning over SSH in CI
ssh-keyscan github.com >> ~/.ssh/known_hostsOptions
| Flag | What it does |
|---|---|
| -t <types> | Key types to fetch (ed25519, rsa, ecdsa) |
| -p <port> | Port to scan (match the SSH port) |
| -H | Hash hostnames in the output |
| -T <sec> | Connection timeout per host |
In CI
Seeding known_hosts with ssh-keyscan lets you keep StrictHostKeyChecking=yes for verified, unattended deploys. Caveat: keyscan trusts whatever answers, so for real security compare the fetched fingerprint (ssh-keygen -lf) against the provider's published host key, or pin a known key string in a secret.
Common errors in CI
Empty output means the host is unreachable or the port is wrong; pass -p to match the SSH port. "getaddrinfo ... Name or service not known" is a DNS failure. If a later connection still fails with "Host key verification failed," the scanned port or hostname differs from what ssh uses, or the host key changed since the scan.