SSH Key Guide: Generation, Config & Security Hardening

Dev Tools

SSH Keys: A More Secure Authentication Method Than Passwords

Comparison Password SSH Key
Authentication factor Knowledge factor (something you know) Possession factor (something you have)
Brute-force attacks Possible Practically impossible
Phishing risk High Low (the private key never leaves your machine)
Server breach Plaintext/hashed passwords can be cracked Only public keys stored; private key can't be derived
Convenience Type it every time Configure once, authenticate automatically

1. Generating a Key Pair

ssh-keygen -t ed25519 -C "your@email.com"
Parameter Description
-t ed25519 Algorithm type (Ed25519 — most secure and fastest)
-C Comment (usually your email as an identifier)

RSA (Compatibility Fallback)

ssh-keygen -t rsa -b 4096 -C "your@email.com"
Algorithm Key Length Security Performance Recommended
Ed25519 256 bit Highest Fastest ✅
ECDSA P256 256 bit High Fast Optional
RSA 4096 4096 bit High Slow Compatibility fallback
RSA 2048 2048 bit Medium Slow ❌ Not recommended

The Generation Process

$ ssh-keygen -t ed25519 -C "dev@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase): ****
Enter same passphrase again: ****
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub

Strongly recommend setting a passphrase: even if the private key leaks, a passphrase prevents it from being used directly.


2. Deploying the Public Key

GitHub / GitLab

# Copy the public key
cat ~/.ssh/id_ed25519.pub | clip

# GitHub → Settings → SSH and GPG keys → New SSH key
# Paste the public key content

Servers

# Option 1: ssh-copy-id
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server.com

# Option 2: append manually
cat ~/.ssh/id_ed25519.pub | ssh user@server.com 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'

Verify the Connection

ssh -T git@github.com
# Hi username! You've successfully authenticated...

ssh user@server.com
# Logs in directly, no password required

3. Multi-Account Configuration

Scenario: Work GitHub + Personal GitHub

# Generate two key pairs
ssh-keygen -t ed25519 -C "work@company.com" -f ~/.ssh/id_work
ssh-keygen -t ed25519 -C "personal@gmail.com" -f ~/.ssh/id_personal

SSH Config

# ~/.ssh/config
Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_work
  IdentitiesOnly yes

Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_personal
  IdentitiesOnly yes

Using with Git

# Work repository
git clone git@github-work:company/project.git

# Personal repository
git clone git@github-personal:username/project.git

Multi-Platform Configuration

# ~/.ssh/config
Host github.com
  User git
  IdentityFile ~/.ssh/id_github

Host gitlab.com
  User git
  IdentityFile ~/.ssh/id_gitlab

Host gitee.com
  User git
  IdentityFile ~/.ssh/id_gitee

Host dev.azure.com
  User git
  IdentityFile ~/.ssh/id_azure

4. SSH Agent Management

Start the Agent

eval "$(ssh-agent -s)"

Add Keys

ssh-add ~/.ssh/id_ed25519
# Enter passphrase: ****

# List added keys
ssh-add -l
# 256 SHA256:xxx... dev@example.com (ED25519)

Auto-Start (bashrc)

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

Persisting with Keychain

# macOS: store the passphrase in Keychain
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

# Linux: use keychain
eval "$(keychain --eval id_ed25519)"

5. Jump Host Configuration

Scenario: Local → Jump Host → Production Server

# ~/.ssh/config
Host jumpbox
  HostName jump.example.com
  User jump-user
  IdentityFile ~/.ssh/id_jump

Host production
  HostName 10.0.1.100
  User deploy
  IdentityFile ~/.ssh/id_prod
  ProxyJump jumpbox
# Connect to the production server directly (automatically via the jump host)
ssh production

Agent Forwarding

Host jumpbox
  HostName jump.example.com
  ForwardAgent yes

Security note: only enable agent forwarding when you trust the jump host.


6. Security Hardening

Server-Side sshd_config

# /etc/ssh/sshd_config
PermitRootLogin no                    # Disable root login
PasswordAuthentication no             # Disable password login
PubkeyAuthentication yes             # Allow key-based login only
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3                       # Maximum authentication attempts
LoginGraceTime 30                    # Login timeout of 30 seconds
AllowUsers deploy admin              # Whitelisted users

Key Permissions

# Private key must be 600
chmod 600 ~/.ssh/id_ed25519

# .ssh directory must be 700
chmod 700 ~/.ssh

# authorized_keys must be 600
chmod 600 ~/.ssh/authorized_keys

Key Rotation

# 1. Generate a new key
ssh-keygen -t ed25519 -C "dev@example.com" -f ~/.ssh/id_ed25519_new

# 2. Deploy the new public key to all servers/Git platforms
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@server

# 3. Verify the new key works
ssh -i ~/.ssh/id_ed25519_new user@server

# 4. Remove the old public key
# Edit ~/.ssh/authorized_keys on the server and delete the old key line

# 5. Delete the old key
rm ~/.ssh/id_ed25519_old

7. Troubleshooting Common Issues

Problem Cause Solution
Permission denied Public key not deployed ssh-copy-id
Too many authentication failures Too many keys in the agent IdentitiesOnly yes
Are you sure you want to continue connecting First connection StrictHostKeyChecking=accept-new
Slow connection Reverse DNS lookup UseDNS no (server-side)
Key not working Wrong permissions chmod 600 on the private key

Debug Mode

ssh -vvv user@server.com
# Verbose output of the connection process to pinpoint authentication failures
#SSH#密钥#Git#免密登录#安全