Typing a password for the same server every day gets old fast, and that is exactly the itch ssh-copy-id scratches. It adds a public key to a remote account's authorized_keys, then you verify key-only login actually works. Takes about five minutes when the remote account already accepts password authentication. Covers the installed Ubuntu package version 1:9.6p1-3ubuntu13.19 and its matching manual page.
You need a local key pair, the public half of the key you intend to install, and a remote account reachable over SSH. The first connection normally needs that account's password. It does not need administrative privileges: ssh-copy-id only writes inside that user's home directory.
Have these ready:
alice.server.example.net.~/.ssh/id_ed25519.pub.Never paste a private key into this command. The -i argument names a key file, and ssh-copy-id installs its public form. Keep private keys exactly that.
Inspect the public key file before touching the remote account. Expect one long line starting with a key type such as ssh-ed25519, followed by key data and an optional comment.
test -r "$HOME/.ssh/id_ed25519.pub" && ssh-keygen -lf "$HOME/.ssh/id_ed25519.pub"
Expected output is a fingerprint and the key file name, for example:
256 SHA256:REPLACE_WITH_YOUR_FINGERPRINT alice@laptop (ED25519)
Nothing there? List the public keys you do have:
find "$HOME/.ssh" -maxdepth 1 -type f -name '*.pub' -print
Pick the matching private and public pair. Using a different key just means swapping ~/.ssh/id_ed25519.pub for it in the commands below.
Run dry-run mode before you install anything. It prints the key or keys that would be installed and makes no remote change.
ssh-copy-id -n -i "$HOME/.ssh/id_ed25519.pub" [email protected]
Check the printed fingerprint or comment against the key you actually meant to use. The explicit -i matters here: leave it off and this version first tries keys reported by ssh-add -L when an agent has any loaded, then falls back to the most recently modified matching ~/.ssh/id*.pub file, skipping certificate public keys.
That fallback is convenient right up until a busy agent installs a key you never intended to send. Keep -i explicit in repeatable instructions and automation, no exceptions.
Run the same command without -n:
ssh-copy-id -i "$HOME/.ssh/id_ed25519.pub" [email protected]
Expect a password prompt for the remote account. The command first checks whether the key already works, then appends any keys not already accepted to ~/.ssh/authorized_keys on the remote user, creating the .ssh directory and file if they do not exist.
Success normally reports how many keys were added and suggests testing with SSH, though the exact wording varies by installed version. A password prompt here is expected; a private-key passphrase prompt can also show up while the script checks existing identities.
Checkpoint: the remote account has now changed. If that was not the plan, stop and work through the recovery step below before doing anything else.
Force SSH to use the selected private key and switch off password authentication for this one test. That proves the newly installed key actually works, rather than quietly falling back to a password.
ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no -i "$HOME/.ssh/id_ed25519" [email protected] 'printf "key login works\n"'
Expected output:
key login works
If that fails, switch to verbose SSH output to find where the chain breaks, client, network or server:
ssh -vv -o PreferredAuthentications=publickey -o PasswordAuthentication=no -i "$HOME/.ssh/id_ed25519" [email protected]
Look for the offered key, whether the server accepted it, and any message about permissions or an unavailable public-key method. Do not share verbose output without stripping host names, account names and other identifying details first.
Pass a non-standard port with -p. Other SSH options go through -o; both are forwarded straight to the underlying ssh command.
ssh-copy-id -i "$HOME/.ssh/id_ed25519.pub" -p 2222 [email protected]
For a host with a jump host or other settings you always use, put them in your per-user SSH configuration and reference the host alias instead. That keeps the copy command short and makes the later verification use the exact same connection policy. The manual page names ssh_config as the place for per-host settings.
ssh-copy-id -i "$HOME/.ssh/id_ed25519.pub" production-server
ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no production-server 'printf "key login works\n"'
-s switches to SFTP mode: it downloads, edits and re-uploads the remote authorized_keys file, useful when the server allows SFTP but restricts remote command execution. It is still changing the remote account's login keys, so treat it with the same care.
ssh-copy-id has no undo button. To remove a key, back up the remote file first, then edit it through a trusted session and delete only the line matching the fingerprint you installed.
ssh [email protected] 'cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak.$(date +%Y%m%d%H%M%S)'
Warning: do not truncate authorized_keys. It may hold other people's access or critical options. Keep your current session open until a separate login test succeeds, because removing the wrong line can lock you out. If you have lost all working access, an administrator or console session is the only way back in, restoring the backup and fixing the file from there.
-i and check the preview..pub. The script does append .pub when an extension is left off, but being explicit avoids the surprise.-s if SFTP is allowed but remote commands are not; otherwise get the server's SSH configuration and logs checked by its administrator.key login works.