SSH Hardening for Linux VPS: 7 Security Rules

Verdict: Essential Security Rules for Production VPS Hosts

Deploying a Linux Virtual Private Server (VPS) with out-of-the-box configurations leaves your host exposed to automated port scans, brute-force SSH attacks, and credential stuffing. Default installations usually allow root password authentication over port 22, enabling attackers to execute persistent dictionary attacks against your server within minutes of provisioning. By enforcing SSH key authentication, disabling password logins, changing default listening ports, and configuring automated IP banning, you can block over 99% of automated server intrusion attempts without compromising administrative accessibility.

Security ParameterDefault StateHardened StatePrimary Risk Mitigated
Authentication ModePassword AllowedEd25519 SSH Key OnlyBrute-force credential guessing
Root AccessDirect Login AllowedDisabled (PermitRootLogin no)Privilege escalation & host compromise
SSH Listening PortPort 22Custom High Port (e.g. 2222)Automated internet-wide bot scans
Intrusion BanningDisabledFail2ban EnabledDistributed credential stuffing attacks

Why Default SSH Configurations Are Dangerous

When you spin up a fresh cloud instance on providers like DigitalOcean, Linode, or AWS, the default OpenSSH daemon is configured for maximum backwards compatibility rather than security. Password authentication remains enabled to allow easy initial setup, and the SSH service listens on standard TCP port 22. Automated botnets continuously sweep public IPv4 address ranges scanning port 22. When an open SSH port is identified, these bots launch high-frequency dictionary attacks trying thousands of default username and password combinations every hour. In addition, permitting direct root logins means an attacker who successfully guesses or steals the password immediately gains complete system ownership without needing to bypass secondary privilege barriers.

Rule 1: Switch to Ed25519 SSH Key Authentication

Traditional password authentication relies on human memory, leading to weak or reused credentials that succumb to brute-force tools like Hydra. SSH key pairs use asymmetric cryptography, rendering password-guessing attacks mathematically impossible. While RSA 4096-bit keys have long been the industry standard, Ed25519 keys offer superior security, smaller key sizes, and faster signature verification based on the Edwards-curve Digital Signature Algorithm (EdDSA).

Generate a secure Ed25519 key pair on your local machine using the following command:

ssh-keygen -t ed25519 -C "admin@grafisify.com"

Copy the public key to your remote Linux VPS using ssh-copy-id:

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your_vps_ip

Once you verify that you can authenticate using your key pair without entering a password, you can safely proceed to disable password logins entirely inside your server configuration.

Rule 2: Disable Root Login and Enforce Non-Root Sudo Users

Logging into your server directly as the root superuser is an unnecessary risk. Every command executed as root has unrestricted system access, making accidental misconfigurations destructive and giving compromise vectors instant host privileges. Hardening best practices dictate creating a dedicated administrative user with sudo privileges and locking direct root access via SSH.

Create a new administrative user and grant sudo permissions on Ubuntu or Debian hosts:

adduser adminuser
usermod -aG sudo adminuser

Open the OpenSSH configuration file located at /etc/ssh/sshd_config using your preferred text editor and locate the PermitRootLogin directive. Update it to disable root logins explicitly:

PermitRootLogin no

This setting ensures that even if an attacker acquires root credentials, OpenSSH rejects any direct authentication request for the root account over the network.

Rule 3: Disable Password Authentication Completely

Generating an SSH key pair is effective only if you prohibit password-based logins server-wide. As long as PasswordAuthentication remains enabled in your SSH config, attackers can still target your system by bypassing key checks and attempting password logins.

In /etc/ssh/sshd_config, modify or add the following directives to enforce key-only authentication:

PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no

Before restarting the SSH daemon, double-check that your public key is properly installed in ~/.ssh/authorized_keys for your non-root user. Closing your current session without testing key access can lock you out of your host permanently.

Linux VPS server room network hardware SSH security
Enforcing key authentication and non-root access stops automated SSH brute-force bots on cloud VPS hosts. (Source: Unsplash)

Rule 4: Change Default SSH Port 22 to a Non-Standard Port

While changing the default port is often categorized as security through obscurity, moving SSH off TCP port 22 yields massive practical benefits. Automated mass-scanning bots scan port 22 exclusively to save bandwidth and compute time across millions of IPv4 addresses. Relocating your SSH service to a custom port between 1024 and 65535 immediately filters out over 95% of automated log noise and auth failure spam.

Select an unused high port (such as 2222 or 49152) and update the Port line in /etc/ssh/sshd_config:

Port 2222

If you are running an active firewall like UFW, remember to allow the new port before restarting the OpenSSH service, or your firewall will drop your connection immediately:

sudo ufw allow 2222/tcp
sudo ufw reload
sudo systemctl restart ssh

