32blogby StudioMitsu
security5 min read

SSH Security Guide: From Key Auth to VPN-Only Access

Harden SSH step by step. Key authentication, fail2ban, firewall rules, and hiding SSH behind a VPN. A practical guide for VPS administrators.

SSHVPNVPSsecurity
On this page

The first thing to do after setting up a VPS is hardening SSH. Leave SSH exposed on port 22 with default settings, and brute-force attempts start within minutes. This is not exaggeration — check /var/log/auth.log on any new VPS and see for yourself.

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.

AttackDescription
Brute forceAutomated bots trying username/password combinations 24/7
Credential stuffingUsing passwords leaked from other services
Port scanningDiscovering open ports. Port 22 open = immediate target
Key compromiseLeaked private keys without passphrases grant full access

Level 1: Essential Configuration

The minimum you must do. This alone stops most brute-force attacks.

Create a Regular User and Disable Root Login

bash
adduser deploy
usermod -aG sudo deploy

Edit /etc/ssh/sshd_config.

text
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 — shorter keys with equivalent or better security than RSA.

bash
ssh-keygen -t ed25519 -C "deploy@myserver"
ssh-copy-id deploy@YOUR_SERVER_IP

After confirming key-based login works, disable password authentication.

text
PasswordAuthentication no
PubkeyAuthentication yes

Apply the changes.

bash
sudo systemctl restart sshd

Level 2: Deeper Defense

Add these on top of the basics to further reduce attack success rates.

Install fail2ban

Automatically bans IPs after repeated authentication failures.

bash
sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Edit /etc/fail2ban/jail.local.

text
[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 3600
findtime = 600

Three failures trigger a one-hour ban. This drastically reduces brute-force efficiency.

bash
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Configure the Firewall

Use UFW to allow only necessary ports.

bash
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.

text
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

text
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.

bash
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --ssh

Close public SSH access with UFW.

bash
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.

Wrapping Up

LevelActionsEffect
1 (Essential)Key auth + disable passwords + no root loginStops most brute force
2 (Recommended)fail2ban + firewall + port changeSignificantly reduces remaining attacks
3 (Maximum)VPN-only / Tailscale to close the portAttacks 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.