SSH is your front door. Every VPS on the internet faces thousands of SSH brute force attempts daily. Here's how to make your door unbreakable.
The Threat
A new VPS receives its first SSH brute force attempt within minutes of going online:
| Metric | Typical Value | |--------|--------------| | Login attempts per day | 1,000-10,000+ | | Unique attacker IPs per day | 50-200 | | Common usernames tried | root, admin, ubuntu, test | | Common passwords tried | 123456, password, admin |
Layer 1: Key-Based Authentication
Disable password authentication entirely:
# /etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
PubkeyAuthentication yes
With passwords disabled, brute force attacks become meaningless.
Key Management
| Key Type | Security | Recommendation | |----------|----------|---------------| | RSA 2048 | Adequate | Minimum acceptable | | RSA 4096 | Good | Good choice | | Ed25519 | Excellent | Best choice | | ECDSA | Good | Good choice |
Generate an Ed25519 key:
ssh-keygen -t ed25519 -C "your-email@example.com" -f ~/.ssh/vps_key
Layer 2: SSH Configuration Hardening
# /etc/ssh/sshd_config
# Change default port
Port 2222
# Only allow specific users
AllowUsers yourusername
# Disable root login
PermitRootLogin no
# Limit authentication attempts
MaxAuthTries 3
# Disconnect idle sessions
ClientAliveInterval 300
ClientAliveCountMax 2
# Disable X11 forwarding (if not needed)
X11Forwarding no
# Disable agent forwarding (if not needed)
AllowAgentForwarding no
# Use only Protocol 2
Protocol 2
Layer 3: Fail2Ban Advanced Configuration
# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 300
bantime = 86400
| Setting | Value | Effect | |---------|-------|--------| | maxretry: 3 | 3 attempts | Low tolerance | | findtime: 300 | 5 minutes | Short window | | bantime: 86400 | 24 hours | Long ban |
Monitor bans:
sudo fail2ban-client status sshd
Layer 4: Two-Factor Authentication
Add TOTP (Google Authenticator) to SSH:
sudo apt install libpam-google-authenticator
google-authenticator
Configure PAM:
# /etc/pam.d/sshd
auth required pam_google_authenticator.so
Configure SSH:
# /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Now login requires both your SSH key and a TOTP code.
Layer 5: Port Knocking (Advanced)
Hide your SSH port behind a knock sequence:
sudo apt install knockd
# /etc/knockd.conf
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 10
command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 2222 -j ACCEPT
tcpflags = syn
[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 10
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 2222 -j ACCEPT
tcpflags = syn
To connect: knock on ports 7000, 8000, 9000 in sequence, then SSH connects.
Monitoring
Log Analysis
# Failed login attempts
grep "Failed password" /var/log/auth.log | tail -20
# Successful logins
grep "Accepted" /var/log/auth.log | tail -20
# Currently banned IPs
sudo fail2ban-client status sshd
Real-Time Monitoring
# Watch auth log in real time
tail -f /var/log/auth.log | grep ssh
Security Checklist
| Layer | Protection | Stops | |-------|-----------|-------| | Key-only auth | 99% of brute force | Password guessing | | Non-standard port | 90% of automated scanners | Script kiddies | | Fail2ban | Repeated offenders | Persistent attackers | | 2FA | Compromised key scenario | Stolen keys | | Port knocking | Port detection | Port scanners |
You don't need all five layers. Key-only auth + Fail2ban + non-standard port stops 99.9% of attacks. Add 2FA for critical servers.
Space-Node's VPS hosting gives you full SSH control from deployment. KVM isolation means your SSH configuration can't be affected by other users, and the clean OS installation lets you harden from a known-good state.
