Referring to this post. We learned about ssh today, and I know that you have to add your public key to the "authorized_keys" manually on the server, but the very first time you log into the server, it will add itself to your (client-side) "known_hosts". Why are you not automatically updated to be a part of the server's "authorized_keys" upon first access (after presenting your password and authenticating yourself)?
2 Answers
SSH's known_hosts
file exists to support server authentication. Unlike TLS (HTTPS, etc.) where server public keys are presented in a certificate that identifies the server and is signed by a trusted third party (certificate authority or CA), SSH mostly relies on "trust on first use" (TOFU) for server authentication. In theory, the user is supposed to verify the server's public key's thumbprint before accepting the connection, which the user receives through an out-of-band channel (though in practice people rarely do).
The SSH client then stores that server:public key thumbprint pair in known_hosts
so that the user doesn't have to manually confirm the key each time (and, if it ever changes, the client can raise an alarm). Thus, known_hosts
is serving a security purpose: it ensures that - even in the common case where the user doesn't really validate the server's public key - there's a degree of server authentication going forward because a change to the public key (because the server is being impersonated or the connection is being tampered with) is detectable.
By comparison, the authorized_keys
file is totally optional; there is no requirement for a user to even have a key pair (only the server needs one), and if password authentication is enabled like you describe, then the user doesn't need to use public key auth even if they have a key pair. Indeed, unless the server's configuration changes, password authentication will continue to be possible even if the user uploads a public key to authorized_keys
. Public key authentication can be more convenient than password authentication if you're using an SSH agent and only connecting from clients that are already configured with your key pair, but in general passwords are the default method of authentication for now. Public key auth isn't even necessarily more secure (though in practice it usually is); unlike a password, a private key can be physically or logically stolen, potentially undetectably, and even if it's encrypted the passphrase can be brute-forced offline without any way for the victim to know.
Furthermore, automatically uploading the same file to multiple servers could be a privacy breach; by default the SSH client uses the same key pair for every server, and it is therefore possible for one server (that knows your public key) to check another server to see if you've ever logged in there too. A more modern public-key-based protocol, such as FIDO2, would prevent this. For example, with SSH, you might have one "master key" that lives only on your machine and unlocks a whole collection of site-specific key pairs (saving you the hassle of needing to memorize many key passphrases). The client could then automatically generate a new key pair for each server, sending the public key along with a one-time enrollment credential (password, essentially) that would not be usable in the future. However, this is just not how SSH was designed, and it would imply a significant update of the protocol.
Automatically updating authorized_keys
wouldn't make any sense. If the client uses password authentication, then there isn't any client-side key to begin with, as CBHacking already said. If the client uses public-key authentication, then the server must have a list of known public keys beforehand. They obviously cannot just accept any key, because then the whole authentication procedure would be pointless.
Besides that, allowing anybody to connect to any account via passwords is not the only way to use SSH and certainly not a particularly secure one. If the server is in any way critical, there will be much more strict rules for SSH authentication, e.g.
- public-key authentication only (so the
authorized_keys
must already exist) - keys are carefully added and removed to ensure that only authorized persons have access
- if necessary, specific restrictions (e.g. in terms of permitted commands) may be imposed for individual keys
None of this would work well with an authorized_keys
file that is somehow updated automatically.
-
My proposal was that you would append the client's
id_rsa.pub
to the server'sauthorized_keys
upon first log-in, similar to how theknown_hosts
file on the client is appended to. Commented Jun 7, 2023 at 4:44 -
As I've said, if the client uses password authentication, there is no public key involved at all, so what key is the server supposed to add to the
authorized_keys
file? And if the client uses public-key authentication, then the server must know which public key is valid before the client is logged in. I could imagine a hypothetical scenario where the client logs in via password but then presents their public key to be added to theauthorized_keys
file, but this makes little sense and conflicts with more security-oriented uses of SSH (as described above).– Ja1024Commented Jun 7, 2023 at 4:49 -
I see. In systems I've accessed, you typically log in via password, and you add your public key to
authorized_keys
, as you mentioned. I was just wondering why this step is necessary. Commented Jun 7, 2023 at 4:51