Skip to content
Back to Blog
Security9 min read

SSH Hardening Mistakes: What Everyone Gets Wrong on Their VPS

Even experienced admins make critical SSH hardening mistakes that leave their VPS exposed. Learn the most common errors—from weak key management to firewall misconfigurations—and the correct approach to each.

Written by Abdul AbrorTechnical Hosting Support Engineer
SSH Hardening Mistakes: What Everyone Gets Wrong on Their VPS
On this page

SSH is the gateway to your VPS. Get it wrong and you've left the front door unlocked. Yet even experienced sysadmins make preventable mistakes when hardening SSH—mistakes that range from inconvenient lockouts to complete server compromises. This guide walks through the most common SSH hardening errors and shows you the correct approach for each.

Mistake 1: Only Changing the SSH Port and Calling It Secure

Changing the default SSH port from 22 to something like 2222 or 22022 is often the first and only hardening step people take. While obscurity reduces automated scan noise, it provides no real security against a determined attacker.

Why This Is a Problem

Port scanning is trivial. Any attacker who targets your server specifically will find your SSH port in seconds. Relying solely on a non-standard port creates false confidence while leaving authentication and access controls weak.

The Correct Approach

  • Change the port as one layer among many, not as your primary defense
  • Focus first on disabling password authentication and enforcing key-based auth
  • Implement fail2ban or similar intrusion prevention
  • Use firewall rules to restrict SSH access by IP when possible

Edit /etc/ssh/sshd_config:

Port 2849
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin prohibit-password

Then restart SSH:

systemctl restart sshd

Port changes belong in a layered security strategy, not standing alone.

Mistake 2: Locking Yourself Out Before Testing

The classic mistake: you edit sshd_config, restart the SSH service, disconnect, and suddenly cannot reconnect. The changes contained a syntax error, disabled your authentication method, or blocked your IP.

Why This Is a Problem

Without an active session or console access, you're locked out of your own server. Recovery requires your hosting provider's emergency console, VNC access, or a support ticket—none of which are ideal.

The Correct Approach

Always maintain two SSH sessions when making changes:

  1. Open your first SSH session
  2. Make configuration changes in that session
  3. Test the configuration: sshd -t
  4. Reload (not restart) SSH: systemctl reload sshd
  5. Open a second SSH session to verify you can still connect
  6. Only after successful connection in the second session should you close the first

If the new connection fails, you still have your original session to revert changes.

For critical changes, use systemctl reload instead of restart when possible—reload preserves existing connections while applying new settings to future connections.

Mistake 3: Weak SSH Key Generation and Management

Many guides tell you to generate SSH keys, but few emphasize key strength and proper management. Common mistakes include using default RSA key sizes, storing keys insecurely, or reusing the same key across multiple servers.

Why This Is a Problem

Weak keys can be cracked. Reused keys mean one compromise affects multiple servers. Keys without passphrases offer no protection if your local machine is compromised.

The Correct Approach

Generate strong keys with proper algorithms:

# Ed25519 (preferred for modern systems)
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_production

# Or RSA with 4096 bits if Ed25519 isn't supported
ssh-keygen -t rsa -b 4096 -C "[email protected]" -f ~/.ssh/id_rsa_production

Always protect keys with strong passphrases. Use different keys for different servers or contexts (production, staging, personal). Store private keys with restrictive permissions:

chmod 600 ~/.ssh/id_ed25519_production
chmod 644 ~/.ssh/id_ed25519_production.pub

On the server side, ensure proper permissions:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Never commit private keys to version control or store them in cloud sync folders without encryption.

Mistake 4: Leaving Root Login Enabled

Permitting direct root SSH login is one of the most dangerous configurations you can leave in place. Many distributions still ship with PermitRootLogin yes by default.

Why This Is a Problem

Root is a known username on every Linux system. Attackers only need to guess or crack the password or key. If compromised, they have immediate full system access with no audit trail of which user account was responsible.

The Correct Approach

Disable root login entirely and use sudo for privilege escalation:

# In /etc/ssh/sshd_config
PermitRootLogin no

Create a non-root user with sudo privileges:

adduser youruser
usermod -aG sudo youruser

Copy your SSH key to the new user's authorized_keys, test login as that user, then disable root login. This creates an audit trail (you know which user account authenticated) and adds a second authentication step via sudo.

If you absolutely must allow root login during initial setup, use PermitRootLogin prohibit-password to require key-based auth, then disable it entirely once your user account is configured.

Mistake 5: Forgetting to Configure the Firewall

Hardening SSH configuration is pointless if your firewall allows SSH connections from anywhere. Many admins configure sshd_config carefully but leave ufw or firewalld wide open or disabled entirely.

Why This Is a Problem

Without firewall rules, your SSH port is exposed to the entire internet. Every bot, scanner, and attacker can attempt connections. Even with strong authentication, you're wasting resources and increasing attack surface.

The Correct Approach

Restrict SSH access at the firewall level. If you have a static IP or known IP ranges:

# UFW example
ufw default deny incoming
ufw allow from YOUR_IP_ADDRESS to any port 2849 proto tcp
ufw enable
# firewalld example
firewall-cmd --permanent --remove-service=ssh
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="YOUR_IP_ADDRESS" port port="2849" protocol="tcp" accept'
firewall-cmd --reload

If you need SSH from dynamic IPs, implement fail2ban:

apt install fail2ban

Create /etc/fail2ban/jail.local:

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

Restart fail2ban:

systemctl restart fail2ban

Combine IP whitelisting, fail2ban, and rate limiting for defense in depth.

Mistake 6: Enabling Password Authentication as a Backup

Some admins disable password auth for root but leave it enabled for other users "just in case" they lose access to their keys. This defeats the purpose of key-based authentication.

