Ransomware actors count on weak perimeters and flat networks. If they breach one service account, they want lateral movement to every database, backup share, and admin panel in your infrastructure. The encryption phase is just the finale—the real damage happens during reconnaissance and privilege escalation.
I've restored servers after ransomware hits, and the pattern is always the same: a compromised WordPress plugin, a weak SSH password, or an unpatched service gave the attacker an initial foothold. From there, they pivoted to backup directories and encrypted everything before anyone noticed.
The five steps below assume you run a Linux VPS or dedicated server, but the principles apply to any hosting stack. They won't stop a zero-day exploit against your kernel, but they will block the common attack chains that lead to mass encryption.
1. Lock down SSH and disable password authentication
Password-based SSH is the easiest entry point. Attackers scan port 22 continuously, trying credential lists against root and common usernames.
Generate an ED25519 key pair on your local machine:
ssh-keygen -t ed25519 -C "[email protected]"
Copy the public key to your server:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server-ip
Edit /etc/ssh/sshd_config and enforce key-only authentication:
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
Port 2222
Changing the default port isn't security by obscurity when combined with key auth—it eliminates the constant brute-force noise in your logs and reduces load on fail2ban. Restart the SSH daemon:
systemctl restart sshd
Test the new configuration in a second terminal before closing your existing session. If you lock yourself out, most hosting control panels offer a web-based console or rescue mode.
Also disable unused services. If you're not using FTP, stop vsftpd or proftpd and prevent them from starting at boot:
systemctl stop vsftpd
systemctl disable vsftpd
Every open port is another surface for exploitation.
2. Separate privileges with dedicated service accounts
Running web applications as root or under a single shared user gives ransomware a straight path to every file on the system. Create isolated service accounts with minimal permissions.
For a WordPress site, create a dedicated system user:
useradd -m -s /bin/bash wpuser1
Set ownership of the web root:
chown -R wpuser1:wpuser1 /var/www/site1
chmod -R 750 /var/www/site1
Configure your PHP-FPM pool to run as that user. In /etc/php-fpm.d/site1.conf:
[site1]
user = wpuser1
group = wpuser1
listen = /run/php-fpm/site1.sock
listen.owner = nginx
listen.group = nginx
Restart PHP-FPM:
systemctl restart php-fpm
If ransomware compromises one site through a plugin vulnerability, it can only encrypt files owned by wpuser1. Your other sites, databases, and system directories remain untouched.
The same principle applies to databases. Don't grant ALL PRIVILEGES to application users. A WordPress database user only needs SELECT, INSERT, UPDATE, and DELETE on its own schema—never FILE, SUPER, or access to mysql system tables.
3. Implement immutable backups with separate credentials
Backups are the ransomware operator's primary target. If they encrypt your live data and your backups in the same pass, you have no recovery path.
Store backups off-server, and use write-once or append-only modes wherever possible. Object storage services like Backblaze B2, Wasabi, or AWS S3 support object lock, which prevents deletion or modification for a retention period you define.
Here's a simple daily backup script using rclone to push encrypted archives to B2 with a seven-day lock:
#!/bin/bash
BACKUP_DATE=$(date +%Y%m%d)
tar -czf /tmp/backup-$BACKUP_DATE.tar.gz /var/www /etc
rclone copy /tmp/backup-$BACKUP_DATE.tar.gz b2:my-backup-bucket/ \
--b2-versions --b2-hard-delete=false
rm /tmp/backup-$BACKUP_DATE.tar.gz
Configure the B2 bucket with object lock in the Backblaze console. Even if an attacker gains root access to your server and finds your rclone config, they cannot delete or overwrite locked backups.
Never store backup credentials in the same location as application credentials. Use a dedicated IAM user or application key with write-only permissions. If your server's credentials are compromised, the attacker can upload junk but cannot enumerate, download, or delete existing backups.
Rotate backup encryption keys separately from your server's root password. I've seen support tickets where the customer had backups, but the encryption passphrase was stored in /root/.backup_pass on the encrypted server.
4. Segment your network and firewall database ports
Flat networks let ransomware spread from a web server to your database, mail server, and backup storage without hitting a single firewall rule.
If you manage multiple VPS instances, place your database on a separate instance and restrict access by IP. In ufw or iptables, allow only your application servers:
ufw allow from 203.0.113.10 to any port 3306
ufw deny 3306
For dedicated servers with multiple network interfaces, bind MySQL to the private interface in /etc/my.cnf:
[mysqld]
bind-address = 10.0.1.5
Application servers connect over the private network, and the database port is never exposed to the internet.
Inside a single server, use namespaces or containers if your hosting stack supports them. A compromised web process should not have direct socket access to MySQL or Redis. Run your database in a separate namespace and enforce access through a local proxy or Unix socket with strict permissions.
Also close outbound ports your applications don't need. A WordPress site has no reason to open outbound SMTP connections if you route mail through a dedicated relay. Block port 25 outbound to prevent compromised plugins from sending spam or exfiltrating data:
ufw deny out 25
5. Enable file integrity monitoring and log aggregation
Ransomware doesn't encrypt everything instantly. Operators often wait days or weeks after initial compromise, escalating privileges and disabling backups before triggering the payload. File integrity monitoring catches the reconnaissance phase.
Install and configure aide (Advanced Intrusion Detection Environment):
apt install aide
aideinit
Initialize the database with known-good file states:
cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
Run daily checks via cron and email diffs:
0 2 * * * /usr/bin/aide --check | mail -s "AIDE Report" [email protected]
You'll see alerts when binaries in /usr/bin, configuration files in /etc, or web application directories change unexpectedly. A legitimate update shows up as a single batch of changes; ransomware shows up as thousands of modifications in a short window.
Ship logs off-server in real time so attackers cannot cover their tracks by editing or deleting local logs. Use rsyslog to forward to a dedicated log server or a managed service:
*.* @@log-server.example.com:514
In support tickets I handled, the usual post-mortem blocker was that all logs were stored on the encrypted server. We had no visibility into when the breach started or which account was compromised first.
What if you're already infected?
If you catch ransomware before the encryption payload runs, isolate the server immediately. Power it off or disconnect the network interface to prevent spread to other systems.
Boot into rescue mode from your hosting control panel and mount the filesystem read-only. Copy critical data to clean storage before attempting any remediation. Never trust binaries or scripts on a compromised system—reinstall from a clean image and restore data from your immutable backups.
If encryption has already started, shut down the server to stop further damage. Do not pay the ransom. Most hosting environments let you snapshot block storage even after encryption; preserve that snapshot in case law enforcement or a decryption tool becomes available later.
Restore from your most recent clean backup and rotate every credential: SSH keys, database passwords, API tokens, and TLS certificates. Scan your backup for signs of compromise before restoring—if the attacker had access for weeks, older backups may contain backdoors.
How often should I test backup restores?
Monthly at minimum. Automate a restore to a staging environment and verify that databases start, web applications load, and file permissions are correct. Untested backups are not backups.
Does two-factor authentication on cPanel stop ransomware?
2FA on control panels prevents unauthorized access to hosting management interfaces, but it doesn't stop ransomware that exploits application vulnerabilities or stolen SSH keys. It's a useful layer but not sufficient on its own.
Can ransomware spread through NFS or Samba shares?
Yes. If your server mounts remote filesystems with write access, ransomware can encrypt those shares. Mount NFS exports read-only where possible, or use separate credentials with no delete privileges.
Should I use a web application firewall?
A WAF helps block common exploit attempts against web apps, but it won't stop ransomware that enters through SSH, mail services, or compromised credentials. Combine it with the hardening steps above.
Start with SSH and backups first
If you only implement two controls today, make them SSH key authentication and immutable off-server backups. Those two steps block the most common entry vector and give you a recovery path if everything else fails.
The other three layers—privilege separation, network segmentation, and integrity monitoring—raise the difficulty curve for attackers and buy you detection time before encryption starts. None of these controls are exotic or expensive. They're standard server administration that gets skipped under deadline pressure.
Schedule two hours this week to walk through each step on one server. Once the tooling and runbooks are in place, applying them to additional servers takes minutes.
