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.