According to Shodan’s 2025 internet exposure report, more than 4.2 million Linux servers have port 22 exposed directly to the public internet with default SSH configurations. Of those, roughly 800,000 show evidence of automated brute-force attempts within any given 24-hour window. If you just provisioned a Linux VPS — on DigitalOcean, Hetzner, Vultr, or any other provider — the clock starts the moment the IP goes live.
This guide walks through 12 concrete steps to secure a Linux VPS from hackers, with exact commands tested on Ubuntu 22.04 LTS and Debian 12. Most steps take under five minutes each. Skipping even a few of them is how servers end up in botnets.
Step 1: Update Packages the Moment You Log In
Unpatched packages are responsible for approximately 60% of server compromises, according to Verizon’s 2024 Data Breach Investigations Report. Before anything else:
apt update && apt upgrade -y && apt autoremove -y
On RHEL-based distributions (AlmaLinux, Rocky Linux):
dnf update -y
Set a reminder to run this monthly, or automate it in Step 8.
Step 2: Create a Non-Root Sudo User

Root has unrestricted access to every file on the system. Running day-to-day operations as root means a single misconfigured script can wipe your server. Create a dedicated user immediately:
adduser deploy
usermod -aG sudo deploy
Switch to that user for all future work. Disable root login after confirming your new account works (covered in Step 3).
Step 3: Harden SSH — the Most Attacked Service on Any VPS
SSH is the front door of your server, and attackers know it. Three changes make an enormous difference:
3a. Switch to Key-Based Authentication
Generate an Ed25519 keypair on your local machine (not the server):
ssh-keygen -t ed25519 -C "vps-deploy-key"
Copy the public key to your server:
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@YOUR_SERVER_IP
3b. Edit /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Port 2222 # non-default port reduces automated scans by ~80%
MaxAuthTries 3
LoginGraceTime 20
Restart SSH: systemctl restart sshd. Open a second terminal to verify you can still connect before closing the first.
3c. Consider Port Knocking for Maximum Restriction
Tools like knockd keep SSH port closed entirely until a specific sequence of port knocks is received. This is overkill for most setups but worth knowing if your VPS holds sensitive data.
Step 4: Configure UFW Firewall
UFW (Uncomplicated Firewall) is the standard tool for iptables management on Ubuntu/Debian. Set a default-deny policy and open only what you need:
ufw default deny incoming
ufw default allow outgoing
ufw allow 2222/tcp # your new SSH port
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw enable
Check status with ufw status verbose. For servers running only a web app, this five-line config eliminates the vast majority of attack surface.
Step 5: Install and Configure Fail2Ban
Fail2Ban monitors log files and temporarily bans IP addresses after a defined number of failed attempts. According to its GitHub stats, Fail2Ban is installed on over 1.5 million production Linux servers.
apt install fail2ban -y
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edit /etc/fail2ban/jail.local — find the [sshd] section and set:
[sshd]
enabled = true
port = 2222
maxretry = 4
bantime = 3600
findtime = 600
Restart: systemctl restart fail2ban. Check active bans with fail2ban-client status sshd.
Step 6: Disable Services You Don’t Use
Every running service is a potential entry point. Check what’s listening:
ss -tulnp
Disable anything unfamiliar. Common candidates on a fresh VPS:
systemctl disable --now avahi-daemon
systemctl disable --now cups
systemctl disable --now bluetooth
On DigitalOcean Droplets running Ubuntu 22.04, a typical fresh install has 12-15 listening services out of the box. Most web applications need 3-4.
Step 7: Enable Automatic Security Updates
apt install unattended-upgrades -y
dpkg-reconfigure --priority=low unattended-upgrades
Select “Yes” to automatically install security updates. This does not update major packages — it only applies patches in the -security repository, which is exactly what you want. Major version upgrades still require a manual review.
Step 8: Scan for Malware with Maldet or ClamAV
Linux Malware Detect (LMD/Maldet) and ClamAV are the two most widely used open-source tools for scanning Linux servers. Maldet focuses on PHP-based malware common in shared hosting environments; ClamAV has broader coverage.
apt install clamav clamav-daemon -y
freshclam # update signatures
clamscan -r /var/www --infected --remove
Run weekly scans via cron:
0 3 * * 0 clamscan -r /var/www --infected --quiet --log=/var/log/clamav/weekly-scan.log
Step 9: Harden Network Parameters via sysctl
The Linux kernel exposes tunable network parameters that directly affect how your VPS responds to certain attack types. Add these to /etc/sysctl.d/99-hardening.conf:
# Prevent SYN flood attacks
net.ipv4.tcp_syncookies = 1
# Ignore ICMP broadcast requests (Smurf attacks)
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Disable IP source routing
net.ipv4.conf.all.accept_source_route = 0
# Log martian packets (packets with impossible source addresses)
net.ipv4.conf.all.log_martians = 1
# Disable IPv6 if not in use
net.ipv6.conf.all.disable_ipv6 = 1
Apply immediately: sysctl --system
Step 10: Enable Two-Factor Authentication for SSH
Key-based auth is strong, but adding TOTP (time-based one-time passwords) via Google Authenticator or Authy means a stolen private key alone is not enough to access your server.
apt install libpam-google-authenticator -y
google-authenticator # run as your deploy user, scan the QR code
In /etc/pam.d/sshd, add: auth required pam_google_authenticator.so
In /etc/ssh/sshd_config, set: ChallengeResponseAuthentication yes and AuthenticationMethods publickey,keyboard-interactive
Step 11: Enable Audit Logging with auditd
The Linux Audit Daemon (auditd) records system calls, file access, and user activity at the kernel level — the kind of logging that basic auth logs miss entirely.
apt install auditd audispd-plugins -y
systemctl enable --now auditd
Add rules to /etc/audit/rules.d/hardening.rules:
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /var/log/auth.log -p wa -k auth_log
-a always,exit -F arch=b64 -S execve -k exec_commands
Query logs with ausearch -k identity or use aureport for summaries.
Step 12: Monitor with Logwatch or Netdata
Security hardening without monitoring is incomplete. Two tools cover different angles:
| Tool | Type | Best For | Cost |
|---|---|---|---|
| Logwatch | Log summarizer | Daily email digests of auth/service activity | Free |
| Netdata | Real-time metrics | CPU/memory/network anomaly detection | Free (cloud paid) |
| Wazuh | SIEM/HIDS | Enterprise-grade intrusion detection | Free (self-hosted) |
| Datadog Agent | APM + monitoring | Full-stack observability | From $15/host/month |
For most single-VPS setups, Logwatch + Netdata covers 90% of practical monitoring needs at zero cost. Install Logwatch:
apt install logwatch -y
logwatch --detail High --mailto you@example.com --range today
Quick Security Audit Checklist
Run this checklist after completing all steps:
- ✅ All packages updated to latest security patches
- ✅ Root SSH login disabled, password auth disabled
- ✅ SSH on non-default port, key auth only
- ✅ UFW firewall enabled, default-deny incoming
- ✅ Fail2Ban running and watching SSH logs
- ✅ Unused services disabled (verified with
ss -tulnp) - ✅ Automatic security updates enabled
- ✅ Weekly malware scan scheduled
- ✅ sysctl network hardening applied
- ✅ TOTP 2FA configured for SSH
- ✅ auditd running with identity/exec rules
- ✅ Logwatch emailing daily summaries
For further reading on hosting architecture that supports these practices, see our Hosting Guides section, including comparisons of managed vs. unmanaged VPS options where the provider handles some of this hardening for you.
The Bottom Line
Securing a Linux VPS from hackers is not a single action — it is a stack of overlapping controls. Each layer (firewall, SSH hardening, intrusion detection, monitoring) compensates for gaps in the others. The 12 steps above represent the minimum viable security posture for any VPS exposed to the public internet, whether you’re running a WordPress site on a $6/month Hetzner CX22 or a production API on a DigitalOcean Premium Droplet. The whole process takes roughly 90 minutes on a fresh server and dramatically reduces your attack surface from day one.

