Ransomware works fast once it's in. Most attacks I've seen in support tickets shared a pattern: the infection landed through a predictable entry point that could have been closed weeks earlier. Five server-level configurations block the majority of those vectors before encryption starts.
These aren't exotic firewall appliances or expensive EDR agents. They're baseline Linux and cPanel hardening steps that take an afternoon to implement and survive reboots.
Step 1: Lock down SSH with key authentication and port changes
Password authentication over SSH is the easiest way for automated scanners to brute-force their way in. The fix is mandatory key-based authentication and a non-standard port.
Edit /etc/ssh/sshd_config:
Port 2289
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
Restart SSH:
systemctl restart sshd
Before you disconnect your current session, open a second terminal and test the new port to confirm you can still get in. If you lock yourself out, most providers offer a serial console or rescue mode.
Changing the port doesn't stop a determined attacker, but it removes your server from the automated scanners that hammer port 22 across entire IP ranges. Those bots move on to easier targets.
For key generation on your local machine:
ssh-keygen -t ed25519 -C "[email protected]"
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2289 user@your-server-ip
Ed25519 keys are shorter and faster than RSA. If you must use RSA for compatibility, generate at least 4096 bits.
Step 2: Enforce restrictive file permissions and immutable flags
Ransomware encrypts what it can touch. Restricting write access to system binaries and configuration files limits the blast radius.
Set correct ownership on web directories:
chown -R username:username /home/username/public_html
find /home/username/public_html -type d -exec chmod 755 {} \;
find /home/username/public_html -type f -exec chmod 644 {} \;
For WordPress or other PHP applications, wp-config.php should be 440 or 400:
chmod 400 /home/username/public_html/wp-config.php
chown username:username /home/username/public_html/wp-config.php
Immutable flags prevent modification even by root until you remove the flag:
chattr +i /etc/passwd
chattr +i /etc/shadow
chattr +i /etc/group
chattr +i /etc/gshadow
chattr +i /etc/ssh/sshd_config
To make changes later, remove the flag temporarily:
chattr -i /etc/passwd
# Make your edits
chattr +i /etc/passwd
In cPanel environments, CSF (ConfigServer Security & Firewall) can monitor and alert on permission changes to critical files. Install it from WHM if you haven't already.
Step 3: Configure firewall rules to allow only necessary services
Every open port is a potential entry point. Close everything except what you actually need.
If you're using firewalld (CentOS/AlmaLinux default):
firewall-cmd --permanent --remove-service=cockpit
firewall-cmd --permanent --remove-service=dhcpv6-client
firewall-cmd --permanent --add-port=2289/tcp
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=smtp
firewall-cmd --reload
firewall-cmd --list-all
For iptables on Ubuntu/Debian:
iptables -F
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 2289 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -j DROP
iptables-save > /etc/iptables/rules.v4
If you run cPanel, ports 2082, 2083, 2086, 2087, and 2095/2096 need to stay open for webmail and WHM access. Restrict those to your office IP if possible.
Rate limiting SSH attempts catches brute-force attacks that made it past the port change:
firewall-cmd --permanent --add-rich-rule='rule service name=ssh limit value=3/m accept'
firewall-cmd --reload
That allows three SSH connection attempts per minute from any single IP.
What if your backups are on the same system?
Isolated backups are the difference between a recoverable incident and paying a ransom. If your backup files live on the same filesystem or network share as your live data, ransomware will encrypt both.
Store backups on a separate physical system or in object storage with versioning enabled. In cPanel, configure remote backup destinations in WHM:
WHM → Backup → Backup Configuration → Additional Destinations
Add an SFTP destination on a different server, or use S3-compatible storage. Set retention to keep at least seven daily snapshots and four weekly snapshots.
For manual backups outside cPanel:
rsync -avz --delete /home/username/public_html/ backup-server:/backups/$(date +%Y%m%d)/
Schedule that in cron to run daily at 2 AM:
0 2 * * * /usr/local/bin/backup-script.sh
The backup server should deny inbound SSH from the production server. Only the production server initiates the connection. If ransomware compromises production, it can't pivot to the backup destination.
For cloud object storage, enable versioning and object lock. AWS S3, Backblaze B2, and Wasabi all support this. Even if ransomware overwrites a backup file, you can restore a previous version.
Test your restore process every quarter. A backup you can't restore is worthless.
Step 5: Disable unnecessary services and harden running daemons
Default Linux installs run services you'll never use. Each one expands your attack surface.
List enabled services:
systemctl list-unit-files --type=service --state=enabled
Disable anything you don't recognize or need:
systemctl disable cups
systemctl disable avahi-daemon
systemctl disable bluetooth
systemctl stop cups
systemctl stop avahi-daemon
systemctl stop bluetooth
For web servers, restrict Apache or Nginx to serve only what's necessary. In Apache, disable directory listings and server signatures in /etc/httpd/conf/httpd.conf (or /etc/apache2/apache2.conf):
Options -Indexes
ServerTokens Prod
ServerSignature Off
Restart Apache:
systemctl restart httpd
PHP execution should be disabled in upload directories. In .htaccess inside /public_html/wp-content/uploads/:
<Files *.php>
Deny from all
</Files>
For Nginx, add this inside the uploads location block:
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
MySQL (or MariaDB) should only listen on localhost unless you have a separate database server. Edit /etc/my.cnf or /etc/mysql/my.cnf:
[mysqld]
bind-address = 127.0.0.1
Restart the database:
systemctl restart mariadb
Disable unused PHP functions that ransomware scripts exploit. In /etc/php.ini (or /etc/php/8.x/apache2/php.ini):
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
Some WordPress plugins break with those disabled, so test after restarting Apache or PHP-FPM.
Monitor and respond to anomalies
Hardening blocks entry, but monitoring catches anything that slips through. Install auditd to log file access and command execution:
yum install audit # CentOS/AlmaLinux
apt install auditd # Ubuntu/Debian
systemctl enable auditd
systemctl start auditd
Add audit rules for sensitive directories:
auditctl -w /etc/passwd -p wa -k passwd_changes
auditctl -w /etc/shadow -p wa -k shadow_changes
auditctl -w /home/ -p wa -k home_changes
Make those permanent by adding them to /etc/audit/rules.d/audit.rules, then restart auditd.
Query the audit log:
ausearch -k passwd_changes
For real-time alerting, forward logs to a centralized system like Graylog or the ELK stack. CSF includes Log Daemon (LFD) that emails alerts when it detects login failures, port scans, or file changes.
Start with SSH and backups
If you only have time for two changes today, lock down SSH and isolate your backups. Those two steps close the most common entry vector and ensure you can recover if something else breaks through. The rest can happen over the next week.
Hardening isn't a one-time task. Schedule a quarterly review to re-check permissions, audit open ports, and verify your restore process still works. Ransomware evolves, but these fundamentals stay effective because they remove the opportunities attackers need to gain a foothold.
