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:
- Source key:
mykey.rsa.pub
(the public key you want to copy) - Authentication key:
hostkey.rsa
(private key for auth to target server) - 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:
- Outputs your specific public key (
mykey.rsa.pub
) - Uses SSH with your authentication key (
hostkey.rsa
) - On the remote server:
- Creates the
.ssh
directory if needed - Sets proper permissions
- Appends your public key to
authorized_keys
- Secures the permissions
- Creates the
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
at600
- 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:
- Copy only
mykey.rsa.pub
from Host to Target - Authenticate using
hostkey.rsa
(private key counterpart ofhostkey.rsa.pub
) - 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.