Skip to Content
Bash & LinuxSSH Keys

SSH Keys

SSH keys provide a secure, passwordless way to authenticate to remote servers and services. This page covers generating keys, deploying them, managing multiple identities, and key rotation.

Key Types

TypeRecommendationNotes
ED25519PreferredFast, small key size, strong security
ECDSAAcceptableUse -b 521 for the strongest curve
RSALegacyUse -b 4096 if ED25519 is not supported
DSAAvoidDeprecated; not supported in OpenSSH 7.0+

Generating a Key Pair

# Generate an ED25519 key (recommended) ssh-keygen -t ed25519 -C "your-comment" # Generate an RSA key (4096-bit minimum if ED25519 is unavailable) ssh-keygen -t rsa -b 4096 -C "your-comment"

The -C flag adds a comment to the public key to help identify it — typically an email address, hostname, or purpose (e.g. work-laptop, github).

When prompted:

  • File location — Press Enter to accept the default (~/.ssh/id_ed25519) or specify a custom path for multiple keys
  • Passphrase — Strongly recommended; encrypts the private key at rest

This produces two files:

  • ~/.ssh/id_ed25519 — private key (never share this)
  • ~/.ssh/id_ed25519.pub — public key (safe to share)

Deploying a Key to a Server

# Copy your public key to the remote server ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server # Specify a non-standard port ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 9437 user@server

Manually

# On the server, append the public key to authorized_keys mkdir -p ~/.ssh && chmod 700 ~/.ssh echo "<paste-public-key-here>" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys

Permissions must be exact — SSH will silently refuse keys if they are too permissive.

Adding Keys to GitHub / GitLab

# Print the public key to copy to your clipboard cat ~/.ssh/id_ed25519.pub
  1. Copy the output
  2. GitHub: Settings → SSH and GPG keys → New SSH key
  3. GitLab: Preferences → SSH Keys → Add new key

Test the connection after adding:

ssh -T git@github.com ssh -T git@gitlab.com

Managing Multiple Keys with ~/.ssh/config

When you have different keys for different hosts (e.g. personal vs. work GitHub, multiple servers), use ~/.ssh/config to map hosts to their keys automatically.

# Create or edit the SSH config file nano ~/.ssh/config
# Personal GitHub Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519_personal # Work GitHub Host github-work HostName github.com User git IdentityFile ~/.ssh/id_ed25519_work # Production server Host prod HostName 10.0.1.50 User deploy Port 9437 IdentityFile ~/.ssh/id_ed25519_prod IdentitiesOnly yes
# Set correct permissions on the config file chmod 600 ~/.ssh/config

With this config, you can use the alias instead of the full hostname:

# Clone using the work GitHub alias git clone git@github-work:org/repo.git # SSH to the production server using its alias ssh prod

IdentitiesOnly yes tells SSH to use only the key specified in the config and not to try others from the agent — this prevents unexpected key usage.

SSH Agent

The SSH agent holds decrypted private keys in memory so you only need to enter the passphrase once per session.

# Start the agent (usually already running in a desktop session) eval "$(ssh-agent -s)" # Add the default key ssh-add # Add a specific key ssh-add ~/.ssh/id_ed25519_work # List keys currently loaded in the agent ssh-add -l # Remove a specific key from the agent ssh-add -d ~/.ssh/id_ed25519_work # Remove all keys from the agent ssh-add -D

Persist Agent Keys Across Sessions (macOS / systemd)

On macOS, add this to ~/.ssh/config to use the keychain:

Host * AddKeysToAgent yes UseKeychain yes

On Linux with systemd, create a user service or use ~/.bashrc / ~/.zshrc:

# Add to ~/.bashrc or ~/.zshrc if [ -z "$SSH_AUTH_SOCK" ]; then eval "$(ssh-agent -s)" > /dev/null ssh-add ~/.ssh/id_ed25519 2>/dev/null fi

Viewing and Verifying Keys

# Show the fingerprint of a public key ssh-keygen -lf ~/.ssh/id_ed25519.pub # Show the fingerprint in a visual (randomart) format ssh-keygen -lvf ~/.ssh/id_ed25519.pub # Show all public keys on a remote server's authorized_keys cat ~/.ssh/authorized_keys # View the comment and type of a public key cat ~/.ssh/id_ed25519.pub

Key Rotation

Rotate keys when:

  • A key or device is compromised
  • An employee with key access leaves
  • As part of a regular security review
# 1. Generate a new key pair ssh-keygen -t ed25519 -C "rotated-$(date +%Y-%m)" -f ~/.ssh/id_ed25519_new # 2. Deploy the new public key to all target servers ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@server # 3. Verify login works with the new key before removing the old one ssh -i ~/.ssh/id_ed25519_new user@server # 4. Remove the old public key from each server's authorized_keys # Edit the file and delete the line containing the old key fingerprint nano ~/.ssh/authorized_keys # 5. Delete the old private key locally once confirmed rm ~/.ssh/id_ed25519_old rm ~/.ssh/id_ed25519_old.pub

Permissions Reference

SSH will refuse to use keys or configs with incorrect permissions.

PathRequired Permission
~/.ssh/700
~/.ssh/authorized_keys600
~/.ssh/config600
~/.ssh/id_ed25519 (private key)600
~/.ssh/id_ed25519.pub (public key)644
# Fix permissions in one pass chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys ~/.ssh/config ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub

Best Practices

  • Always protect private keys with a passphrase
  • Use ED25519 keys; avoid RSA keys shorter than 4096 bits and never use DSA
  • Use a separate key per device — if a device is compromised, revoke only that key
  • Use descriptive comments (-C) to track which key belongs to which device or purpose
  • Regularly audit authorized_keys on servers and remove stale entries
  • Never store private keys in version control, cloud storage, or email
  • Use IdentitiesOnly yes in ~/.ssh/config to prevent unintended key negotiation
Last updated on