Ransomware attacks encrypt your data and demand payment to unlock it. For servers, the stakes are higher—downtime means lost revenue, angry customers, and scrambling to rebuild. A single security control won't save you. You need layers.
This guide walks through five practical security layers that form defense-in-depth for servers. Each layer catches what the previous one missed. I'll define every term and show you the first working setup.
What defense-in-depth means
Defense-in-depth is security jargon for "multiple independent barriers." If an attacker breaks through one layer, they hit another. Think castle walls, moat, gates, guards—except we're protecting SSH access and file systems.
The five layers we'll build:
- Immutable backups (your last line of defense)
- Access control and authentication hardening
- Patch management and vulnerability reduction
- Real-time monitoring and intrusion detection
- Network segmentation and firewall rules
Start with backups. Always.
Layer 1: Immutable backups you can actually restore
Ransomware that encrypts your primary data often tries to delete backups too. Your backup strategy must survive an attacker with root access to your server.
What immutable means
Immutable backups cannot be altered or deleted for a set retention period—even by someone with admin credentials. Once written, they're locked. Cloud storage providers offer immutability features; some backup tools support append-only modes.
The 3-2-1 rule
Keep three copies of your data: the production copy, a local backup, and an offsite backup. Store them on two different media types (disk and tape, or disk and cloud). Keep one copy offsite. This protects against hardware failure, fire, and ransomware.
Your first backup setup
For a Linux server, use restic with an S3-compatible backend. Restic supports append-only mode.
Install restic:
wget https://github.com/restic/restic/releases/download/v0.16.0/restic_0.16.0_linux_amd64.bz2
bunzip2 restic_0.16.0_linux_amd64.bz2
sudo mv restic_0.16.0_linux_amd64 /usr/local/bin/restic
sudo chmod +x /usr/local/bin/restic
Initialize a repository with a strong password:
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/your-backup-bucket"
export RESTIC_PASSWORD="your-strong-password"
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
restic init
Take your first backup:
restic backup /var/www /etc /home --exclude=/var/www/cache
Set append-only mode on the S3 bucket using bucket policies or object lock. This prevents delete operations. Check your cloud provider's documentation—AWS calls it Object Lock, Backblaze calls it Object Lock, Wasabi has immutability settings.
Automate backups with cron:
sudo crontab -e
# Add this line for daily 2 AM backups
0 2 * * * /usr/local/bin/restic backup /var/www /etc /home --exclude=/var/www/cache
Test your restores
Backups you never test are backups that don't work. Restore a file once a month:
restic snapshots
restic restore latest --target /tmp/restore-test --include /etc/hostname
cat /tmp/restore-test/etc/hostname
If that file matches production, your backup works.
Layer 2: Lock down access and authentication
Most ransomware enters through stolen credentials or brute-forced passwords. Harden how users and services authenticate.
Disable password authentication for SSH
Passwords are guessable. SSH keys are not.
Generate an SSH key pair on your local machine (not the server):
ssh-keygen -t ed25519 -C "[email protected]"
Copy the public key to your server:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server-ip
Test that key-based login works, then disable password auth. Edit /etc/ssh/sshd_config:
PasswordAuthentication no
ChallengeResponseAuthentication no
PermitRootLogin no
Restart SSH:
sudo systemctl restart sshd
Root login is disabled because even with keys, you want users to SSH as themselves and sudo when needed. This creates an audit trail.
Require multi-factor authentication
SSH keys are strong, but if an attacker steals your private key, they're in. Add a second factor.
Install Google Authenticator PAM module:
sudo apt install libpam-google-authenticator # Debian/Ubuntu
sudo yum install google-authenticator # RHEL/CentOS
Run the setup as your user:
google-authenticator
Answer yes to time-based tokens, update your .google_authenticator file, disallow token reuse, and set rate limiting.
Edit /etc/pam.d/sshd and add this line at the top:
auth required pam_google_authenticator.so
Edit /etc/ssh/sshd_config:
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Restart SSH. Now you need your private key and the six-digit code from your phone.
Limit user privileges
Don't run applications as root. Create service accounts with minimal permissions. If you're running a web app, it should run as www-data or a dedicated user, not root. If ransomware compromises that process, it can only encrypt files that user can write.
Check file ownership:
ls -la /var/www/html
If everything is owned by root, fix it:
sudo chown -R www-data:www-data /var/www/html
Layer 3: Patch everything and reduce attack surface
Unpatched software is how attackers get in. Vulnerabilities in the kernel, web server, PHP, database, or any installed package become entry points.
Enable automatic security updates
For Debian and Ubuntu, install unattended-upgrades:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
This applies security patches automatically. You still need to monitor and reboot when kernel updates land.
For RHEL and CentOS, use yum-cron:
sudo yum install yum-cron
sudo systemctl enable yum-cron
sudo systemctl start yum-cron
Edit /etc/yum/yum-cron.conf and set apply_updates = yes.
Remove unused services
Every running service is a potential target. List what's listening:
sudo ss -tuln
You'll see ports and the processes bound to them. If you see MySQL on 3306 but your app connects via localhost only, bind MySQL to 127.0.0.1. Edit /etc/mysql/my.cnf:
[mysqld]
bind-address = 127.0.0.1
Restart MySQL:
sudo systemctl restart mysql
Remove packages you don't use:
sudo apt autoremove
Keep web applications updated
If you run WordPress, outdated plugins are a common entry point. Update core, plugins, and themes weekly. Better yet, set up automatic updates for minor releases and security patches.
For custom applications, subscribe to security advisories for every framework and library you use.
Layer 4: Monitor logs and detect intrusions early
You won't catch every attack before it happens, but you can detect suspicious behavior and respond before ransomware spreads.
What to monitor
Watch for:
- Failed SSH login attempts (brute-force indicators)
- Privilege escalation attempts (
sudofailures, SELinux denials) - Unusual file modifications in system directories
- High disk I/O (encryption is CPU and disk intensive)
- Network connections to known malicious IPs
Install Fail2Ban
Fail2Ban watches log files and bans IPs after repeated failed login attempts.
sudo apt install fail2ban
Create a local config:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edit /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
Restart Fail2Ban:
sudo systemctl restart fail2ban
Check banned IPs:
sudo fail2ban-client status sshd
Use file integrity monitoring
AIDE (Advanced Intrusion Detection Environment) creates a database of file checksums and alerts when files change unexpectedly.
Install AIDE:
sudo apt install aide
Initialize the database (this takes time):
sudo aideinit
Run a check:
sudo aide --check
Schedule daily checks:
sudo crontab -e
# Add this line
0 3 * * * /usr/bin/aide --check | mail -s "AIDE Report" [email protected]
If critical system files change and you didn't change them, investigate immediately.
Centralize logs
If you manage multiple servers, send logs to a central location. An attacker who gets root can tamper with local logs. Use syslog forwarding or a tool like Graylog or the ELK stack.
For a simple setup, forward to a dedicated log server:
Edit /etc/rsyslog.conf on the target server:
*.* @@log-server-ip:514
Restart rsyslog:
sudo systemctl restart rsyslog
On the log server, configure rsyslog to receive remote logs.
Layer 5: Segment your network and filter traffic
Network segmentation limits how far an attacker can move laterally. If ransomware compromises one server, it shouldn't be able to reach every other system on your network.
What network segmentation means
Segmentation divides your network into zones. Put public-facing web servers in one zone, databases in another, and internal admin systems in a third. Control traffic between zones with firewall rules.
If you run servers in a data center or cloud, use VLANs or VPCs to create isolated subnets. If you're on a VPS with one network interface, you can still use local firewall rules to limit exposure.
Set up a host firewall with UFW
UFW (Uncomplicated Firewall) is a front-end for iptables. It's simple and effective.
Install UFW:
sudo apt install ufw
Default policy: deny incoming, allow outgoing:
sudo ufw default deny incoming
sudo ufw default allow outgoing
Allow SSH (change port if you run SSH on a non-standard port):
sudo ufw allow 22/tcp
Allow HTTP and HTTPS:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Enable UFW:
sudo ufw enable
Check status:
sudo ufw status verbose
If you have multiple servers, restrict database access to the web server's IP only:
sudo ufw allow from web-server-ip to any port 3306
Block outbound traffic to suspicious destinations
Ransomware often calls home to a command-and-control server. Block traffic to known malicious IPs using threat intelligence feeds. Tools like Suricata or Snort can do this, but for a simple setup, you can subscribe to IP blocklists and load them into iptables.
How the layers work together
Here's what happens when an attacker tries to breach a server with all five layers in place:
- They scan for open ports. Your firewall blocks everything except SSH, HTTP, and HTTPS.
- They try to brute-force SSH. Fail2Ban bans their IP after three attempts.
- They compromise a web application through an unpatched plugin. The app runs as
www-data, so they can't access system files. - They try to escalate privileges. AIDE detects modified binaries and alerts you.
- They encrypt files in
/var/www. You restore from last night's immutable backup and revoke the compromised credentials.
No single layer stopped the attack, but together they limited the damage and gave you time to respond.
Your first 24 hours
Prioritize the layers in this order:
- Day one: Set up immutable backups and test a restore. This is your insurance policy.
- Day one: Disable SSH password auth and enable key-based login. Most attacks come through SSH.
- Day two: Enable automatic security updates. Unpatched software is the easiest way in.
- Day three: Install Fail2Ban and AIDE. Monitoring catches what prevention misses.
- Week one: Configure UFW and review what ports are open. Lock down everything you don't need.
Don't try to implement everything at once. Start with backups and access control. Add the other layers over a few days.
Start with backups and build from there
Ransomware protection isn't a single product or setting—it's five overlapping layers that catch what the others miss. Immutable backups are your safety net. Access controls and patching reduce the attack surface. Monitoring detects intrusions early. Network segmentation limits lateral movement.
Implement one layer at a time. Test each control. Check your backups monthly. The goal is working defense-in-depth, not perfection on day one.
