Ssh Key Authentication

ssh-key authentication

intro

When connecting to a remote server, you have to authenticate yourself. The standard way to do this is by transmitting a password through an encrypted connection that is established between your local computer and the remote server. However, this is susceptible to man-in-the-middle attacks, meaning that your password can be intercepted. It is safer to use ssh-keys to authenticate yourself (note: this only verifies that you are the correct person to the server, not that the server you are logging into is the correct one. For that, you need to check the fingerprint of the server – which can be done automagically if you have signed gpg keys and are using the monkeysphere.

how to set up an ssh-key for your local machine

On your local computer, you can generate a key by doing the following:

client:~$ ssh-keygen -t rsa -b 2048
Enter passphrase (empty for no passphrase): …
Enter same passphrase again: …

This creates both a public and a private key:

client:~$ ls -l .ssh
-rw------- 1 user user  1675 2007-01-24 14:41 id_rsa
-rw------- 1 user user   395 2007-01-24 14:41 id_rsa.pub

how to set up the ssh-key on the remote server

You should send `id_rsa.pub` to the server administrator. Alternatively, if you have access, you can place it on the server yourself:

client:~$ scp .ssh/id_rsa.pub user@remote.server:/home/user/

Then, you need to place it in your `authorized_keys` file:
client:~$ ssh remote.server
...
server:~$ cat id_rsa.pub >> .ssh/authorized_keys

You should now be able to login using your ssh-key!

explanation

Using ssh-keys, a file on your local computer is used as a key to ‘unlock’ your access to the remote server. However, this file is also protected by a passphrase. Thus, when you are entering your password, you only enter it into your local computer to unlock this file, rather than transmitting it across the internet – where it could potentially be intercepted. This greatly reduces the opportunities for an attacker to gain access to your account on the remote server (for example, through trying ‘dictionary attacks’ when the attacker tries to guess your password by using pre-existing lists of words).

 

Nice write-up! You could simplify the installation of the ssh-key on the remote server by doing:

$ ssh-copy-id user@remote.server

If you need to specify a different key than the default, you can use the -i switch.

Might be good to add something to this document about how to add your key to your agent, how to tell that the agent has your key, and debugging!

 
 

yep, help welcomed ;-)

i started this as i was about to write instructions to someone in an email, so thought it better to stick on here and then just give them the link.

 
 

by the way, i’ve never used ssh-copy-id but doesn’t that still require you to transmit your password at least once across the wire?

 
 

yes, ssh-copy-id requires some alternate form of ssh authentication, just like your scp invocation above does. Note that transmitting your key to the system administrator also requires (or should require) some form of authentication too (e.g. an OpenPGP-signed e-mail), albeit at the human-operator level. Otherwise, your administrator would be likely set up someone else’s key so long as they’re willing to forge an e-mail from you or briefly adopt your nick on IRC.

fwiw, there are many forms of authentication for ssh, and only some of which (e.g. keyboard-interactive and password authentication) involve actually transmitting your password to the remote server. But even these authentication techniques don’t transmit the password in plaintext such that a casual network snooper could read it: The material is sent across an encrypted session anchored by your belief that the host key is the appropriate key.

I see two main reasons why these approaches are undesirable, aside from the dictionary attacks you mention above:

  • if the client is not conscientious about checking the host keys, a MITM attack from an active attacker could learn the client’s password by impersonating the server and proxying the communications through.
  • the server itself gets a raw copy of the user’s password; in the event that the client uses the same password for multiple services, and the server is (or becomes) malicious, the server can then impersonate the client on these other services.

(note that while keyboard-interactive authentications can be used to pass the raw password to the server (and often are, in common PAM arrangements), they can also be used in more clever ways. For example, OpenSSH’s “ChallengeResponseAuthenticatio n” uses keyboard-interactive as a transport to take advantage of OpenBSD’s various authentication schemes. Many of these schemes do not have the same password-is-visible-to-the-server problem i describe above)

 
 

I started making ssh-keys for different machines, and adding a comment to them, to make it easier to keep things apart:
ssh-keygen -t rsa -b 2048 -f ~/.ssh/ServerName_UserName_id -C “ServerName”

And then the sweet ~/.ssh/config makes life great if you have to use different usernames or have hostnames which you can’t ever remember. It contains for example something like:

Host streamtime
HostName fqdn.streamtime.fqdn
IdentityFile /home/kwadronaut/.ssh/streamtime.id
PasswordAuthentication no
PubkeyAuthentication yes
PreferredAuthentications publickey
User kwadronaut
Port 12345

 
 

gdm: what do you think about trying to integrate my ssh good practices document into this document (or elsewhere in the grimoire and link them)?

lackof.org/taggart/hacking/ssh

The other document I have been meaning to write is a “ssh server good practices”, that would be nice to have in the grimoire too.

 
 

taggart, sounds like a great idea! i haven’t time to read your page properly at the moment, but looks like a really good, comprehensive page….i’m perfectly happy for people to edit this page heavily (i.e. delete everything i’ve written and replace it with better stuff :-) as i really don’t have that much time at the moment – and anyway, it’s better for it to be a community maintained resource. so, go for it!

 
 

Yes, the link or how-to by taggart is good. I would also add “apt-get install fail2ban”, disable Root login in /etc/ssh/sshd_config, disable password-authentication (covered by taggart already), use a non-default port and make use of ~/.ssh/config, like mentioned by kwadronaut.

 
 

On servers with multiple users that have varying authorizations, it’s a good idea to restrict root-access to only those users that actually need it using /etc/sudoers and /etc/pam.d/su (check the option auth required pam_wheel.so to activate wheel-group for users with authorized su-access). Also, use /etc/pam.d/sshd and /etc/security/access.conf for further finegrained control of ssh logins.

 
 

what do you think about ssh through tor ?
apart from a security enhanced connection(?), this could also be useful in case a user’s connecting ip has been banned by some strict fw rules.
tip from skytal.es/docs/tips/ssh_over_tor_to_rem...
just sceptical about using tor relays in general…(?)

 
 

what do you think about ssh through tor ?

very usefull to join ssh server behind NATed router

 
 

I agree. The other document I have been meaning to write is a “ssh server good practices”, which would be nice to have in the grimoire too.

 
   

I’m glad that I find this great information. Thanks for taking the time to post this.