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.