SSH Configuration
Secure SSH with key-based authentication and hardening.
SSH is the front door to most Linux servers. Secure SSH first, then build everything else on top of it. The biggest wins are: key-based auth, no root login, and no password auth.
SSH Key Authentication
# Generate key pair
$ ssh-keygen -t ed25519 -C "your@email.com"
# Copy to server
$ ssh-copy-id user@server
# Connect with key
$ ssh -i ~/.ssh/id_ed25519 user@server
$ ssh-keygen -t ed25519 -C "your@email.com"
# Copy to server
$ ssh-copy-id user@server
# Connect with key
$ ssh -i ~/.ssh/id_ed25519 user@server
Permissions matter
SSH is strict about file permissions. If your keys arenβt working, this is a common cause.
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/id_ed25519
$ chmod 644 ~/.ssh/id_ed25519.pub
$ chmod 600 ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/id_ed25519
$ chmod 644 ~/.ssh/id_ed25519.pub
Client config (quality of life)
Use ~/.ssh/config so you donβt have to remember flags and ports.
# ~/.ssh/config
Host myserver
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
$ ssh myserver
Host myserver
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
$ ssh myserver
SSH Hardening (/etc/ssh/sshd_config)
Hardening is about reducing brute-force success and limiting who can log in. After changes, always validate config and keep a second session open.
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Port 2222 # Non-standard port
AllowUsers pranav # Whitelist users
PasswordAuthentication no
PubkeyAuthentication yes
Port 2222 # Non-standard port
AllowUsers pranav # Whitelist users
Additional hardening knobs (common)
MaxAuthTries 3
LoginGraceTime 30
PermitEmptyPasswords no
X11Forwarding no
AllowTcpForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 30
PermitEmptyPasswords no
X11Forwarding no
AllowTcpForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
Validate and reload safely
# Validate config (does not restart)
$ sudo sshd -t
# Reload without dropping existing connections (preferred)
$ sudo systemctl reload ssh
$ sudo journalctl -u ssh -n 50 --no-pager
$ sudo sshd -t
# Reload without dropping existing connections (preferred)
$ sudo systemctl reload ssh
$ sudo journalctl -u ssh -n 50 --no-pager
Troubleshooting
# Client-side verbose output
$ ssh -vvv user@server
# Server-side logs
$ sudo journalctl -u ssh -f
$ ssh -vvv user@server
# Server-side logs
$ sudo journalctl -u ssh -f
β Practice (20 minutes)
- Generate an ed25519 key and add it to
authorized_keys. - Disable password authentication and validate using
sshd -tbefore reloading. - Use
ssh -vvvto understand the authentication flow.