Setting up SSH keys

Russ Bateman
last update:


Why generate an SSH key?

If you must authenticate frequently via ssh or scp to Unix or Linux hosts, you may wish to create a key that will permit this without requiring you to type in a password each time.

This is especially useful if you a) run scripts to perform automated tasks on remoted hosts or b) consume source-code control from remote servers (Subversion, CVS, Git, etc.).

Note that, when we say "key" here, we're actually speaking of a key pair: one private key and a corresponding public key. If you generate a key, send the public one to whatever service wants to use it, then delete the corresponding private one, the identification/authentication solution will immediately cease to work.


How to generate an SSH key

Note that a key belongs to the person generating it. It isn't created somehow "respective" to the computer host or user on that host where it will be used. You can generate one key to be used on many different hosts. What makes it usable on a remote host and for any particular user account on that host is its presence under that user's .ssh subdirectory: if you can get it there, then you can get into the host as that user.

  1. Generate a new SSH key. You may or may not wish to do this: If you have already have one (or more), you may wish just to use it instead. If the latter is true, then skip this step. Below, the -C is merely a comment.
    [email protected]:~/.ssh> cd ~/.ssh [email protected]:~/.ssh> ssh-keygen -t rsa -C "[email protected]" Generating public/private rsa key pair. Enter file in which to save the key (/home/russ/.ssh/id_rsa): Enter passphrase (empty for no passphrase): * Your identification has been saved in /home/russ/.ssh/id_rsa. Your public key has been saved in /home/russ/.ssh/id_rsa.pub. The key fingerprint is: d3:b1:23:fd:54:b1:30:80:27:19:e8:19:45:4b:86:35 [email protected] The key's randomart image is: +--[ RSA 2048]----+ | *E+..o . | | +o+o. o o | | . o.o. o | | o o o . | | S = . | | o + | | . | | | | | +-----------------+
  2. Make a copy of the public key (do not delete the private key)

* You may wish to use a passphrase if there's any risk to someone sitting down in front of your computer with access to your account. As it's unlikely (right?) that you'd ever abandon your host without locking the desktop, this is probably not important to you.

If you decide that the passphrase is important to you, you will have to type it in each time to gain access to the remote resources. However, you may try ssh-agent to overcome this problem. (This document does not undertake to show that.)

Frustration

This utility can be error-prone and the error message is moronic. For instance, below, I'm trying to put together a key for use by Jenkins. Don't, for instance, use the -p as some out there suggest. This will obligate you to input the original passphrase. What original passphrase you ask? Yeah. In any case, when it says "No such file or directory", it's not asking you for the full path to the new key.

jenkins@acme-buildserver:~/.ssh$ pwd /home/jenkins/.ssh jenkins@acme-buildserver:~/.ssh$ ssh-keygen -p Enter file in which the key is (/home/jenkins/.ssh/id_rsa): /home/jenkins/.ssh/id_rsa: No such file or directory jenkins@acme-buildserver:~/.ssh$ ssh-keygen -p Enter file in which the key is (/home/jenkins/.ssh/id_rsa): /home/jenkins/.ssh Enter old passphrase: Bad passphrase. jenkins@acme-buildserver:~/.ssh$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/jenkins/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/jenkins/.ssh/id_rsa. Your public key has been saved in /home/jenkins/.ssh/id_rsa.pub. The key fingerprint is: 7e:c7:9a:8a:90:ce:17:2c:b5:dd:28:3d:53:fa:03:d9 jenkins@acme-buildserver The key's randomart image is: +--[ RSA 2048]----+ | | | | | | | . . | | o +SB | | ..=.X E. | | o. o.=. o | | o ... .o+ | | o.. ..o. | +-----------------+

What to do with the new key

The new key is copied to the remote server and placed into the .ssh subdirectory of the account you log in to. In other words, if you frequently log in as russ on host keltia, you could do this:

[email protected]:~/.ssh> ssh [email protected] [email protected]'s password: ***************** russ@keltia:~/$

...or, you could put your new key there. If there is no subdirectory .ssh on the remote machine, create it so you can copy your key there.

[email protected]:~/.ssh> cp id_rsa.pub id_rsa.pub.tuonela [email protected]:~/.ssh> scp id_rsa.pub.tuonela [email protected]:/home/russ/.ssh [email protected]'s password: ***************** id_rsa.pub 100% 403 1.6KB/s 00:00 [email protected]:~/.ssh> ssh [email protected] [email protected]'s password: ***************** russ@keltia:~/$ cd .ssh russ@keltia:~/.ssh$ cat id_rsa.pub.tuonela >> authorized_keys

