45

How do you setup ssh to authenticate a user using keys instead of a username / password?

9 Answers 9

33

For each user: they should generate (on their local machine) their keypair using ssh-keygen -t rsa (the rsa can be replaced with dsa or rsa1 too, though those options are not recommended). Then they need to put the contents of their public key (id_rsa.pub) into ~/.ssh/authorized_keys on the server being logged into.

4
  • The only other thing I would add to this is look at the permissions on the file and directory.
    – trent
    May 1, 2009 at 15:29
  • 3
    Don't forget chmod 0700 .ssh chmod 0600 .ssh/authorized_keys May 3, 2009 at 3:50
  • 3
    Definitely generate the keys this way but then check @Chris Bunch's post regarding "ssh-copy-id". That's the way to transfer your 'id_rsa.pub'.
    – Gareth
    May 5, 2009 at 23:08
  • FWIW, this answer is rather old; most SSH implementations should support newer ed25519 keys and these are ideal.
    – Bink
    Oct 23, 2023 at 21:05
25

I actually prefer ssh-copy-id, a script found on *nix by default (can be put on Mac OS X easily enough as well) that automatically does this for you. From the man page:

ssh-copy-id is a script that uses ssh to log into a remote machine (presumably using a login password, so password authentication should be enabled, unless you've done some clever use of multiple identities)

It also changes the permissions of the remote user's home, ~/.ssh, and ~/.ssh/authorized_keys to remove group writability (which would otherwise prevent you from logging in, if the remote sshd has StrictModes set in its configuration).

If the -i option is given then the identity file (defaults to ~/.ssh/identity.pub) is used, regardless of whether there are any keys in your ssh-agent.

2
  • 2
    @Chris Bunch EVERYONE LOOK OVER HERE! :) ssh-copy-id is definitely the way to share one's id_rsa.pub
    – Gareth
    May 6, 2009 at 1:12
  • 1
    Cool, I never knew about this... I wrote my own script to do exactly the same thing :-/
    – David Z
    May 9, 2009 at 23:18
7

Hum, don't get it. Simply create a key and get started. :) HOWTO Additionatly you could forbid login via password. In e.g. /etc/ssh/sshd_config:

PasswordAuthentication no
1
  • 3
    And you also need to set UsePAM no (or configure PAM accordingly). It's amazing how many HOWTOs miss this part out. Failure to do so will result in you still being able to login using a password.
    – Nathan
    May 6, 2009 at 13:36
3

This is fairly straight-forward to do - there's a simple walkthrough to be found here.

The main points are:

  • Run ssh-keygen on your machine. This will generate public and private keys for you.
  • Copy and paste the contents of your public key (likely in ~/.ssh/id_rsa.pub) in to ~/.ssh/authorized_keys on the remote machine.

It's important to remember that this will give anyone who has access to the private key on your machine the same access to the remote machine, so when generating the key pair you may choose to enter a password here for extra security.

3
  • I recommend cut-and-paste instead of copying. An authorized_keys file can contain multiple keys, and you don't want to clobber the other keys already in there. May 1, 2009 at 14:54
  • My favorite walkthrough has been consigned to the Wayback Machine: web.archive.org/web/20061103161446/http://… May 1, 2009 at 18:21
  • @Chris oops - I did mean to copy it in to the file rather than over-write! Answer updated now to clarify
    – ConroyP
    May 2, 2009 at 0:35
3

For Windows users to setup putty

3

To summarize what others have said, setting up SSH keys is easy and invaluable.

On the machine that you will be SSHing from you need to generate your key pair:

claudius:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/dinomite/.ssh/id_rsa): <ENTER>
Enter passphrase (empty for no passphrase): <PASSPHRASE>
Enter same passphrase again: <PASSPHRASE>
Your identification has been saved in /home/dinomite/.ssh/id_rsa.
Your public key has been saved in /home/dinomite/.ssh/id_rsa.pub.
The key fingerprint is:
a3:93:8c:27:15:67:fa:9f:5d:42:3a:bb:9d:db:93:db dinomite@claudius

Just hit enter where noted and enter a passphrase when prompted - ideally this is different from your regular login password on both the current host and the ones you will be SSHing to.

Next, you need to copy the key you just generated to the host that you want to SSH to. Most Linux distributions have a tool ssh-copy-id for doing this:

claudius:~$ ssh-copy-id caligula.dinomite.net
Now try logging into the machine, with "ssh 'caligula.dinomite.net'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

