How do you setup ssh to authenticate a user using keys instead of a username / password?
9 Answers
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.
- 1,842
- 16
- 16
-
The only other thing I would add to this is look at the permissions on the file and directory. – trent May 01 '09 at 15:29
-
3Don't forget chmod 0700 .ssh chmod 0600 .ssh/authorized_keys – Dave Cheney May 03 '09 at 03:50
-
3Definitely 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 05 '09 at 23:08
-
@gyaresu: Thanks! I just learnt something new! :-D – C. K. Young May 06 '09 at 04:09
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.
- 979
- 3
- 14
- 17
-
2@Chris Bunch EVERYONE LOOK OVER HERE! :) ssh-copy-id is definitely the way to share one's id_rsa.pub – Gareth May 06 '09 at 01:12
-
1Cool, I never knew about this... I wrote my own script to do exactly the same thing :-/ – David Z May 09 '09 at 23:18
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,644
- 1
- 13
- 15
-
3And 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 06 '09 at 13:36
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.
- 130
- 1
- 6
-
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. – C. K. Young May 01 '09 at 14:54
-
My favorite walkthrough has been consigned to the Wayback Machine: http://web.archive.org/web/20061103161446/http://www.justenoughlinux.com/2004/04/14/scp_without_passwords.html – Philip Durbin May 01 '09 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 02 '09 at 00:35
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
- 662
- 7
- 12
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.
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.Your private key must be
chmod 600
.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.
- 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. - I like to
chmod 600 ~/.ssh/authorized_keys
. It must be at least g-w. - 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.
- 11
- 3
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.
- 4,429
- 3
- 24
- 32
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.
- 251
- 2
- 3