Is getting server host key with ssh-keyscan secure?
I am trying to establish SSH connection to a server through a program.
As a pre-requisite to be able to do so, I am getting the publicly available server host key using
ssh-keyscan ``` and adding it to my
known_hostsfile. I don't have the server host key with me before hand.
Can an attacker feed the wrong key to ssh-keyscan? Can we trust the key that we get from ssh-keyscan?
Can an attacker feed the wrong key to ssh-keyscan?
Unfortunately, yes, if the attacker can get a network position between you and the server (via being on either local network, controlling an Internet router along the path, spoofing the server's DNS such that you keyscan the attacker's host instead, etc.).
Can we trust the key that we get from ssh-keyscan?
Well... you can as much as the key you get the first time you connect to any server over SSH. So... in theory no (unless you manually verify it), but in practice, usually people do anyhow. That whole
The authenticity of host ' ()' can't be established.
key fingerprint is SHA256:.
message you get when you try? That's the SSH client telling you "hey, here's what I think is the server's key, does this look right to you?" In theory, you should manually verify it. In practice, people just type "yes" and move on. This only rarely causes security catastrophes.
ssh-keyscanjust automates the process of retrieving that key for inclusion in the known-hosts file without actually logging into the server.
SSH in general relies on either manually verifying the keys, or Trust On First Use (TOFU). This is as true for
ssh-keyscanas for everything else. From the man page:
If an ssh_known_hosts file is constructed using ssh-keyscan without verifying the keys, users will be vulnerable to man in the middle attacks.
Unlike the Public Key Infrastructure (PKI) used for TLS, S/MIME, etc., there's no concept in SSH of a "certificate authority" (CA) or other issuer of keys or certificates. Nor does SSH use the "Web of Trust" (WOT) model from PGP, where keys can be signed by other users (hopefully, some of whom you trust). As such, there's nobody inherent to the SSH ecosystem that you can turn to and ask "hey, is this the right key?". Key verification is still possible, of course, but it must be done manually; either compare the key thumbprint with the expected one as relayed over a secure connection (this is why SSH shows you the thumbprint when you first connect to a server), or install both the public/private key pair (on the server) and the public key (on the client) from the same source (e.g. a flashdrive you've had control of the whole time).
In practice, most people just rely on TOFU. It's not ideal. It means that a new client will always be vulnerable to a MitM (man-in-the-middle) attack unless the expected public key is copied from another client or known to the operator. It means there's no way to rotate the server's public key without either also rotating it manually on every client or triggering a bunch of errors followed by another TOFU operation on each client (and each TOFU is a MitM risk); PKI makes rotating anything except CA keys easy, and with WOT the key holder just signs the new one with the old one and tells everybody to update. Unfortunately, the SSH ecosystem is what it is. While other tooling (e.g. remote configuration utilities) can be used to populate (and even update) known-hosts files, if you don't have such tooling in place or you need to connect to a server that the tooling doesn't supply a trusted key for, you're on your own when it comes to verification.