Networking and remote
ssh-copy-id
Install your public SSH key in a remote account's authorized_keys so you can log in without a password.
ssh-copy-id [-i [KEY.pub]] [-p PORT] [-n] [-f] [-t TARGET] [USER@]HOST
ssh-copy-id host logs in to host (with a password, the last time you will need it) and
appends your public key to ~/.ssh/authorized_keys there, creating the directory and file with
the right permissions if needed. After that, ssh, scp and rsync log in with the key.
It first tries to log in with each candidate key, and skips keys that already work, so
running it twice does not add duplicates. -i picks a specific key; without it, ssh-copy-id
uses the keys in your ssh agent, or else your newest ~/.ssh/id_*.pub.
It is a shell script that only needs a working ssh login, so it works against any server. When
you cannot use it, the manual equivalent is
cat key.pub | ssh host 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys' plus fixing
permissions (chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys). In the sandbox, server
is the machine itself and the default key is already installed.
Examples
Running it when the key is already installed
ssh-copy-id server
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/dev/.ssh/id_ed25519.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system. (if you think this is a mistake, you may want to use -f option)
ssh-copy-id found the default key, logged in with it successfully, and therefore installed nothing. The warning is informational and the exit status is 0, so it is safe to run repeatedly from provisioning scripts.
Preview which keys would be installed
Setup run before this example
ssh-keygen -q -t ed25519 -C deploy@ci -f ./deploy_key -N ''ssh-copy-id -n -i deploy_key.pub server
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "deploy_key.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys =-=-=-=-=-=-=-= Would have added the following key(s): ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIvmoKuS6vOgqonogcrZS270fnRbj9i3y0K+WO24eVtZ deploy@ci =-=-=-=-=-=-=-=
-n does everything except the copy: it checks that the new key does not already work,
then prints the exact line it would add.
Install a new key and log in with it
Setup run before this example
ssh-keygen -q -t ed25519 -C deploy@ci -f ./deploy_key -N ''ssh-copy-id -i deploy_key.pub server
ssh -i deploy_key -o IdentitiesOnly=yes server 'tail -n 1 ~/.ssh/authorized_keys'
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "deploy_key.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys Number of key(s) added: 1 Now try logging into the machine, with: "ssh -i ./deploy_key 'server'" and check to make sure that only the key(s) you wanted were added. ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL5oue4QVJ4VoWzKWyIbF+HUMNfZsXrHLOK36PyBQ3di deploy@ci
ssh-copy-id reports one key added and suggests a test login. The second command does that
test: IdentitiesOnly=yes makes ssh offer only deploy_key, and the last line of
authorized_keys on the server is the new key.
A server on another port
ssh-copy-id -p 2222 server
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/dev/.ssh/id_ed25519.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: ERROR: ssh: connect to host server port 2222: Connection refused
ssh-copy-id passes -p to ssh. Nothing listens on 2222 here, so ssh cannot connect and
ssh-copy-id fails with exit status 1. With a Port line in ~/.ssh/config you can leave
-p out.
Write to a different authorized_keys file
Setup run before this example
ssh-keygen -q -t ed25519 -C backup@nas -f ./backup_key -N ''ssh-copy-id -f -i backup_key.pub -t /home/dev/demo/authorized_keys.test server
cat authorized_keys.test
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "backup_key.pub" Number of key(s) added: 1 Now try logging into the machine, with: "ssh -i 'server'" and check to make sure that only the key(s) you wanted were added. ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIDV74ZbGT0gH2eiToKZAziGmYokL0tJD7AynXcxbbz0 backup@nas
-t PATH (in recent OpenSSH releases) installs the key into another file on the server, for
setups where sshd reads keys from a central location. -f skips the trial login with the
new key, which could not succeed here anyway since sshd does not read that file. In this
mode the suggested test command even leaves out the key name; ignore it.
The manual equivalent without ssh-copy-id
Setup run before this example
ssh-keygen -q -t ed25519 -C deploy@ci -f ./deploy_key -N ''ssh server 'umask 077; mkdir -p keys-test && cat >> keys-test/authorized_keys' < deploy_key.pub
ssh server 'ls -l keys-test/authorized_keys'
-rw------- 1 dev dev 91 Oct 31 20:21 keys-test/authorized_keys
This is essentially what ssh-copy-id does: append the public key over ssh, with a umask
that makes the directory 700 and the file 600. On a real server the path is
~/.ssh/authorized_keys; the example writes to a test directory instead.
Common pitfalls
If key login still asks for a password after ssh-copy-id, check permissions on the server:
~must not be group- or world-writable,~/.sshshould be 700 andauthorized_keys600, or sshd ignores the file.ssh-copy-id -i ~/.ssh/id_ed25519(without.pub) still installs the public key; it adds.pubitself. Never copy the private file anywhere.-fskips the "already installed" check and can add duplicate lines.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
ssh-copy-id ships with OpenSSH on Linux and recent macOS. Old macOS releases lacked it; the manual
cat key.pub | ssh host ...pipeline works everywhere.
Options worth knowing
A selection, described in our own words. For the full list, see ssh-copy-id(1) or ssh-copy-id --help.
| Option | What it does |
|---|---|
-i FILE | Install this key (the .pub is used even if you name the private file). |
-p PORT | Connect to PORT on the remote host. |
-n | Dry run: show the keys that would be installed. |
-f | Force: install without checking whether the key already works. |
-s | Use SFTP instead of running commands on the remote side. |
-t PATH | Install into PATH on the remote host instead of ~/.ssh/authorized_keys. |
-F FILE | Use FILE as the ssh configuration. |
-o OPTION | Pass an option to ssh. |
-x | Trace the script for debugging. |
Related
ssh-keygenCreate, inspect and manage SSH keys, and maintain known_hosts entries.sshLog in to a remote machine or run a command on it over an encrypted connection; also forwards ports and jumps through hosts.scpCopy files between hosts over ssh, with cp-like syntax where a remote path is written HOST:PATH.