465

I am lazy at home and use password authentication for my home machines. I am ready to move to key based authentication. There are many options on the web on how to do this, including catting then sshing the key over, scping the key over directly, etc.

I am looking for the easiest and recommended way to copy a key over, hopefully there is a convenience wrapper somewhere in the Ubuntu ssh package?

I'm already aware on how to shut off password logins.

Jorge Castro
  • 71,754
  • 1
    http://askubuntu.com/questions/307881/ssh-public-key-authentication-doesnt-work/848174#answer-848174 – Vineet Nov 11 '16 at 11:56

8 Answers8

622

The ssh-copy-id command (in the openssh-client package and installed by default) does exactly this:

ssh-copy-id user@hostname.example.com

copies the public key of your default identity (use -i identity_file for other identities) to the remote host.

The default identity is your "standard" ssh key. It consists of two files (public and private key) in your ~/.ssh directory, normally named identity, id_rsa, id_dsa, id_ecdsa or id_ed25519 (and the same with .pub), depending on the type of key. If you did not create more than one ssh key, you do not have to worry about specifying the identity, ssh-copy-id will just pick it automatically.

In case you do not have an identity, you can generate one with the tool ssh-keygen.

In addition, if the server uses a port different from the default one (22) you should use quotation marks in this way (source):

ssh-copy-id "user@hostname.example.com -p <port-number>"
zypA13510
  • 119
  • 1
    What is the default identity? – Oxwivi Jun 04 '11 at 18:28
  • @Oxwivi: The default identity is your "standard" ssh key. It consists of two files (public and private key) in your ~/.ssh directory, normally named ``identity,id_rsaorid_dsa(and the same with.pub), depending on the type of key. If you did not create more than one ssh key, you do not have to worry about specifying the file,ssh-copy-id` will just pick it automatically. – Marcel Stimberg Jun 06 '11 at 13:56
  • 19
    for different port use this: ssh-copy-id "user@host -p 6842" – Jibon Jan 25 '14 at 20:27
  • 11
    What if the remote server you're copying to doesn't allow password prompts and is basically locked down save for SSH access? – Cyle Jan 29 '14 at 23:13
  • 10
    On mac you can do brew install ssh-copy-id and then run the command. – Avishai Sep 30 '14 at 14:31
  • I have the ssh-key-agent running and this command pushed ALL of my keys in the agent to the remote server and not only the default key in my .ssh profile folder. The -i Option is important if you use the agent. – Jürgen Hörmann Dec 02 '16 at 09:30
  • 2
    @MarcelStimberg please update answer to include -i profile ; people likely have more than 1 key and push them all, or have to hunt for the -i option in comments – Nick Mar 12 '17 at 18:07
  • my machine (a real time linux distribution) do not have it installed. It has only opkg manager. How can i install it? opkg install sshopen says it is up to date...... – Brethlosze Jun 20 '17 at 22:14
171

I like the answer from Marcel. I did not know this command. I've always been using what I had found on the Oracle web site:

cat ~/.ssh/id_rsa.pub | ssh <user>@<hostname> 'cat >> .ssh/authorized_keys && echo "Key copied"'

I thought to post it here still, because it is a good illustration of what can be achieved in shell code with the power of ssh. But using the ssh-copy-id is definitively a safer way to do it properly!

Note that if the folder .ssh does not already exist, the above command will fail. In addition, it might be better when creating the file to set a minimum possible permission (basically read-write for owner only). Here is a more advanced command:

cat ~/.ssh/id_rsa.pub | ssh <user>@<hostname> 'umask 0077; mkdir -p .ssh; cat >> .ssh/authorized_keys && echo "Key copied"'
Huygens
  • 4,713
  • 3
    This exact commands also work from a Mac too – Mihai P. Feb 20 '15 at 04:09
  • It should work under any Unix with most shell. I've update the post with an updated command in case the folder .ssh does not exist on the remote side. – Huygens Mar 01 '15 at 14:54
  • 2
    The cat is not necessary - a normal input redirection is enough, e.g. < ~/.ssh/id_rsa.pub | ssh ... – maxschlepzig Mar 17 '16 at 22:44
  • @Huygens Thanks. More useful to remember this one, because you do not need to install anything and it can also be good for executing foreign commands e.g. changing server-side permissions as you demonstrated in your advanced example. – Jonathan Komar Mar 21 '16 at 13:15
  • 2
    I much prefer this way since it lets you use verbose ssh which is helpful in figuring out why things are broken. sshcopyid just froze and never worked, this went perfectly. – Allison May 29 '17 at 23:03
  • 1
    I would shorten your last command: cat ~/.ssh/id_rsa.pub | ssh <user>@<hostname> 'mkdir .ssh; cat >> .ssh/authorized_keys'. No need for the the p (parent) flag in mkdir. Never used the umask and echo key copied does not help. A detail: if you know that you will be the first entry in the authorized_keys, a > (wipe the file and insert the content) is fine. – Timo Dec 10 '20 at 18:37
  • I use the following approach in peace cat ~/.ssh/id_rsa_name.pub | ssh <username>@192.168.1.X "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys" - it for my old mac - El Capitan – Manuel Jordan Oct 01 '22 at 15:48
32

Graphical method

  1. Open ApplicationsPasswords and KeysMy Personal Keys.
  2. Select your key and then click RemoteConfigure Key for Secure Shell.

Set Up Computer for SSH Connection

ændrük
  • 76,794
20

On Ubuntu you can fetch your keys from Launchpad:

ssh-import-id [launchpad account name]

Details:

  1. You need a Launchpad account so login or create an account
  2. After logging in, click the button next to SSH keys:
  3. Paste the contents of your public key file in that field (including comment). Such a key looks like:

    ssh-rsa AAAAB3Nza .... UyDOFDqJp lekensteyn
    

    Here, ssh-rsa indicates that the key is a RSA key, AAAAB3Nza .... UyDOFDqJp is the actual key and lekensteyn is the comment.

  4. Save the key by pressing Import Public Key
  5. If everything went well, your key should now be listed under SSH keys:

The package ssh-import-id needs to be installed on the machine which needs to be accessed from remote. This package is installed together with the openssh-server package as it's a recommended package for openssh-server. After making sure that ssh-import-id has been installed On the client machine, run:

ssh-import-id [launchpad account name]

This will download the public key from the Launchpad servers over HTTPS which protects you from MITM attacks.

On Ubuntu Lucid and before, you can accomplish the same with:

wget https://launchpad.net/~[lp acount name]/+sshkeys -O - >> ~/.ssh/authorized_keys && echo >> ~/.ssh/authorized_keys

The echo command is needed to get an extra newline after the line with the SSH key.

Lekensteyn
  • 174,277
17

for custom port

ssh-copy-id -i "user@hostname.example.com -p2222"

-i switch defaults to ~/.ssh/id_rsa.pub, if you want another key, put the path of the key after -i

WARNING: If you did not write the -i it will copy all your keys found in ~/.ssh

omars
  • 281
  • 1
    Are you sure about that WARNING? "-i identity_file - Use only the key(s) contained in identity_file (rather than looking for identities via ssh-add(1) or in the default_ID_file). If the filename does not end in .pub this is added. If the filename is omitted, the default_ID_file is used." – Yousha Aleayoub Apr 22 '15 at 20:37
15

Here is a less secure, but very simple solution(not recommended for servers):

Move ~/.ssh to the new machine and run ssh-add. DONE!

LONG ANSWER:

  1. In the old machine, take the folder ~/.ssh to an USB drive, or to any other storage you like.
  2. On the new machine, put the folder under ~ aka /home/$USER.
  3. Run ssh-add, on the new machine done.
  • 5
    Important to add, make sure to restore permissions on files, sudo chmod 600 ~/.ssh/id_rsa sudo chmod 600 ~/.ssh/id_rsa.pub sudo chmod 644 ~/.ssh/known_hosts and on folder, if whole folder was copied sudo chmod 755 ~/.ssh – Jaco Mar 17 '21 at 23:37
  • 1
    You definitely don't want to do it this way. By doing this you're not only copying your public key, but your private key as well! This is especially dangerous when the other machine is shared with other users that have root privileges. They'll have access to your private key! – Rens Verhage Jul 07 '21 at 18:43
  • 2
    Pls update your post - your solution IS GOOD to copy ssh keys for your another work machine (for example from desktop to laptop) but bad idea to do it for alive host\server (that's why other answers "over-complicated"). And thank you for your answer - it worked for me too. – user1954544 Oct 24 '21 at 21:51
5

ssh-copy-id does exactly that. I am not sure why some of the other answers here add inaccurate information. The help shows the following:

~$ ssh-copy-id -h
Usage: /usr/bin/ssh-copy-id [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o <ssh -o options>] ...] [user@]hostname
    -f: force mode -- copy keys without trying to check if they are already installed
    -n: dry run    -- no keys are actually copied
    -h|-?: print this help

I just tried the following on Ubuntu 18.04 client with a CentOS 7.6 server and it worked like a charm. The example shows using a custom port of 2222, and specifying a public key at ~/.ssh/path-to-rsa.pub

$ ssh-copy-id -i ~/.ssh/path-to-rsa.pub -p 2222 myusername@hostname.tld

Before running the command, I actually used the -n switch at the end to do a dry run which confirmed that the command will work as intended. Once I confirmed it I ran the command again as above, without the -n switch.

isapir
  • 513
0

If you already have a host key like in the case of AWS EC2, then do this

cat ~/.ssh/id_rsa.pub | ssh -i hostkey.pem hostname@hostaddress 'cat >> .ssh/authorized_keys && echo "Key copied" '

Next time, simply do this:

ssh hostname@hostaddress
zx485
  • 2,426