🗓️ 18042026 0000
📎 ssh
Utility that fetches a remote host's public SSH host keys without logging in. Used to pre-populate known_hosts so that first-time SSH/SCP/rsync connections don't prompt for interactive trust — critical in automation where no human is present to type "yes".
Why it matters
SSH uses Trust On First Use (TOFU): on first connection, the client asks the user to verify the server's host key fingerprint, then caches it in ~/.ssh/known_hosts. Subsequent connections check against that cached key to detect MITM swaps.
Automation breaks this model — scripts can't answer the prompt. Two bad workarounds exist:
StrictHostKeyChecking=no— disables verification entirely, MITM-vulnerable- Piping
yesinto ssh — same problem, just uglier
ssh-keyscan is the right answer: pre-seed known_hosts ahead of time so verification still happens, just without the prompt.
Common usage
# Fetch host keys and append to known_hosts
ssh-keyscan github.com >> ~/.ssh/known_hosts
# Specific key types (ed25519 is preferred for modern hosts)
ssh-keyscan -t ed25519,rsa github.com >> ~/.ssh/known_hosts
# Non-standard port
ssh-keyscan -p 2222 internal.example.com >> ~/.ssh/known_hosts
# Multiple hosts at once
ssh-keyscan host1 host2 host3 >> ~/.ssh/known_hosts
# Quiet mode — suppress banner/comment lines
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
The -H flag hashes hostnames in the output — same format OpenSSH writes by default. Prevents an attacker who reads known_hosts from enumerating every host you've ever connected to.
Verifying what you fetched
ssh-keyscan on its own inherits the trust problem it's trying to solve — if you scan during a MITM, you cache the attacker's key. Verify against an out-of-band source:
# Compute fingerprint of the fetched key
ssh-keyscan github.com | ssh-keygen -lf -
# 256 SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU github.com (ED25519)
Compare the fingerprint to the vendor's published list (e.g. GitHub's SSH key fingerprints).
Typical automation pattern
CI/CD cloning a private repo over SSH:
mkdir -p ~/.ssh
ssh-keyscan -t ed25519 github.com >> ~/.ssh/known_hosts
git clone git@github.com:org/repo.git
Docker image baking in trusted hosts:
RUN mkdir -p /root/.ssh && \
ssh-keyscan -t ed25519 github.com >> /root/.ssh/known_hosts
Don't blindly scan in hostile networks: ssh-keyscan trusts whatever responds on port 22. If run on an attacker-controlled network before fingerprints are verified, you'll cache the attacker's key and silently hand them future sessions. Always cross-check fingerprints against a vendor-published source, or distribute a pre-validated known_hosts file.