57

Here is what I have tried, and I got an error:

$ cat /home/tim/.ssh/id_rsa.pub | ssh [email protected] 'cat >> .ssh/authorized_keys'
Password: 
cat: >>: No such file or directory
cat: .ssh/authorized_keys: No such file or directory
3
  • Why not do it in two steps? Copy it across and then append it? Jan 18, 2012 at 20:01
  • @FaheemMitha: That works, thanks! I actually might realize the cause of trouble. Please see my new post?
    – Tim
    Jan 18, 2012 at 21:23
  • With the -f parameter you don't need the private key, so you can just pass the key up for them with only someone's public key!
    – Kzqai
    Aug 6, 2019 at 14:57

7 Answers 7

99

OpenSSH comes with a command to do this, ssh-copy-id. You just give it the remote address and it adds your public key to the authorized_keys file on the remote machine:

$ ssh-copy-id [email protected]

You may need to use the -i flag to locate your public key on your local machine:

$ ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
7
  • 1
    Thanks! Why my command doesn't work?
    – Tim
    Jan 18, 2012 at 20:18
  • @Tim This answer explained it; >> is handled by your shell, and you're running the command through SSH instead of through a shell. His fix of having SSH run a shell, which then runs your command, should work Jan 18, 2012 at 20:22
  • Thanks! (1) ssh-copy-id doesn't work either. I manually copy the file to the remote and append its content, then it works. I wonder why is this? I found that my default shell on the server is some script, which I update to my original post, and might be the reason. Please have a look. (2) I wonder if ssh-copy-id is just copy the public key to the remote, it doesn't create the private and public key, does it?
    – Tim
    Jan 18, 2012 at 20:37
  • 1
    Let's assume the SSH server is configured in such a way that it only accepts public key authentication as a authentication mechanism. In that case, using ssh-copy-id won't work, right?
    – Abdull
    Jun 7, 2016 at 15:24
  • 1
    @Abdull Not unless you already have some other key on that machine to connect with. It's just connecting over SSH Jun 7, 2016 at 15:31
44

You could always do something like this:

scp ~/.ssh/id_rsa.pub [email protected]:/tmp/id_rsa.pub
ssh [email protected] 
cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys

I am not sure if you can cat from a local machine into an ssh session. Just move it to /tmp as suggested.

Edit: This is exactly what ssh-copy-id does. Just like Michael said.

5
  • Thanks! I wonder if ssh-copy-id is just copy the public key to the remote. It doesn't create the private and public key, does it?
    – Tim
    Jan 18, 2012 at 20:51
  • No it doesn't create it. Just adds it.
    – Mr. Monkey
    Jan 18, 2012 at 21:22
  • @Mr.Monkey Yes, you can pipe data into an ssh session (from cat or otherwise). What you're describing is the old-fashioned way; ssh-copy-id is recommended because there's less risk of typos or giving files wrong permissions. Jan 18, 2012 at 23:19
  • @Gilles , You not always have access to the server to the client, especially when you're preparing a computer for its operation, so this method is much better than using ssh-cpy-id because you do not need to take the equipment or connect to the network before setting.
    – e-info128
    Oct 26, 2016 at 19:13
  • 1
    Or you can just pipe directly to the destination: cat ~/.ssh/id_rsa.pub | ssh <user>@<hostname> 'cat >> ~/.ssh/authorized_keys'.
    – Pablo A
    Jan 28, 2018 at 2:12
10

This answer describes how to make the intended way shown in the question working.

You can execute a shell on the remote computer to interpret the special meaning of the >> redirection operator:

ssh [email protected] sh -c "'cat >> .ssh/authorized_keys'" < /home/tim/.ssh/id_rsa.pub

The redirection operator >> is normally interpreted by a shell.

When you execute ssh host 'command >> file' then it is not guaranteed that command >> file will be interpreted by a shell. In your case command >> file is executed instead of the shell without special interpretation and >> was given to the command as an argument -- the same way as running command '>>' file in a shell.

Some versions of SSH (OpenSSH_5.9) will automatically invoke shell on the remote server and pass the command(s) to it when they detect tokens to be interpreted by a shell like ; > >> etc.

2
  • ssh [email protected] 'cat >> .ssh/authorized_keys' < /home/tim/.ssh/id_rsa.pub also work, leaving sh -c
    – Timo
    Mar 13, 2021 at 10:14
  • 1
    @Timo Yes, I tested this between current versions of Ubuntu (OpenSSH_8.2p1) and Debian (OpenSSH_7.9p1) and it works. ...but there is some trickery: in some cases the command is run directly on the server: command in other cases it is run using shell: bash -c command. I was not able to find in the OpenSSH documentation about how it is decided which way will OpenSSH use. It seems to be decided on the server side. --- To wrap it up: your shorter code might or might not work. --- I tried to explain this in my answer. Mar 13, 2021 at 12:27
5

Avoiding ssh-copy-id

Taken from the answers/comment to the Original Poster(OP)'s question:

1. with redirection (ssh at beginning)

ssh <user>@<host> 'cat >> ~/.ssh/authorized_keys' < ~/.ssh/id_rsa.pub

2. with pipe (ssh not at beginning)

cat ~/.ssh/id_rsa.pub | ssh <user>@<host> 'cat >> ~/.ssh/authorized_keys'
3

openssh does provide ssh-copy-id. The sequence would be:

  • Generate a decent 4k key

    ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa4k
    
  • Start your ssh-agent up and suck in information like SSH_AGENT_PID, etc.

    ssh-agent -s > ~/mysshagent
    source ~/mysshagent
    rm ~/mysshagent
    
  • Now start loading keys into your SSH Agent

    ssh-add ~/.ssh/id_rsa4k
    
  • Check that it is loaded

    ssh-add -l
    ssh-add -L
    

    This will show you what you have in the ssh-agent

  • Now actually SSH to a remote system

    ssh [email protected]
    
  • Now you can run ssh-copy-id with no arguments:

    ssh-copy-id
    

    This creates ~/.ssh/authorized_keys and fills in the basic info required from ssh-agent.

2
  • BTW, I created a small script at github.com/centic9/generate-and-send-ssh-key which runs most of these steps in one go and additionally ensures file/directory permissions which usually always caused me headaches...
    – centic
    Oct 7, 2015 at 11:24
  • This is a great method to use when password login is disabled. It allows adding a new key while authenticating with a prior key.
    – MountainX
    Feb 19, 2018 at 22:45
1

I had troubles with ssh-copy-id when choosing another port than 22... so here is my oneliner with a different ssh-port (e.g. 7572):

ssh yourServer.dom -p7572 "mkdir .ssh; chmod 700 .ssh; umask 177; sh -c 'cat >> .ssh/authorized_keys'" < .ssh/id_rsa.pub
1
1

Indeed the the ssh-copy-id command does exactly this (from the openssh-client package):

ssh-copy-id user@host

Note:
host means IP address or domain.


I would like also to add some additional information to this

1) We can specify a different port for SSH on destination server:

ssh-copy-id "-p 8127 user@host"

Note:
The port must be in front of the user@host or it will not resolve.

Source

2) We can specify a file with a public key:

ssh-copy-id -i ~/.ssh/id_rsa.pub user@host

Note:
The -i option allows us to indicate the appropriate location of the name with the file that contains the public key.

Sometimes it can come in handy, especially if we store it in a non-standard location or we have more than one public key on our computer and we want to point to a specific one.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .