SSH-COPY-ID(1)

๐Ÿ“ฆ
version 10.6p1 ยท 4 versions
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, centos-stream 10, centos-stream 9, debian trixie, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable, opensuse-leap 16.0, ubuntu questing, ubuntu resolute, ubuntu stonking

โœจ NAME โœจ

Okay bestie, this is ssh-copy-id(1) from the General Commands Manual ๐Ÿ’– It's basically how you use the keys already on your machine to authorise logins on a remote machine ๐Ÿ”‘

๐ŸŒธ SYNOPSIS ๐ŸŒธ

ssh-copy-id [-f] [-n] [-s] [-x] [-i [identity_file]] [-t target_path]
            [-F ssh_config] [[-o ssh_option] ...] [-p port]
            [user@]hostname
ssh-copy-id -h | -?

๐Ÿ’… DESCRIPTION ๐Ÿ’…

okay so ssh-copy-id is a script that uses ssh(1) to log into a remote machine ๐Ÿงš It usually needs a login password, so password authentication should be enabled, unless you've done some clever stuff with multiple identities ๐Ÿ™ˆ It builds a list of one or more fingerprints (more on that below) and tries logging in with each key to see if any of them are already installed. Heads up, if you're not using ssh-agent(1), this can have you getting prompted for pass-phrases over and over, so iykyk ๐Ÿ˜ญ Then it makes a list of the keys that failed to log in and, using ssh(1), enables logins with those keys on the remote server โœจ

By default it adds the keys by appending them to the remote user's ~/.ssh/authorized_keys, and it'll create the file and directory if they don't exist yet ๐ŸŽ€ It's also smart enough to notice if the remote system is a NetScreen, and in that case it uses its set ssh pka-dsa key ... command instead ๐Ÿ‘‘

๐Ÿฆ‹ The options ๐Ÿฆ‹

The options are as follows:

  • -i [identity_file] โ€” Lowkey the most important one ๐Ÿ’– This uses only the key(s) inside identity_file, instead of hunting for identities via ssh-add(1) or in the default_ID_file. If the filename doesn't end in .pub, that gets added for you. If you leave the filename out, the default_ID_file gets used. Pro tip: this is how you make sure the copied keys have the comment you want and/or extra options applied, as long as the key file has those set up before you attempt the copy ๐Ÿซถ
  • -f โ€” Forced mode ๐Ÿ’€ It doesn't check whether the keys are already on the remote server, which means it doesn't need the private key at all. Be warned though, this can end up with more than one copy of the key installed on the remote system ๐Ÿ™ˆ
  • -n โ€” Dry-run vibes ๐Ÿ“ Nothing gets installed. It just prints the key(s) that would have been installed.
  • -s โ€” SFTP mode ๐Ÿฆ‹ Normally the public keys get installed by running commands on the remote side. With this one, your ~/.ssh/authorized_keys gets downloaded, edited locally, and uploaded again with sftp. It's a lifesaver if the server restricts which commands you can run on its side ๐Ÿ”ฅ
  • -t target_path โ€” Where the keys get added on the target system ๐ŸŒˆ It defaults to .ssh/authorized_keys.
  • -p port โ€” The port to connect to on the remote host โญ
  • -F ssh_config, -o ssh_option โ€” These get passed through untouched, argument and all, to ssh/sftp ๐Ÿ’œ -F lets you pick an alternative config file, and -o lets you set other options. Honestly though, it's usually cleaner to put per-host settings in ssh(1)'s configuration file, ssh_config(5), instead of typing them on the command line ๐Ÿงš
  • -x โ€” Debugging the ssh-copy-id script itself ๐Ÿ” It sets the shell's -x flag, so you can literally watch every command being run โœจ
  • -h, -? โ€” Prints the Usage summary ๐Ÿ“

Okay, so if you don't use -i, the default behaviour is to check whether ssh-add -L gives any output. If it does, those keys get used ๐Ÿ’… Just know that the comment on the key ends up being the filename you gave ssh-add(1) when you loaded it into your ssh-agent(1), not the comment inside the file. It's a bit of a shame, ngl ๐Ÿฅบ If ssh-add(1) gives back no keys at all, the contents of the default_ID_file are used instead.

The default_ID_file is the most recent file matching ~/.ssh/id*.pub (excluding anything matching ~/.ssh/*-cert.pub) ๐Ÿซง So if you made a key that isn't the one you want ssh-copy-id to use, just run touch(1) on your preferred key's .pub file to make it the most recent again. Main character energy ๐Ÿ‘‘

๐Ÿงš EXAMPLES ๐Ÿงš

Real talk, if you've already installed keys from one system on a bunch of remote hosts, and then you make a brand new key on a new client machine, it gets hard to remember which systems have the new key ๐Ÿ˜ญ One way to handle this is to load both the new key and the old key(s) into your ssh-agent(1). Load the new key first, without the -c option, then load one or more old keys into the agent, possibly by ssh-ing to the client machine that has that old key, using the -A option to allow agent forwarding ๐Ÿ’–

      user@newclient$ ssh-add
      user@newclient$ ssh -A old.client
      user@oldl$ ssh-add -c
      ... prompt for pass-phrase ...
      user@old$ logoff
      user@newclient$ ssh someserver

Now, if the new key is installed on the server, you'll get let in without being prompted ๐Ÿซถ But if you only have the old key(s) enabled, you'll get asked for confirmation, and that's your cue to log back out and run:

      user@newclient$ ssh-copy-id -i someserver

So why use the -i option here? It makes sure the comment on the installed key is the one from the .pub file, not just the filename that got loaded into your agent ๐ŸŽ€ It also means only the id you meant to install gets installed, instead of every key sitting in your ssh-agent(1) ๐Ÿ”ฅ Of course, you can specify another id, or use the contents of the ssh-agent(1) if that's your thing โœจ

Also, since we're talking about ssh-add(1)'s -c option: you might think about using it whenever you use agent forwarding, to stop your key getting hijacked ๐Ÿ‘€ But honestly it's way better to use ssh(1)'s ProxyCommand and -W option to bounce through remote servers while still doing direct end-to-end authentication ๐Ÿ’… That way the middle hop(s) never get access to your ssh-agent(1). A web search for ssh proxycommand nc should be super enlightening ๐ŸŒˆ (NB: the modern approach is to use the -W option, rather than nc(1).)

๐Ÿฆ‹ SEE ALSO ๐Ÿฆ‹

ssh(1), ssh-agent(1), sshd(8)


That's the whole tea โ˜•๐Ÿ’– This page is from Debian, dated June 17, 2010, and it's SSH-COPY-ID(1) forever ๐Ÿงš๐Ÿ’œโœจ

๐Ÿ“ฆ where this page comes from