Stop Exposing Your VPS! Step-by-Step Linux Security Hardening Guide, Say Goodbye to SSH Brute Force Attacks

▎ Preface: Why Bother with This?

Let’s start with a test:

Run this command in your Linux console: grep "Failed password" /var/log/auth.log

You should see a wall of Failed password errors.

Note: The command may differ on other distributions. Here, I’m using Debian12 for demonstration, and running this might flood your screen, so proceed with caution!

image

  • Problem Description: Just bought a VPS and your logs are full of Failed password entries? This is because scripts across the internet constantly scan the default port 22. Since your server has a public IP by default, it is always accessible and open to potential malicious attacks. That means your SSH port is continuously targeted by automated login attempts.

Risk Warning: If you’re still using a weak password for SSH, change it immediately—or follow this guide. If someone breaches your server, it could be used for illegal activities like crypto mining or DDoS attacks. Having your server deleted or shut down is just the start—if you’re implicated in illegal activity, the consequences could be severe.

▎ Preparatory Steps

  • Environment: A newly-provisioned VPS (Debian/Ubuntu/CentOS). I’m using Debian12 here—though Debian 13 is out, I’m more accustomed to Debian12 as my main OS.
  • SSH Client: Xshell, XTerminal, FinalShell—any will do. Here’s a XTerminal download link.

Note: Until you’ve confirmed all settings are correct, do NOT close your current SSH connection window! Otherwise, you’ll have to use the provider’s VNC console or even reinstall your OS.

▎ Step 1: Update Software Repositories and Sync Time

  1. Why update repositories? To ensure you’re downloading the latest software; using outdated packages with known vulnerabilities defeats the purpose of hardening. So, first update your sources and upgrade your system:
  • Debian/Ubuntu: apt update && apt upgrade -y

Sometimes, if installing software fails, updating sources first can resolve it.

  1. Sync server time (I prefer Shanghai time for easier log troubleshooting, though it’s optional):
  • Set time zone: Set your server timezone to Shanghai for easier log analysis.
    • Command: timedatectl set-timezone Asia/Shanghai

▎ Step 2: Create a Regular Admin Account (Strongly Recommended to Avoid Root Logins)

The Root user has the highest privileges, making it convenient—but risky. If a weak password is cracked or your key leaked, an attacker will have full control. Avoid running commands as root directly.

  1. Create user: adduser myadmin (name can be customized).
  2. Grant privileges: usermod -aG sudo myadmin.
  • Verify: Log out of root, login as the new user, and test sudo apt update to ensure sudo privileges are active.

The sudo command allows ordinary users to temporarily elevate permissions to root—useful when higher privileges are required.

▎ Step 3: Set Up SSH Key Authentication (Upgrade the Lock on Your Front Door)

  • Generate key pair:
    • Recommended algorithm: Use Ed25519 (safer and more efficient than RSA).
    • Command: ssh-keygen -t ed25519 -C "your_email"
  • Upload public key to server:
    • Method A (recommended): Use ssh-copy-id myadmin@ip_address for automatic deployment.
    • Method B (manual): mkdir -p ~/.ssh && echo "public_key_contents" >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
  • Test connection: Open a new terminal and log in with the private key; only proceed once successful.

As a side note: Few providers enforce mandatory key-based login and disable root password logins by default. The only one I’ve dealt with directly is DMIT, which forces key authentication on initial setup.

Reference: DMIT New VPS Connection Issues? Step-by-step SSH Key Login Setup (Illustrated Guide)

▎ Step 4: Change SSH Port & Configure Firewall

  • Edit config file to open a new port: nano /etc/ssh/sshd_config
    • Strategy: Keep Port 22, add a new line Port 10086 (dual ports in parallel to avoid being locked out due to misconfiguration).

Many providers let you specify a different SSH port at OS reinstall, dodging default port scans. Since SSH defaults to 22, most scans target that; a high-numbered port requires scanning all your ports before SSH is found.

image

  • Configure firewall (UFW/Firewalld):
    • Key point: Always open the new port before enabling the firewall! If not, you risk losing SSH access entirely—bad news!
    • Debian/Ubuntu (UFW):
      ufw allow 10086/tcp  # Open new SSH port
      ufw allow 80/tcp     # Reserve web port
      ufw allow 443/tcp
      ufw enable           # Enable firewall
      
  • Verify: Try connecting through port 10086. Once successful, go back and remove Port 22 from the config, then restart the SSH service.

