Skip to main content

SSH Hardening: Secure sshd_config Configuration on a VPS

VDS / VPS · 19.04.2026 · 5 min read
Illustration for “SSH Hardening: Secure sshd_config Configuration on a VPS”

SSH is the main way to access a VPS. By default it runs on port 22 and is exposed to brute-force attacks. Proper configuration minimizes the risk of a breach.

A Secure /etc/ssh/sshd_config

># Change the default port (optional, but recommended)
Port 2222

# Disable root login
PermitRootLogin no

# Allow login only for specific users
AllowUsers deploy admin

# Disable password login (keys only!)
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no

# Disable X11 forwarding
X11Forwarding no

# Idle session timeout (5 minutes)
ClientAliveInterval 300
ClientAliveCountMax 2

# IPv4 only (if you don't need IPv6)
AddressFamily inet

# SSH protocol 2 (the legacy protocol 1 is no longer used, but state it explicitly)
Protocol 2

# Encryption algorithms (modern)
KexAlgorithms curve25519-sha256,diffie-hellman-group14-sha256
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com

Apply the Changes

# Check the syntax before restarting!
sudo sshd -t

# Restart SSH
sudo systemctl restart sshd

# Do not close the current session — open a new window and test the login
⚠️ Do not close your current SSH session until you've verified the new login. If you made a mistake, you could lose access to the server. Always test in a new tab.

Generating and Adding SSH Keys

# On the client — generate a key (Ed25519 — modern and secure)
ssh-keygen -t ed25519 -C "myserver" -f ~/.ssh/myserver

# Copy the public key to the server
ssh-copy-id -i ~/.ssh/myserver.pub user@server.example.com

# Add the public key manually
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Fail2Ban — Protection Against Brute-Force

>sudo apt install fail2ban -y

# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 2222          # your SSH port
maxretry = 5         # attempts before a ban
bantime = 3600       # ban for 1 hour
findtime = 600       # 10-minute window

sudo systemctl enable --now fail2ban

# View banned IPs
sudo fail2ban-client status sshd
💡 Secure SSH checklist:
  • ✓ Key-only login (PasswordAuthentication no)
  • ✓ PermitRootLogin no
  • ✓ Non-standard port
  • ✓ AllowUsers — only the users you need
  • ✓ Fail2Ban active
  • ✓ UFW allows SSH only from the IPs you need

Common SSH hardening mistakes

Most SSH problems after hardening fall into two buckets — "the server won't start" and "access is lost" — and it matters which one you're dealing with.

sshd: no hostkeys available -- exiting.

The service can't find the host key files — typical after manually deleting or moving /etc/ssh/ssh_host_*_key. Regenerate them: ssh-keygen -A, then restart sshd.

Permission denied (publickey).

This exact error shows up when PasswordAuthentication no was applied before the public key was actually added and verified in a new session. That ordering is the difference between a working server and lost access. Always test key-based login in a separate window BEFORE disabling passwords, as noted in the instructions below.

/etc/ssh/sshd_config line 27: Bad configuration option: Protocol

The Protocol 2 directive in the example configuration above is a leftover from old versions. As of OpenSSH 7.6 it's deprecated, and some OpenSSH 8.0+ builds reject the line outright during syntax checking. SSH protocol version 1 was removed from the code long ago, and version 2 is used by default with no need to state it — just remove the line from the config.

Authentication methods compared

MethodBrute-force resistanceConvenienceCompromise risk
PasswordLowHigh (no file needed)Guessing, leaks, phishing
SSH key (Ed25519)HighNeeds access to the private keyTheft of the key file
Key + passphraseVery highRequires entering a passphraseMinimal even if the file is stolen
SSH certificates (CA)Very highRequires CA infrastructureMinimal, revocable

An Ed25519 key is enough for a single VPS. For server fleets of 10+ machines, it's worth looking at SSH certificates — they save you from adding and revoking keys on every server one by one.

When strict hardening doesn't fit

Changing the port reduces log noise from automated scanners — it's not protection against a targeted attack: if an attacker already knows the IP and is targeting that specific server, scanning the port range takes seconds. Don't treat a non-standard port as a substitute for the other measures. Disabling PermitRootLogin can break installers for legacy control panels that expect direct root SSH access — before hardening, check whether the software you're running needs that kind of access during first install or upgrade. If an external team manages the server under a corporate policy requiring password access over VPN, disabling PasswordAuthentication means first agreeing on a switch to keys with everyone who logs in.

How to verify the result

Check more than "the connection worked" — confirm what actually took effect on the server:

# Check that sshd is listening on the new port
sudo ss -tlnp | grep sshd

# Check fail2ban's status for sshd
sudo fail2ban-client status sshd

# Verbose connection output — shows which key is being used
ssh -v -p 2222 user@server.example.com

In the ssh -v output, look for the line Authentication succeeded (publickey) — if the server asks for a password instead, either PasswordAuthentication no hasn't taken effect yet, or the key isn't in the authorized_keys file of the user you're logging in as.

Was this article helpful?
← Back to Knowledge Base Ask Support