TL;DR
- Generate a keypair (public + private). Share the public key; never share the private key.
- Put the public key in the server’s
~/.ssh/authorized_keys, then connect withssh user@host. - Use ed25519 keys by default; use rsa‑4096 only for legacy systems.
- Protect the private key with a passphrase and load it into ssh‑agent.
- Harden servers: disable password auth and root SSH, use firewall + fail2ban.
1) Generate a keypair
Recommended (Ed25519):
ssh-keygen -t ed25519 -C "[email protected]"
# Saves to: ~/.ssh/id_ed25519 (private) and ~/.ssh/id_ed25519.pub (public)
# Choose a strong passphrase when prompted
Legacy compatibility (RSA 4096, with modern key derivation):
ssh-keygen -t rsa -b 4096 -o -a 100 -C "[email protected]"
# Files: ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub
Private key (
id_ed25519/id_rsa) stays on your machine. Public key (.pub) can be shared/pasted on servers and dev platforms.
2) Install your public key on the server
Quick way (macOS/Linux):
ssh-copy-id [email protected]
Manual way (works everywhere):
# On your laptop
cat ~/.ssh/id_ed25519.pub
# On the server (as target user)
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI.... [email protected]" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Windows paths: keys live in C:\Users\<you>\.ssh\.
Permissions (PowerShell):
icacls $HOME\.ssh\id_ed25519 /inheritance:r
icacls $HOME\.ssh\id_ed25519 /grant:r "$($env:USERNAME):(R)"
3) Connect
ssh [email protected]
# custom port
ssh -p 2222 [email protected]
# specify identity explicitly
ssh -i ~/.ssh/id_ed25519 [email protected]
Increase verbosity when debugging:
ssh -vvv [email protected]
4) Use ssh‑agent (no passphrase prompts every time)
macOS/Linux (bash/zsh):
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# list loaded keys
ssh-add -l
Windows 10+ (PowerShell, built‑in OpenSSH):
Start-Service ssh-agent
Get-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519
On macOS, keys can be stored in the Keychain (
ssh-add --apple-use-keychain ~/.ssh/id_ed25519).
5) Make aliases with ~/.ssh/config
Create ~/.ssh/config (permissions 600) and add hosts:
Host prod
HostName server.example.com
User ubuntu
Port 22
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
AddKeysToAgent yes
ForwardAgent no
Host db
HostName 10.0.2.15
User postgres
ProxyJump prod
Now connect with:
ssh prod
ssh db # jumps through 'prod'
6) Use SSH keys with Git (GitHub/GitLab)
Test:
ssh -T [email protected]
# or
ssh -T [email protected]
Set remote:
git remote set-url origin [email protected]:yourname/yourrepo.git
Add your public key (.pub) in the platform’s SSH Keys settings.
7) Server hardening (must‑do basics)
Edit /etc/ssh/sshd_config (as root) and set:
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin no
ChallengeResponseAuthentication no
UsePAM yes
Then reload:
sudo systemctl reload sshd # some distros: ssh
Important: keep an existing SSH session open while testing, so you don’t lock yourself out.
Firewall & abuse protection:
# Ubuntu example
sudo ufw allow 22/tcp
sudo ufw enable
# Optional: fail2ban
sudo apt install fail2ban
8) Rotate & revoke keys
- Generate a new keypair and add it to all servers/services.
- Remove the old public keys from
authorized_keys. - If a private key leaks, revoke immediately and rotate credentials (and audit logs).
Common errors & quick fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Permission denied (publickey) | Public key not on server or wrong user/path | Ensure key is in ~/.ssh/authorized_keys for the right user; correct perms 700 ~/.ssh, 600 authorized_keys |
| “Permissions are too open” | Private key mode too permissive | chmod 600 ~/.ssh/id_ed25519 (and 700 ~/.ssh) |
| “Too many authentication failures” | Agent has many keys; server gives up | ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 host or set in config |
| “Host key verification failed” | Server’s fingerprint changed | Verify change is legitimate; update ~/.ssh/known_hosts |
| Can’t use ed25519 on old boxes | Old OpenSSH/OpenSSL | Generate RSA‑4096 and use that key for legacy hosts |
Quick checklist
- [ ] Use ed25519 with a passphrase; store via ssh‑agent.
- [ ] Add public key to
~/.ssh/authorized_keyswith correct permissions. - [ ] Create
~/.ssh/configaliases; preferIdentitiesOnly yes. - [ ] Disable password auth and root SSH on servers.
- [ ] Keep a firewall on; consider fail2ban.
- [ ] Rotate keys periodically and after any suspicion of compromise.
One‑minute setup plan
ssh-keygen -t ed25519 -C "[email protected]"→ set passphrase.ssh-copy-id user@server(or paste.pubtoauthorized_keys).eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519.- Create
~/.ssh/configwith an alias andIdentitiesOnly yes. - Harden server (
PasswordAuthentication no,PermitRootLogin no) and test.