Why This Is a Problem

Password authentication is vulnerable to brute force attacks, credential stuffing, and password reuse. If any user account has a weak password, your entire server is at risk. The "just in case" scenario almost never happens with proper key backup procedures.

The Correct Approach

Disable password authentication completely:

# In /etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no

Instead of keeping passwords as a backup:

  • Store your private key in multiple secure locations (encrypted backups, password manager)
  • Maintain access to your hosting provider's emergency console (VNC, Serial Console)
  • Document your recovery procedure
  • Use SSH key forwarding when connecting through bastion hosts

If you must maintain password access during a transition period, set a hard deadline to disable it and use strong, unique passwords generated by a password manager.

Mistake 7: Ignoring SSH Configuration File Permissions

SSH is strict about file permissions for good reason. Incorrect permissions on configuration files or key files can cause SSH to silently ignore them or refuse connections, leading to confusion and potential security issues.

Why This Is a Problem

If your authorized_keys file is world-writable, anyone with local access could add their own key. If your private key is readable by others, it's not private. SSH will often refuse to use improperly secured files.

The Correct Approach

Verify and correct permissions on all SSH-related files:

# Server side
chown -R youruser:youruser /home/youruser/.ssh
chmod 700 /home/youruser/.ssh
chmod 600 /home/youruser/.ssh/authorized_keys
chmod 644 /etc/ssh/sshd_config
chmod 600 /etc/ssh/ssh_host_*_key
chmod 644 /etc/ssh/ssh_host_*_key.pub
# Client side
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/id_*.pub
chmod 644 ~/.ssh/config
chmod 644 ~/.ssh/known_hosts

When troubleshooting SSH issues, check permissions first. The error messages SSH provides about permission problems can be cryptic.

Mistake 8: Not Limiting User Access with AllowUsers or AllowGroups

By default, SSH permits all system users to attempt login. On a multi-user system or a server with service accounts, this expands your attack surface unnecessarily.

Why This Is a Problem

Every user account is a potential entry point. Service accounts, legacy users, or accounts created by applications may have weak security. You rarely need more than one or two users to have SSH access.

The Correct Approach

Explicitly whitelist SSH users in sshd_config:

AllowUsers youruser admin

Or use groups for better management:

AllowGroups sshusers

Then add permitted users to that group:

groupadd sshusers
usermod -aG sshusers youruser

This approach ensures that even if an attacker compromises a service account, they cannot use it for SSH access.

Mistake 9: Skipping SSH Audit and Log Monitoring

Many admins harden SSH but never check whether their hardening is effective. Failed login attempts, unusual connection patterns, and successful authentications all generate logs that usually go unexamined.

Why This Is a Problem

Without monitoring, you won't know if you're under attack until after a breach. You can't measure the effectiveness of your hardening efforts or spot configuration drift over time.

The Correct Approach

Regularly review SSH logs:

# Recent SSH activity
journalctl -u sshd -n 100

# Failed login attempts
grep "Failed password" /var/log/auth.log

# Successful logins
grep "Accepted publickey" /var/log/auth.log

Implement centralized logging if you manage multiple servers. Set up alerts for suspicious patterns:

  • Multiple failed attempts from the same IP
  • Successful logins from unexpected geographic locations
  • SSH access outside business hours (for production servers)

Periodically audit your SSH configuration:

sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication|port'

Verify that your actual running configuration matches your intended security policy.

Mistake 10: Using Outdated SSH Protocol Settings

Legacy SSH servers may still accept old protocol versions, weak ciphers, or deprecated key exchange algorithms for backward compatibility. These create unnecessary vulnerabilities.

Why This Is a Problem

Older protocol versions and weak cryptographic algorithms have known vulnerabilities. Supporting them increases attack surface even if you never intentionally use them.

The Correct Approach

Explicitly configure modern, strong cryptographic settings in sshd_config:

# Use only SSH protocol 2
Protocol 2

# Strong ciphers
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr

# Strong MACs
MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256

# Strong key exchange
KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group-exchange-sha256

Before applying these settings, verify that your SSH clients support them. Modern systems handle these without issue, but very old clients may require updates.

Conclusion

SSH hardening is not a checklist you complete once and forget. It's a layered approach combining strong authentication, restrictive access controls, proper monitoring, and regular audits. The mistakes outlined here share a common thread: they trade real security for convenience or rely on single points of failure.

Avoid the false confidence that comes from half-measures like changing the port alone or leaving password auth enabled as a backup. Build defense in depth by combining key-based authentication, firewall restrictions, privilege separation, and active monitoring. Test your changes carefully to avoid lockouts, verify your configuration regularly, and keep your SSH software updated. Your VPS security depends on getting these fundamentals right.

FAQ

What should I do first when hardening SSH?

Disable password authentication and enforce key-based authentication. This single change eliminates the vast majority of automated attacks. Create a non-root user with sudo privileges and disable root login next.

Is changing the SSH port really necessary?

It's not necessary for security, but it dramatically reduces log noise from automated scans and reduces load on fail2ban or similar tools. Treat it as a convenience feature, not a security control.

How do I recover if I lock myself out?

Use your hosting provider's emergency console or VNC access. Most VPS providers offer out-of-band console access that bypasses SSH. This is why you should always test configuration changes with two simultaneous sessions before disconnecting.

Should I disable IPv6 for SSH?

Only if you're not using IPv6 at all and want to reduce attack surface slightly. If you disable IPv6 SSH, ensure your firewall rules account for both protocols and verify that your server isn't exposing SSH on IPv6 unintentionally.

How often should I rotate SSH keys?

Rotate keys when a team member with access leaves, when you suspect a key may have been exposed, or on a regular schedule for high-security environments. For most use cases, annual rotation is reasonable if keys are properly secured with passphrases.