Now that this is done, log out, then reconnect via ssh to see the magic happen (no password to type in):

russ@keltia:~/.ssh$ logout Connection to keltia.site closed. [email protected]:~/.ssh> ssh [email protected] Linux keltia 2.6.32-31-generic #61-Ubuntu SMP Fri Apr 8 18:24:35 UTC 2011 i686 GNU/Linux Ubuntu 10.04.2 LTS Welcome to Ubuntu! * Documentation: https://help.ubuntu.com/ 8 packages can be updated. 7 updates are security updates. Ubuntu 10.04.2 LTS Welcome to Ubuntu! * Documentation: https://help.ubuntu.com/ 5 packages can be updated. 0 updates are security updates. Last login: Wed May 4 10:55:50 2011 from sys254.nat.cce.hp.com russ@keltia:~/$

Offending key for IP in...

How to fix...

russ@tirion ~ $ ssh russ-microservices
Warning: the ECDSA host key for 'russ-microservices' differs from the key for the IP address '192.168.0.128'
Offending key for IP in /home/russ/.ssh/known_hosts:12
Matching host key in /home/russ/.ssh/known_hosts:31
Are you sure you want to continue connecting (yes/no)? yes

...so it doesn't happen next time?

russ@tirion ~ $ sed -i '12d' ~/.ssh/known_hosts

Errors along the way?

There's real trouble, then there's superstition. Let's start with the latter: ensure that various files and subdirectories (as illustrated below) on both the client and the user at the "server" (or, remote host) have the privileges shown here. (If you make it all like this, at least you're not worrying about privileges. Normally, none of this is ever wrong unless you've really mucked with something.)

russ@tuonela:~/.ssh$ ll total 9 drwx------ 2 russ russ 112 2012-01-23 15:30 . drwxr-xr-x 9 russ russ 704 2012-01-23 14:24 .. -rw------- 1 russ russ 402 2012-01-23 15:04 authorized_keys -rw------- 1 russ russ 402 2012-01-23 15:03 id_rsa.pub

Now for the real trouble. When you've followed the instructions above and get:

~/.ssh > ssh [email protected] Agent admitted failure to sign using the key.

...you should only need to finish logging in (by providing your password), then logging out (from the remote host), and then do this:

~/.ssh > ssh-add Identity added: /home/russ/.ssh/id_rsa (/home/russ/.ssh/id_rsa)

Then you should find you can perform ssh without the need to type in your password.

Still trouble? Note that until January, 2012, I had never had to perform this last step. Was this new condition the result of an Ubuntu system update? No. I found this quote somewhere on-line:

ssh private keys are usually stored encrypted on the computers they are stored on. A pass-phrase is used to decrypt them when they are to be used. Since most people use ssh public-private key-pairs to get around typing in passwords all the time, the ssh-agent daemon exists to store decrypted private-keys you plan on using in a given session. The thing most people get tripped up on when using ssh-agent is that what the program outputs, some borne or csh shell commands, needs to be run. It may look like ssh-agent has set some variables for you, but it has in fact done no such thing. If you call ssh-add without processing ssh-agent's output, it will complain it is unable to open a connection to your authentication agent. The most straightforward way to run ssh-agent on the command line is as follows: eval `ssh-agent`. After doing this, calls to ssh-add should succeed without error.

So, here we go...

~/.ssh > ssh-add Could not open a connection to your authentication agent. ~/.ssh > eval `ssh-agent` Agent pid 3451 ~/.ssh$ ssh-add Identity added: /home/russ/.ssh/id_rsa (/home/russ/.ssh/id_rsa)

Special operations

What if you need to copy and paste the key via the clipboard, such as when you're adding a key to your GitHub or Bitbucket account? Do one of these:

$ xclip -sel clip < ./id_rsa.pub $ xclip -sel c -i ./id_rsa.pub

Then, in the browser (in the two cases noted above), use Ctrl-V in the large edit space provided. Don't type even the least little thing besides in there.


Doesn't work?

You try to use ssh or scp (to get to a newly installed server) and get:

ssh: connect to host tuonela port 22: Connection refused

This is only because you're running on a new installation and haven't installed OpenSSH server (on the host you're trying to reach). Usually, OpenSSH client is already there.

    $ sudo apt-get install openssh-server

Warning: the ECDSA host key for (hostname) differs from the key for the IP address