How to Use ssh-copy-id with a Specific Key Pair for Passwordless SSH Authentication


2 views

When automating server deployments or managing multiple SSH key pairs, you often need to copy a specific public key to a remote server's authorized_keys file - not just the default id_rsa.pub. The standard ssh-copy-id command doesn't directly support selecting which key to copy while authenticating with a different key.

In your scenario:

  1. Source key: mykey.rsa.pub (the public key you want to copy)
  2. Authentication key: hostkey.rsa (private key for auth to target server)
  3. Target server: user@target

While ssh-copy-id doesn't support this directly, we can construct the equivalent operation:

cat ~/.ssh/mykey.rsa.pub | ssh -i ~/.ssh/hostkey.rsa user@target "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

This pipeline:

  1. Outputs your specific public key (mykey.rsa.pub)
  2. Uses SSH with your authentication key (hostkey.rsa)
  3. On the remote server:
    • Creates the .ssh directory if needed
    • Sets proper permissions
    • Appends your public key to authorized_keys
    • Secures the permissions

If you prefer a more readable solution, you could use:

KEY_TO_COPY=~/.ssh/mykey.rsa.pub
AUTH_KEY=~/.ssh/hostkey.rsa
TARGET="user@target"

ssh -i "$AUTH_KEY" "$TARGET" "cat >> ~/.ssh/authorized_keys" < "$KEY_TO_COPY"

After running either command, verify the key was added:

ssh -i ~/.ssh/hostkey.rsa user@target "tail -n 1 ~/.ssh/authorized_keys"

Remember to:

  • Use 600 permissions for private keys
  • Keep authorized_keys at 600
  • Maintain 700 for .ssh directory
  • Consider using ssh-keygen -l -f keyfile.pub to verify fingerprints

For scripting scenarios, add error checking:

KEY_TO_COPY=~/.ssh/mykey.rsa.pub
AUTH_KEY=~/.ssh/hostkey.rsa
TARGET="user@target"

if [ ! -f "$KEY_TO_COPY" ]; then
    echo "Error: Public key not found at $KEY_TO_COPY" >&2
    exit 1
fi

if ! ssh -i "$AUTH_KEY" -o PasswordAuthentication=no "$TARGET" true; then
    echo "Error: Authentication failed" >&2
    exit 1
fi

ssh -i "$AUTH_KEY" "$TARGET" "mkdir -p ~/.ssh && chmod 700 ~/.ssh"
cat "$KEY_TO_COPY" | ssh -i "$AUTH_KEY" "$TARGET" "cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

When managing multiple SSH key pairs across servers, the standard ssh-copy-id behavior of copying all .ssh/*.pub keys becomes problematic. Consider this scenario where you need to:

  1. Copy only mykey.rsa.pub from Host to Target
  2. Authenticate using hostkey.rsa (private key counterpart of hostkey.rsa.pub)
  3. Maintain existing authorized_keys on Target

The correct command structure combines -i for both key selection and authentication:

ssh-copy-id -i ~/.ssh/mykey.rsa -i ~/.ssh/hostkey.rsa user@target

Key points about this command:

  • First -i specifies which public key to copy (can use either private or public key path)
  • Second -i defines the authentication key for the SSH connection
  • Omitting .pub extension automatically locates the public key

For environments where ssh-copy-id isn't available, use this SSH pipeline:

cat ~/.ssh/mykey.rsa.pub | ssh -i ~/.ssh/hostkey.rsa user@target "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

After key transfer, verify proper configuration:

ssh -v -i ~/.ssh/mykey.rsa user@target

Check the debug output for these confirmation messages:

Authenticated to target ([IP]) using "publickey".
debug1: Authentication succeeded (publickey).

For production environments, consider these enhancements:

# Restrict key usage in authorized_keys
command="/bin/restricted-shell",no-agent-forwarding,no-port-forwarding ssh-rsa AAAAB3Nza... user@host

This adds execution constraints to the transferred key.