Ports 80 and 443 are required for web hosting. If you need other ports, simply modify the commands above. This step is for security—to restrict exposed ports. If you find it troublesome, you can skip it (optional).

▎ Step 5: Disable Password & Root Login (Final Seal of Vulnerability)

  • Edit config: nano /etc/ssh/sshd_config
    • PermitRootLogin no: Fully disable root login (since we already have a sudo user, there’s no need to worry).
    • PasswordAuthentication no: Turn off password login entirely—only key authentication will work.
  • Restart service: systemctl restart sshd to apply the new settings.

After this step, only key-based SSH logins are possible. The root account cannot use a password, and password login is disabled. Brute-forcing your private key is virtually impossible unless you leak it yourself.

image

▎ Step 6: Install Fail2Ban (Optional Enhancement)

  • Why: Even after changing the port, someone will still try to scan/login. Fail2Ban can auto-ban IPs after multiple failed logins. Without it, your logs can get huge due to persistent SSH login attempts.
  • Install: apt install fail2ban -y
  • Configure: Copy the config file cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local, then set bantime (ban duration) and maxretry (max allowed failed attempts).

Fail2Ban’s configs live in /etc/fail2ban. jail.conf is the main file; you can define global settings or service-specific rules.

  • Config file overview:
  • bantime: How long (in seconds) an IP is banned after an attack.
  • unbantime: How often to check and unban, in seconds.
  • maxretry: Max failed attempts before a ban triggers.
  • findtime: Time window for maxretry attempts, in seconds.

▎ Last-Resort Rescue

If something goes wrong (forgot to open the port, lost your key, etc.), don’t panic. Here’s a potential solution.

  • VNC Direct Connect:
    • Scenario: Firewall enabled before opening the port? Lost your key?
    • Fix: Log into your provider’s dashboard (nearly all offer this), open the VNC console—it acts like plugging a monitor directly into your server. This bypasses SSH restrictions and lets you modify configs, add a new key, or re-enable password login. Then reboot and retry.

If nothing works, you may have to reinstall the OS from your provider’s panel—inconvenient, but not a big deal for a fresh server.

▎ Conclusion

Breakdown of the steps above should make your VPS worry-free—safe against brute-force and port scans. A properly configured firewall keeps unnecessary ports closed. For example, exposing MySQL’s 3306 or Redis’s 6379 with a weak or no password is extremely risky!

  • System updated & time synced
  • New sudo user created & remote root login disabled
  • SSH key login tested & password login disabled
  • SSH port changed & firewall (UFW) correctly configured
  • Fail2Ban is active

If this guide helped, feel free to follow ChuanJiabaoVPS.

Original article: https://www.legacyvps.com/archives/linux-vps-security-hardening-guide-protect-ssh-from-brute-force

22 Likes

Thank you for sharing

1 Like

Thanks for sharing~ I’ve gotten used to changing the port and disabling password login, using key login instead~ Using an SSH tool to create a one-key login, very convenient.

Of course, for those who frequently tinker, these are usually to protect against themselves :clown_face:

4 Likes

Haha, this is very realistic. It’s still necessary for a website server.

1 Like

thank you for sharing

Ha ha Because when I first started playing, I always went through this whole process, and then found myself disconnected~~ :joy:


Another addition, you can use fail2ban add a login IP whitelist~ To prevent yourself from getting locked out as well

2 Likes

I considered adding a whitelist, but it’s not a mainstream approach. If the jump server or IP changes, it would be useless.

Bookmark, learn, thanks

1 Like

I remember the fail2ban script was quite good.

1 Like

studied

1 Like

This thing is plentiful, but understanding the principles is more important.

Thank the great tutor’s tutorial

1 Like

Thank you for sharing

Thanks for sharing

Is Mac system applicable as well?

very comprehensive approach

study

Thank you for sharing :xhj003:

Thank you for sharing! I’ll learn from it!

Either use professional scripts or practice offline locally, familiarize yourself之后再实战

Either use professional scripts or practice offline locally, familiarize yourself with it before going live