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: