<<< Back to the Linux Tips Index

8th October 2016

Copying SSH ~/.ssh/id_rsa between machines

Handy ssh command of the day: ssh-copy-id. The ssh-copy-id command copies your Public Key to a remote machine. It also configures all of the file permissions correctly, because SSH is (rightly) very picky about who can access your SSH configuration.

Step 1: Create an SSH keypair

If you don't already have a id_rsa and id_rsa.pub in your $HOME/.ssh/ directory, then you will need to create them. The ssh-keygen command does this for you. You may optionally add a passphrase to the key. This means that even if someone gets hold of your private key file (such as, a system where somebody else has root access, or if you need to be certain that the key won't be usable by anybody else if they get hold of it at some time in the future), it won't do them any good, because they will need the passphrase to unlock the key itself.

I cannot think of a situation in which I would create a key without a passphrase; if there is no passphrase, then as soon as somebody gets that file, they can impersonate you.

By default, it will create the Private key in $HOME/.ssh/id_rsa and the Public key in $HOME/.ssh/id_rsa.pub. You can give it a different prefix if you like, when it prompts you below.

Here, you could press ENTER to create a key with no passphrase, though in this example, we use a passphrase of sshkey-passphrase.

steve@localbox$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/steve/.ssh/id_rsa): press ENTER
Created directory '/home/steve/.ssh'.
Enter passphrase (empty for no passphrase): sshkey-passphrase
Enter same passphrase again: sshkey-passphrase
Your identification has been saved in /home/steve/.ssh/id_rsa.
Your public key has been saved in /home/steve/.ssh/id_rsa.pub.
The key fingerprint is:
2a:fa:91:3a:a9:5d:b0:14:df:0a:e0:2e:5e:7f:b5:b8 steve@localbox
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|. .              |
|.. o .           |
| .+ . . S        |
|.. + o . .       |
|...o* . o .      |
|o.++.o o .       |
|.o+o...E.        |
+-----------------+
[steve@localbox ~]$ 

Step 2: Copy the key to the remote box

This is where ssh-copy-id comes in. You will have to enter the password to log in to the remote box, of course, because you do not (yet!) have SSH key-based login enabled.

If this is the first time that you have connected to remotebox, SSH will also say that "The authenticity of host 'remotebox (192.168.1.92)' can't be established". This is because the two machines share the machine-level SSH public keys, so that you can tell, on subsequent connections, that it is the same machine that you connected to before (not a substitute, aka "man-in-the-middle", trying to steal your authentication tokens). Assuming you have reason to trust that remotebox is the machine you think it is, it is safe to say yes here.

Note: By default, ssh-copy-id will copy the most recent $HOME/.ssh/id*.pub file to the remote box, and add it to the $HOME/.ssh/authorized_keys file there. That is normally what you want. However, you can specify a different keyfile to copy with the -i switch: ssh-copy-id -i ~/.ssh/jenkins_id_rsa.pub remotebox.

Because security is at the heart of SSH, this ssh-copy-id tool finally asks you to confirm that it has done what you expected, and not - for example - added some other guy's keys to remotebox so that they can log in to it, too.

[steve@localbox ~]$ ssh-copy-id remotebox
The authenticity of host 'remotebox (192.168.1.92)' can't be established.
RSA key fingerprint is fe:31:ac:69:33:0e:5b:05:24:9e:f4:05:b3:41:71:9f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'remotebox,192.168.1.92' (RSA) to the list of known hosts.
steve@remotebox's password: remotebox-password
Now try logging into the machine, with "ssh 'remotebox'", and check in:

  .ssh/authorized_keys

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

[steve@localbox ~]$

Step 3: Test it

Now, you should be able to simply "ssh remotebox" and log in without a password. However, you will still be prompted to enter the passphrase of the SSH key, if you gave it a passphrase when you created the keypair with ssh-keygen in Step 1:

steve@localbox$ ssh remotebox
Enter passphrase for key '/home/steve/.ssh/id_rsa': sshkey-passphrase
Last login: Fri Dec 11 11:01:33 2016 from localbox
remotebox$


Step 4: ssh-add and ssh-agent

You can also add your SSH key to your SSH Agent. This is a piece of software which will run in memory, holding your SSH keys (unlocked, if they have a passphrase), so that you never have to enter their passphrase for as long as the ssh-agent is running.

[steve@localbox ~]$ eval `ssh-agent`
Agent pid 1612
[steve@localbox ~]$ ssh-add
Enter passphrase for /home/steve/.ssh/id_rsa: sshkey-passphrase
Identity added: /home/steve/.ssh/id_rsa (/home/steve/.ssh/id_rsa)
[steve@localbox ~]$ ssh remotebox
Last login: Sat Oct  8 01:31:10 2016 from 192.168.1.100
[steve@remotebox ~]$ logout
Connection to remotebox closed.
[steve@localbox ~]$

Any subsequent uses of /home/steve/.ssh/id_rsa, within this shell session, will use the key without asking you for the passphrase. Most window managers (GNOME, etc), will store the key within their session, meaning that any new shell that you start, will also inherit access to the same ssh-agent, so that any terminal window you use will be able to use that facility.

The alternative

The alternative to using ssh-copy-id is to copy the key file to remotebox, create the $HOME/.ssh directory, set 0700 (-rwx------) permissions, create $HOME/.ssh/authorized_keys with 0644 (-rw-r--r--) permissions, then test it.

Footnote

The reason for the "eval `ssh-agent`" syntax above, is that ssh-agent will launch the ssh-agent as a background process, and then output the following text:

[steve@localbox ~]$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-LeskoW1673/agent.1673; export SSH_AUTH_SOCK;
SSH_AGENT_PID=1674; export SSH_AGENT_PID;
echo Agent pid 1674;
[steve@localbox ~]$

This, if read in via the "eval `ssh-agent`" method, will set those variables (SSH_AUTH_SOCK and SSH_AGENT_PID) in your shell. This allows your shell to communicate with the agent, which is now running in the background.

 

Invest in your career. Buy my Shell Scripting Tutorial today:

 

Steve Parker - Linux / DevOps Consultant
Share on Twitter Share on Facebook Share on LinkedIn Share on Identi.ca Share on StumbleUpon