Rule 5: Implement Fail2ban Automated IP Banning

Even on a custom port, sophisticated scanners may eventually discover your active SSH service. Fail2ban acts as an automated intrusion prevention framework that monitors authentication log files (such as /var/log/auth.log) for repeated failure patterns. When an IP address accumulates a specified number of failed login attempts within a set timeframe, Fail2ban dynamically updates firewall rules to drop packets from that host for a configurable duration.

Install Fail2ban on Ubuntu/Debian hosts using apt:

sudo apt update && sudo apt install fail2ban -y

Create a local jail configuration file at /etc/fail2ban/jail.local to override default rules safely:

[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600

This configuration monitors custom port 2222, allowing a maximum of 3 failed attempts within 10 minutes before banning the offending IP address for one hour (3600 seconds).

Rule 6: Restrict SSH Access with Firewall Rules (UFW / IP Whitelisting)

For high-security production servers, opening your SSH port to the entire internet is unnecessary if administrative access only originates from static IP addresses or an internal VPN. Configuring strict firewall rules limits network exposure exclusively to trusted sources.

If you have a static IP address, restrict SSH access using Uncomplicated Firewall (UFW):

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 203.0.113.45 to any port 2222 proto tcp
sudo ufw enable

This policy drops all inbound packets targeting your SSH port unless they originate from your verified administrative IP (203.0.113.45), making the port completely invisible to external scanners.

Rule 7: Set Idle Timeout and Limit Max Authentication Attempts

Unattended SSH sessions left open on workstation screens invite physical security risks, while unbounded login attempts per connection allow multi-threaded password spraying attacks. Hardening OpenSSH session parameters mitigates both threat vectors.

Add the following directives to /etc/ssh/sshd_config:

ClientAliveInterval 300
ClientAliveCountMax 2
MaxAuthTries 3
MaxSessions 2

ClientAliveInterval 300 sends a keepalive probe every 5 minutes (300 seconds). If the client fails to respond twice (ClientAliveCountMax 2), the server automatically terminates the idle connection after 10 minutes of inactivity. Setting MaxAuthTries 3 limits individual connection attempts to 3 before closing the socket.

Cybersecurity matrix code digital protection server security
Automated firewall rules and session timeouts protect cloud servers against persistent unauthorized access. (Source: Unsplash)

Frequently Asked Questions

Can changing the SSH port break automated deployment scripts or Ansible?

Changing the SSH port will affect deployment pipelines, CI/CD runners, and Ansible playbooks if they assume port 22 by default. However, you can update target port configurations easily in your ~/.ssh/config file or inventory files by specifying Port 2222 or setting ansible_port: 2222.

What should I do if I am locked out of my VPS after enabling key authentication?

If you lose access due to a misconfigured firewall or key error, log into your cloud provider’s web console (such as DigitalOcean Console, Linode LISH, or AWS VNC). Web consoles bypass network-level SSH rules and provide direct virtual terminal access so you can repair /etc/ssh/sshd_config or restore administrative key files.

Is Ed25519 supported on older legacy servers?

Ed25519 has been natively supported in OpenSSH since version 6.5 (released in 2014). Virtually all modern Linux distributions support Ed25519 out of the box. If you must support legacy distributions running ancient OpenSSH builds, RSA 4096-bit keys serve as a secondary fallback.

Conclusion

Hardening SSH access is the single most critical baseline step when deploying a production Linux VPS. By moving to Ed25519 key authentication, disabling root and password logins, shifting to a custom port, and deploying Fail2ban, you replace default vulnerabilities with layered defensive barriers. Regularly update your host packages with sudo apt update && sudo apt upgrade to ensure OpenSSH and system libraries remain patched against emerging vulnerabilities.

Irfan is a Creative Tech Strategist and the founder of Grafisify. He spends his days testing the latest AI design tools and breaking down complex tech into actionable guides for creators. When he’s not writing, he’s experimenting with generative art or optimizing digital workflows.

Leave a Reply

Your email address will not be published. Required fields are marked *

You might also like
How to Self-Host a Password Manager with Vaultwarden

How to Self-Host a Password Manager with Vaultwarden

How to Back Up a VPS with Restic and Backblaze B2

How to Back Up a VPS with Restic and Backblaze B2

How to Set Up WireGuard VPN on a Linux VPS

How to Set Up WireGuard VPN on a Linux VPS

How to Set Up Uptime Kuma on a VPS

How to Set Up Uptime Kuma on a VPS

Linux VPS Security Rules: 7 Steps to Harden SSH Access

Linux VPS Security Rules: 7 Steps to Harden SSH Access

Docker Container Hardening: 7 Production Security Rules

Docker Container Hardening: 7 Production Security Rules