Secure SSH
This guide explains how to secure SSH access to your Linux VPS with keys and fail2ban.
SSH Key Authentication
SSH keys are more secure than passwords because they cannot be guessed by brute force.
Generate a Key Pair
On your local computer (not on the VPS):
# Windows (PowerShell) / macOS / Linux
ssh-keygen -t ed25519 -C "your@email.com"
Press Enter to accept the default location. Add a passphrase for extra security.
Two files are created:
~/.ssh/id_ed25519(private key - never share)~/.ssh/id_ed25519.pub(public key - to copy to the VPS)
Copy the Key to the VPS
Simple method:
ssh-copy-id root@YOUR_IP
Manual method:
# On your computer, display the public key
cat ~/.ssh/id_ed25519.pub
# On the VPS, add the key
mkdir -p ~/.ssh
nano ~/.ssh/authorized_keys
# Paste the public key and save
# Correct permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Test the Connection
ssh root@YOUR_IP
You should connect without a password (or with the key passphrase).
Disable Password Authentication
First test that key authentication works before disabling passwords!
sudo nano /etc/ssh/sshd_config
Modify these lines:
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin prohibit-password
Restart SSH:
sudo systemctl restart sshd
Change the SSH Port
Changing the default port (22) reduces automated attacks.
sudo nano /etc/ssh/sshd_config
Port 2222
Before restarting SSH, allow the new port in the firewall:
sudo ufw allow 2222/tcp
sudo systemctl restart sshd
Connect with the new port:
ssh -p 2222 root@YOUR_IP
Fail2ban - Attack Protection
Fail2ban automatically blocks IPs that attempt too many failed connections.
Installation
sudo apt update
sudo apt install fail2ban
Configuration
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Modify the [sshd] section:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600
Parameters:
maxretry: Number of attempts before banningfindtime: Observation period (seconds)bantime: Ban duration (seconds), -1 = permanent
Advanced Configuration
For a custom SSH port:
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
Start fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Useful Commands
# Fail2ban status
sudo fail2ban-client status
# SSH jail status
sudo fail2ban-client status sshd
# View banned IPs
sudo fail2ban-client status sshd | grep "Banned IP"
# Unban an IP
sudo fail2ban-client set sshd unbanip 192.168.1.100
# View logs
sudo tail -f /var/log/fail2ban.log
Other Best Practices
Limit Allowed Users
sudo nano /etc/ssh/sshd_config
AllowUsers admin deployer
# or
AllowGroups ssh-users
Disable Direct Root Connections
First create a user with sudo:
adduser admin
usermod -aG sudo admin
Then disable root:
PermitRootLogin no
Inactivity Timeout
ClientAliveInterval 300
ClientAliveCountMax 2
Disable Unnecessary Features
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
Recommended Complete SSH Configuration
# /etc/ssh/sshd_config
Port 2222
PermitRootLogin prohibit-password
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
AllowTcpForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
MaxAuthTries 3
MaxSessions 3
SSH Security Checklist
- SSH keys configured
- Password authentication disabled
- SSH port changed
- Fail2ban installed and configured
- Root connection limited or disabled
- Firewall configured with the correct port
Always keep an SSH session open when modifying SSH configuration, to avoid locking yourself out in case of error.