The first thing to do after setting up a VPS is hardening SSH. Disable password authentication, enforce key-based login, and restrict access with a firewall — these three steps stop the vast majority of attacks.
Leave SSH exposed on port 22 with default settings, and brute-force attempts start within minutes. This is not exaggeration — spin up a fresh VPS, wait an hour, and check /var/log/auth.log. You will find hundreds of failed login attempts from automated bots trying root with common passwords. That is the reality of every internet-facing SSH port.
This article walks through SSH hardening in progressive levels, from essential basics to completely hiding your SSH port from the internet.
Understanding SSH Risks
SSH is powerful, but being exposed to the internet makes it a constant target.
| Attack | Description |
|---|---|
| Brute force | Automated bots trying username/password combinations 24/7 |
| Credential stuffing | Using passwords leaked from other services |
| Port scanning | Discovering open ports. Port 22 open = immediate target |
| Key compromise | Leaked private keys without passphrases grant full access |
Research from Sucuri shows exposed SSH servers can receive 70,000–100,000 failed login attempts per day. Proper hardening reduces that to near zero.
Level 1: Essential Configuration
The minimum you must do. This alone stops most brute-force attacks.
Create a Regular User and Disable Root Login
adduser deploy
usermod -aG sudo deploy
Edit /etc/ssh/sshd_config.
PermitRootLogin no
AllowUsers deploy
Root is the most targeted account. Use a regular user with sudo instead.
Switch to Key Authentication and Disable Passwords
Generate a key pair on your local machine. Ed25519 is recommended — NIST approved it in FIPS 186-5 as a standard signature algorithm. Shorter keys with equivalent or better security than RSA.
ssh-keygen -t ed25519 -C "deploy@myserver"
ssh-copy-id deploy@YOUR_SERVER_IP
After confirming key-based login works, disable password authentication.
PasswordAuthentication no
PubkeyAuthentication yes
Apply the changes.
sudo systemctl restart sshd
Level 2: Deeper Defense
Add these on top of the basics to further reduce attack success rates.
Install fail2ban
fail2ban automatically bans IPs after repeated authentication failures.
sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edit /etc/fail2ban/jail.local.
[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 3600
findtime = 600
Three failures trigger a one-hour ban. This drastically reduces brute-force efficiency. For a more modern alternative, CrowdSec adds community-driven threat intelligence — it shares anonymized attack signatures across all users, so your server benefits from attacks blocked on other servers worldwide.
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Configure the Firewall
Use UFW to allow only necessary ports.
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Change the SSH Port (Optional)
Moving from port 22 to a non-standard port avoids most automated scanners.
Port 2222
This is security through obscurity — not a real defense. A port scan will still find it. Better than nothing, but do not rely on it.
Limit Authentication Attempts
MaxAuthTries 3
LoginGraceTime 30
Level 3: Hide SSH Completely
Everything above makes SSH secure enough. But not exposing the SSH port at all is the ultimate defense. You cannot attack a port that does not exist.
Allow SSH Only Through a VPN
Permit SSH connections only through a VPN tunnel and close the public SSH port.
Using NordVPN encrypts your traffic when managing a VPS from a cafe or public network. SSH over unencrypted WiFi is risky. Make it a habit to connect to a VPN before opening an SSH session — this alone significantly improves security.
Use Tailscale to Close the Port Entirely
For a more comprehensive solution, Tailscale is a mesh VPN built on WireGuard that hides your SSH port from the public internet entirely.
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --ssh
Close public SSH access with UFW.
sudo ufw delete allow ssh
Now SSH is only accessible from within the Tailscale network. From the public internet, the SSH port simply does not exist.
Tailscale is free for personal use (3 users, 100 devices). It also handles key management automatically and provides session recording for audit purposes.
For a detailed comparison of VPN options for development workflows, see our Developer VPN Guide. If you run NordVPN on your server or workstation, the NordVPN Linux Setup Guide covers CLI configuration. Developers should also check 5 Ways Developers Accidentally Leak Personal Info — SSH keys are just one vector.
For general key management best practices, NIST SP 800-57 provides comprehensive guidance on cryptographic key lifecycle, rotation, and storage.
FAQ
Is changing the SSH port from 22 actually useful?
It reduces noise from automated scanners, but it is not a real security measure. A targeted port scan will find the new port in seconds. Think of it as spam reduction, not defense. Always combine it with key authentication and fail2ban.
Should I use RSA or Ed25519 for SSH keys?
Ed25519. It is faster, produces shorter keys, and NIST approved it in FIPS 186-5. RSA-4096 is still secure, but there is no reason to choose it for new keys. If you have existing RSA keys, they are fine — just generate Ed25519 for new servers.
What happens if I lose my SSH key?
If password authentication is disabled and you lose the only authorized key, you are locked out. Most VPS providers offer a web console or recovery mode to regain access. Always keep a backup of your private key in a secure location and consider adding a second key as a fallback.
Can I use SSH key authentication and password authentication together?
Yes, OpenSSH supports both simultaneously. But the whole point of key auth is to eliminate password-based attacks. Keeping passwords enabled negates most of the security benefit. Disable password auth after confirming key auth works.
How does fail2ban differ from CrowdSec?
fail2ban monitors local logs and bans IPs after repeated failures — reactive and self-contained. CrowdSec adds a community layer: it shares anonymized attack signatures across all users, so your server can block known malicious IPs before they even try. CrowdSec is the more modern choice for multi-server setups.
Is Tailscale SSH free?
Yes. Tailscale's Personal plan is free for up to 3 users and 100 devices, which covers most personal VPS setups. The SSH feature, including automatic key management and session recording, is included at no cost.
Should I use a VPN every time I SSH into a server?
If you are on a trusted home or office network, SSH encryption itself is sufficient. But on public WiFi — cafes, airports, coworking spaces — a VPN adds an important encryption layer that protects against network-level attacks. It is a good habit to connect to a VPN before any remote administration over untrusted networks.
Wrapping Up
| Level | Actions | Effect |
|---|---|---|
| 1 (Essential) | Key auth + disable passwords + no root login | Stops most brute force |
| 2 (Recommended) | fail2ban + firewall + port change | Significantly reduces remaining attacks |
| 3 (Maximum) | VPN-only / Tailscale to close the port | Attacks become impossible |
Level 1 is mandatory for every VPS administrator. It takes five minutes. Level 2 handles most remaining threats. Level 3 removes the SSH port from the internet entirely, making attacks structurally impossible.
If you manage VPSes from cafes or public networks, use NordVPN to encrypt your connection before SSH. That one habit makes a measurable difference.
The world's leading VPN — fast, secure, and easy to use
- 6,400+ servers across 111 countries
- NordLynx protocol (WireGuard-based)
- Threat Protection Pro (ads & malware blocking)
Related articles: