Why should I use Public-Key Authentication for SSH?
if someone hacks into my computer, he doesn't just get my computer, but my server too?
This is potentially true anyway with keyloggers: as soon as you log into your server from the compromised computer, they get the password.
But there are 3 advantages to keys:
1) Cacheable authentication. Enter your passphrase once, carry out multiple ssh commands. This is very useful if you're using something that uses ssh as a transport, like scp, rsync or git.
2) Scaleable authentication. Enter your passphrase once, log into multiple machines. The more machines you have, the more useful this is. If you have 100 machines, what do you do? You can't use the same password (unless it's a clone farm), and you can't remember that many. So you'd have to use a password manager, and you're back to single point of compromise. Effectively the key passphrase is your password manager.
2b) It scales in the other way if you have multiple admins using the same systems, because you can revoke keys from user A without having to tell B,C,D,E,F... that the password has changed.
(This can also be done with individual accounts and sudo, but then you have to provision those accounts somehow)
3) Automation and partial delegation. You can set up SSH to run a particular command when a key connects. This enables an automated process on system A to do something on system B without having full passwordless trust between the two.
(It's a replacement for rlogin/rsh, which was hilariously insecure)
Edit: another advantage to public keys rather than passwords is the common scenario where the server is compromised through a vulnerability. In this case, logging in with a password compromises the password immediately. Logging in with a key does not! I would say this is more common than the admin's originating desktop getting compromised.
If you are using good passwords, this can be secure enough. I usually limit the number of publicly accessible servers to the minimum and allow SSH from specific IP(s) whenever possible.
Also, you can protect your keys by passphrase (password). So, this passphrase must be entered whenever you need to login to your server(s). No one can then use your key unless the right passphrase is provided.
There are similar posts:
- Post from serverfault.
- Post from security stackexchange.
- Post from superuser.
One way where public-key authorization is more secure is when the attacker manages to be man-in-the-middle (MitM) between your client computer and the server, and you don't notice the changing host key (possibly because you didn't have the old key, e.g. because this is the first time using this specific client computer).
(The same applies when the attacker manages to take control of the server, and there are other servers where the same credentials work.)
With standard password-based authentication, you are submitting your password (inside the encrypted connection) in plain text, the genuine server will normally hash it and compare the result to a hash stored in its password database. A MitM attacker could instead take this password, open a connection to the real server, and login there ... and either forwarding the contents to you (so you don't notice anything), or just doing its own evil stuff on your server.
With public-key authentication, the client is basically signing some data known by both server and client to prove it is in possession of the private key, and sending the signature to the server. This signed data includes a session identifier, which depends on random numbers chosen by both client and server, and is thus different for each session. If the MitM opens its own SSH connection to the real server, that one will have a different session ID, and thus the signature provided by the client will not work there.
Of course, as other answers already told, you need to keep your private key secure, e.g. encrypted with a passphrase, or possible on a separate device which only creates signatures after entering a PIN.
OpenSSH can keep its own CA to manage SSH host and client keys and can use revocation lists on them. This could add to the security provided by key-based authentication.
You are right about the "you don't need a password" claim. That is really insecure on the client side.
What makes allowing only public keys for logging in much more secure is the fact that there is no way to brute force access to your server. All an would be attacker can achieve is to put some load on your server - you can employ fail2ban to keep that in check.
For security on the client side you must protect the private key with a good pass phrase. Of course now connecting to the server is more cumbersome than with a password. To overcome this you can make use of ssh agent to store the private key in memory if you intend to connect to the server several times in a row. It is good practice to limit the time for how long a key shall be kept in memory.