If your distribution doesn't have that, then you should copy the key to the destination host and add it to the (possibly existing) .ssh/authorized_keys file:

claudius:~$ scp .ssh/id_dsa.pub caligula.dinomite.net:
id_dsa.pub                                    100% 1119     1.1KB/s   00:00
claudius:~$ ssh caligula.dinomite.net
Last login: Sat May  9 10:32:30 2009 from claudius.csh.rit.edu
Caligula:~$ cat id_dsa.pub >> .ssh/authorized_keys

Finally, to gain the maximum benefit out of SSH keys, you will want to run an SSH agent. If you use a desktop environment (Gnome, KDE, etc.) then just logging out and back in will start an SSH agent for you. If not, you can add the following to your shell RC file (.bashrc, .profile, etc.):

SSHAGENT=/usr/bin/ssh-agent
SSHAGENTARGS="-s"
if [ -z "$SSH_AUTH_SOCK" -a -x "$SSHAGENT" ]; then
    eval `$SSHAGENT $SSHAGENTARGS`
trap "kill $SSH_AGENT_PID" 0
fi
1

There is good advice on here, so I won't repeat it. Once you get one server set up to allow you to sign on with keys, you can setup others to do the same with this one liner:

remote=server1 server2 server3 server4
for r in $remote; do echo connecting to $r; tar czf - ./.ssh/id*.pub ./.ssh/authorized_keys2 ./.ssh/config | ssh $r "tar zxf -; chmod 700 .ssh" ; done

Just cd to your home directory, define the variable remote as one or many server names and do a bunch at once. The password it asks for will be your ssh password for the remote server. You can of course use a simplified version without the for-loop:

tar czf - ./.ssh/id*.pub ./.ssh/authorized_keys2 ./.ssh/config | ssh YOUR_SERVER_NAME_HERE "tar ztvf -; chmod 700 .ssh"

REMEMBER: Only copy over your public keys. You don't want your private keys sitting out on some server where anyone with sudo can copy them and brute force your passphrase.

1

This is intended as a checklist. If one follows it point-by-point, the most common gotchas to passwordless logins should be covered. Most of these points are mentioned elsewhere; this is an aggregation.

There must be a ~/.ssh directory chmod 700 on each machine under the account that will originate or receive the connections.

The (private) key must be generated without a passphrase, or an agent can be started which will hold a decrypted version of a passphrase-bearing key for clients to use. Start the agent with ssh-agent $SHELL . It's the $SHELL part that took me a while to find. See the man page as there are multifarious details if you want to use an agent.

Don't forget that by default weak (<2048 bit DSA) keys are not accepted by recent versions of sshd.

The following must be done on the client-side machine to originate a connection.

  1. Your private key must be placed in ~/.ssh/id_rsa or ~/.ssh/id_dsa as appropriate. You may use another name, but then it must be included on a -i option on the ssh command on the originating machine to explicitly indicate the private key.

  2. Your private key must be chmod 600.

  3. Check that your home folder is chmod 700.

Now for allowing a machine to receive a request. A common model is where an admin is giving you access to a machine you don't own (like shared web hosting). Therefore, the idea with ssh is that you offer your public key to whomever is giving you the account. That's why you generally don't put private keys on the machine receiving requests. But, if you want this machine to do outgoing ssh as well, then you must treat is as an originating machine with the steps above.

  1. Your public key must be placed in a file called ~/.ssh/authorized_keys under the account that will receive the connections. You may place other keys that are allowed to connect via this account in here as well. A particularly tricky thing if you are in vi and pasting the key into the file from the paste buffer in PuTTY is this: the key starts with a "ssh-". If you are not in insert mode, the first "s" will put vi in insert mode and the rest of the key will look just fine. But you'll be missing an "s" at the beginning of the key. It took days for me to find that.
  2. I like to chmod 600 ~/.ssh/authorized_keys. It must be at least g-w.
  3. Now, you must have the host fingerprint added to the cache. Go to machine A, and ssh to machine B manually. The first time, you will get a query like "Do you want to add . . . to the host key cache?". If you are trying to get automation (such as a script) to use this login, you must ensure that the ssh client being used by the automation will not get this prompt.
0
0

As others have said, your users should make keypairs for themselves on their client machines with ssh-keygen and add their public key to ~/.ssh/authorized_keys on the machine they want to log into.

For more detailed information though, I highly recommend SSH, The Secure Shell.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .