Ransomware doesn't need a sophisticated zero-day. It walks through doors you left open.
Most successful ransomware attacks I've handled in support tickets shared one trait: easily preventable misconfigurations. An exposed SSH port, no rate-limiting, backups mounted read-write at all times. When you harden a server properly, you force attackers to expend real effort, and most move on to easier targets.
Here are nine configuration changes that stop ransomware before encryption starts.
1. Lock down SSH access immediately
SSH is the front door. Port 22 receives thousands of login attempts daily on any public server.
Disable root login first. Edit /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Restart SSH after changes:
systemctl restart sshd
Move SSH to a non-standard port if you don't need port 22 for compatibility reasons. Change the Port directive to something above 1024. This eliminates automated scans targeting port 22 specifically.
Use key-based authentication only. Generate an Ed25519 key pair on your workstation, copy the public key to ~/.ssh/authorized_keys on the server, then disable password login entirely. Every password is a brute-force target.
Set up Fail2Ban to block repeat offenders automatically. The default SSH jail configuration works well:
apt install fail2ban # Debian/Ubuntu
yum install fail2ban # CentOS/RHEL
systemctl enable --now fail2ban
Fail2Ban watches auth logs and temporarily blocks IPs after a few failed attempts. It's not foolproof, but it stops basic dictionary attacks cold.
2. Implement proper firewall rules
A firewall should deny everything by default and allow only what you need.
On most Linux distributions, use iptables or the newer nft (nftables). For simplicity, UFW (Uncomplicated Firewall) wraps iptables with readable commands:
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp # or your custom SSH port
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
Review open ports regularly:
ss -tulpn
Every listening service is a potential entry point. If you see MySQL on 0.0.0.0:3306, bind it to localhost in /etc/mysql/my.cnf instead:
[mysqld]
bind-address = 127.0.0.1
The same applies to Redis, PostgreSQL, and other databases. They don't need public exposure unless you're running a managed service.
For multi-server setups, whitelist specific IPs instead of opening ports to the world. Use security groups or firewall rules to allow database connections only from your application servers.
3. Separate backup systems from live mounts
Backups mounted read-write at all times are the first thing ransomware encrypts.
I've seen this pattern repeatedly: an attacker gains file access, encrypts /home, /var/www, and then follows mounted backup drives. The backups were technically "offline" but sitting there as /mnt/backup1 with full write permissions.
Store backups on a separate system with network access restricted to backup windows only. Use the 3-2-1 rule: three copies, two different media types, one offsite.
For practical implementation, push backups to remote storage rather than pulling from the production server. The production server should not have credentials to delete or modify remote backups.
If you must mount backup storage, do it read-only:
mount -o ro /dev/sdb1 /mnt/backup
Better yet, mount on-demand during backup runs only, then unmount:
#!/bin/bash
mount /dev/sdb1 /mnt/backup
rsync -a /var/www/ /mnt/backup/www/
umount /mnt/backup
Schedule this via cron, and the backup drive stays unmounted outside backup windows.
4. Enable immutable backups where possible
Immutability means backups cannot be altered or deleted, even by an attacker with root access to the production server.
Cloud storage providers offer object lock features that enforce retention policies. AWS S3 Object Lock, Backblaze B2 with Object Lock, and Wasabi Immutability all prevent deletion before a specified date.
On-premises, consider append-only storage or WORM (write-once, read-many) drives. For budget setups, a separate backup server with aggressive access controls works if the production server cannot authenticate to it.
Test restoration regularly. Untested backups are just wishful thinking. Schedule a monthly restore drill to a test environment and verify file integrity.
5. Restrict user permissions and disable unnecessary accounts
Ransomware often runs under a compromised user account, inheriting that user's file permissions.
Audit active user accounts:
cat /etc/passwd | grep -v nologin | grep -v false
Disable or remove accounts you don't recognize. For service accounts, set the shell to /usr/sbin/nologin or /bin/false.
Use file permissions correctly. Web files should be owned by a dedicated user (not root), and writable only where necessary:
chown -R www-data:www-data /var/www/html
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;
For WordPress and similar CMSs, make configuration files read-only after initial setup:
chmod 440 /var/www/html/wp-config.php
chown root:www-data /var/www/html/wp-config.php
Implement least privilege everywhere. A compromised Apache process running as www-data should not be able to modify application code.
6. Monitor file integrity and catch changes early
Ransomware leaves traces before full encryption. Hundreds or thousands of files modified in minutes is an obvious signal.
File integrity monitoring tools like AIDE (Advanced Intrusion Detection Environment) or Tripwire establish a baseline of your filesystem and alert on unexpected changes.
Install AIDE:
apt install aide
aideinit
This creates a database of file hashes in /var/lib/aide/aide.db. Run checks daily:
aide --check
Alert on changes to critical directories like /etc, /usr/bin, and application directories. Not every change is malicious, but you should know when it happens.
For real-time monitoring, use auditd to log file access and modifications. Configure rules for sensitive paths:
auditctl -w /etc/passwd -p wa -k passwd_changes
auditctl -w /var/www -p wa -k web_files
Review audit logs regularly or forward them to a centralized logging system.
7. Keep software patched and remove abandoned packages
Unpatched software is an open invitation. Ransomware doesn't need a backdoor when it can use a known CVE.
Enable automatic security updates on Debian and Ubuntu:
apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades
For CentOS and RHEL, enable yum-cron with security updates only:
yum install yum-cron
systemctl enable --now yum-cron
Edit /etc/yum/yum-cron.conf and set update_cmd = security.
Remove packages you don't use. Every installed package is a potential vulnerability:
apt autoremove
yum autoremove
Audit installed packages quarterly and remove anything orphaned or unnecessary.
8. Disable unnecessary services and daemons
Every running service is a potential attack vector.
List active services:
systemctl list-units --type=service --state=running
Disable services you don't need. Common culprits include cups (printing), avahi-daemon (network discovery), and various RPC services.
systemctl stop cups
systemctl disable cups
On a typical web server, you need your web server (Apache/Nginx), database, and SSH. Everything else is optional.
So what if you're not sure whether a service is needed? Check its documentation or stop it temporarily and see if anything breaks. Monitor logs for a few days before disabling permanently.
9. Implement rate-limiting and intrusion prevention
Rate-limiting slows down automated attacks and brute-force attempts.
For web servers, use Nginx's limit_req or Apache's mod_evasive. In Nginx:
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
location / {
limit_req zone=one burst=20;
}
}
This allows 10 requests per second per IP, with a burst allowance of 20.
For system-level protection, install an intrusion prevention system like Snort or Suricata. These analyze network traffic for malicious patterns and can block attacks in real time.
Configure email alerts for critical events. You want to know within minutes if someone is hammering your server or if a service suddenly starts behaving abnormally.
How often should you review these settings?
Hardening isn't a one-time task. Schedule quarterly reviews:
- Audit user accounts and SSH keys
- Review firewall rules and open ports
- Test backup restoration
- Check for software updates
- Rotate credentials and API keys
Between reviews, monitor logs actively. Set up centralized logging with tools like rsyslog or journald forwarding. Failed SSH attempts, file modifications, and service crashes all tell a story.
What about application-level security?
Server hardening stops perimeter attacks, but applications need their own protection. Keep your CMS and plugins updated, use strong database passwords, and disable file execution in upload directories.
For WordPress, add this to .htaccess in the uploads directory:
<FilesMatch "\.(php|phtml|php3|php4|php5|pl|py|jsp|asp|sh|cgi)$">
Require all denied
</FilesMatch>
For Nginx, deny execution in the uploads location block:
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
Can cloud hosting protect against ransomware?
Cloud providers handle infrastructure security, but they don't manage your configurations. An exposed database or weak SSH password is your responsibility regardless of where the server runs.
Cloud snapshots and backups are useful, but verify they're immutable and stored separately from the main account. An attacker with full account access can delete snapshots too.
What if ransomware still gets through?
No defense is perfect. Have an incident response plan:
- Isolate the infected server from the network immediately
- Identify the infection vector from logs
- Restore from the most recent clean backup
- Patch the vulnerability before bringing the server back online
- Reset all passwords and API keys
Document the incident. Understanding how attackers got in prevents repeat infections.
Start with SSH and backups
You don't need to implement all nine steps today. Start with the two that matter most: secure SSH access and separate, immutable backups.
Disable password authentication, enable key-based login, and verify your backups are actually restorable. Those two changes alone stop the majority of ransomware attacks I've seen in production environments.
Work through the remaining steps over the next few weeks. Hardening is a process, not a destination. Each layer you add makes the attacker's job harder, and eventually they'll find an easier target.
