Security
Generate SSH key pairs, manage authorized keys, and use SSH agent for secure access.
▶ Watch the demo: fix "Permission denied (publickey)" in 4 steps (24 sec)Watch on YouTubeSubscribe
Contents
Generate an SSH Key Pair
# Modern Ed25519 key (recommended)
ssh-keygen -t ed25519 -C "craig@example.com"
# RSA 4096-bit (for legacy compatibility)
ssh-keygen -t rsa -b 4096 -C "craig@example.com"
# Keys are saved to:
# ~/.ssh/id_ed25519 (private key)
# ~/.ssh/id_ed25519.pub (public key)
Copy Key to Server
# Automated (recommended)
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server.ip
# Manual alternative
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
SSH Client Config (~/.ssh/config)
Define host aliases to simplify SSH connections:
Host myserver
HostName 203.0.113.10
User craig
Port 2222
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
Host staging
HostName staging.example.com
User deploy
IdentityFile ~/.ssh/id_ed25519
# Connect using the alias
ssh myserver
SSH Agent
# Start agent and add key
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_ed25519
# List loaded keys
ssh-add -l
# On macOS: add to keychain so key persists after reboot
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
Server-Side Hardening
sudo nano /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
LoginGraceTime 30
sudo systemctl restart sshd
Fix "Permission denied (publickey)"
Work through these in order. Step 4 is the most common cause: SSH silently ignores keys when the permissions on the server are too open.
# 1. Is your key loaded in the agent?
ssh-add -l
# 2. Load it
ssh-add ~/.ssh/id_ed25519
# 3. Copy the public key to the server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# 4. On the server: fix permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# 5. Still failing? See exactly which key is offered and why it is rejected
ssh -v user@server
Last updated October 2026.