SSH Key Guide: Generation, Config & Security Hardening
Dev ToolsRachel Kim
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
Ed25519 (Recommended)
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#免密登录#安全