Skip to main content

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​

Important

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
Warning

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 banning
  • findtime: 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
# /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
Tip

Always keep an SSH session open when modifying SSH configuration, to avoid locking yourself out in case of error.