Skip to content
Back to Blog
Security11 min read

Prevent Data Breach: 10 Controls [Solved for 2026]

Layer encryption, access controls, logging, and incident response into your server stack to stop breaches before they happen.

Written by Abdul AbrorTechnical Hosting Support Engineer
Prevent Data Breach: 10 Controls [Solved for 2026]
On this page

A single compromised credential or unpatched service can expose customer data, trigger compliance penalties, and destroy trust. Defense-in-depth layers multiple controls so that when one fails—and one will—the others hold the line.

I've seen breaches that could have been stopped by any one of these ten controls. Stack them together and you build a system that's hard to compromise and easy to audit.

Encrypt data at rest

Disk-level encryption protects data if someone walks away with a hard drive or gains physical access to your server. LUKS on Linux encrypts entire partitions; your data is gibberish without the key.

Set up LUKS during OS install or add it to an existing volume. Unlock at boot with a passphrase or key file stored on a separate device. For databases, use native encryption: MySQL's InnoDB tablespace encryption, PostgreSQL's pgcrypto, or transparent data encryption in SQL Server.

Application-level encryption gives you finer control. Encrypt sensitive columns (passwords, credit cards, PII) before writing to the database. Store keys in a dedicated vault—HashiCorp Vault, AWS KMS, or Azure Key Vault—not in your application config.

Backups need encryption too. An unencrypted backup sitting on S3 or a USB drive is a breach waiting to happen. Use encrypted transport and encrypted storage for every backup target.

Enforce encryption in transit

Every connection between client and server, server and database, server and API should run over TLS. Period.

Configure your web server to redirect HTTP to HTTPS and set HSTS headers so browsers remember to use HTTPS. Disable TLS 1.0 and 1.1; they're deprecated. Prefer TLS 1.3 for speed and security, fall back to 1.2 if clients require it.

# Apache
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
# Nginx
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

Database connections should use TLS too. MySQL's require_secure_transport, PostgreSQL's sslmode=require, Redis over stunnel—make it the default, not an option.

Internal service-to-service calls often skip encryption because "it's all on a private network." That's fine until an attacker pivots from a compromised container or VM. Encrypt internal traffic with mutual TLS or a service mesh if you're running microservices.

Implement multi-factor authentication everywhere

Passwords alone won't stop an attacker who phished your team or cracked a hash from an old breach. MFA adds a second proof: a time-based code from an authenticator app, a hardware token, or a push notification.

Enable MFA on every admin account—cPanel/WHM, cloud consoles, SSH, database admin tools, CI/CD pipelines. TOTP apps like Authy or Google Authenticator work fine. Hardware tokens (YubiKey, Titan) are stronger because they resist phishing.

For SSH, combine key-based auth with two-factor via PAM and libpam-google-authenticator. After you log in with your private key, the server prompts for a TOTP code.

sudo apt install libpam-google-authenticator
google-authenticator

Edit /etc/pam.d/sshd, add this line at the top:

auth required pam_google_authenticator.so

In /etc/ssh/sshd_config:

ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

Restart SSH. Now every login requires both your key and your TOTP code.

Log access and changes comprehensively

You can't investigate what you didn't log. Capture authentication attempts, file access, privilege escalations, configuration changes, and database queries.

Enable auditd on Linux to track who did what at the syscall level. Log SSH sessions, sudo commands, file modifications in sensitive directories.

sudo apt install auditd
sudo auditctl -w /etc/passwd -p wa -k passwd_changes
sudo auditctl -w /var/www -p wa -k web_changes

Application logs should record user actions—logins, failed auth, data access, permission changes. Correlate these with system logs to see the full picture.

Ship logs off-server immediately. An attacker who gains root access will clear local logs. Forward to a centralized collector (syslog-ng, Fluentd, Logstash) or a managed service (Datadog, Splunk, ELK). Retention depends on your compliance requirements; GDPR and PCI-DSS both set minimums.

Monitor logs for anomalies: repeated failed logins, privilege escalation, access from unexpected IPs, bulk data exports. Automated alerting catches incidents while they're still small.

Restrict access with least privilege

Every user and service should have the minimum permissions needed to do its job. No more.

Database users don't need GRANT ALL. Web application users need SELECT, INSERT, UPDATE, DELETE on specific tables. Backup users need SELECT only. Admin users exist for schema changes and nothing else.

CREATE USER 'webapp'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'webapp'@'localhost';
FLUSH PRIVILEGES;

File permissions matter too. Web content should be owned by a dedicated user, readable by the web server, writable by deployment automation only.

chown -R deploy:www-data /var/www/myapp
find /var/www/myapp -type d -exec chmod 755 {} \;
find /var/www/myapp -type f -exec chmod 644 {} \;

Upload directories need different rules—writable by the web server, not executable.

chmod 733 /var/www/myapp/uploads

Sudo access should be scoped. Instead of giving a deploy user full sudo, grant only the commands they need.

deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart myapp.service

Scan for vulnerabilities continuously

Unpatched software is the easiest way in. Automate scanning so you catch CVEs before attackers do.

OS-level tools like unattended-upgrades on Debian or yum-cron on RHEL apply security updates automatically. For production, test updates in staging first, but don't let that slow critical patches.

sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

Dependency scanners flag vulnerable libraries in your application. Snyk, Dependabot, and OWASP Dependency-Check all integrate with CI/CD. Run them on every commit.

Web application scanners like OWASP ZAP or Nikto test for common vulnerabilities—SQL injection, XSS, insecure headers, exposed admin panels. Schedule weekly scans and fix findings before they make it to production.

Port scans from outside your network show what an attacker sees. Use Nmap or Masscan to verify that only intended services are exposed.

nmap -sV -p- your-server-ip

If something's listening that shouldn't be, firewall it or disable it.

Segment networks and isolate workloads

Flat networks let attackers move laterally once they're in. Segmentation contains the blast radius.

Separate production, staging, and development environments into different VPCs or VLANs. Database servers live on a private subnet unreachable from the internet. Application servers sit in a DMZ behind a load balancer.

Firewall rules enforce segmentation. Web servers can reach the database on port 3306, but nothing else can. SSH access comes through a bastion host, not directly to production boxes.

# ufw example: allow web traffic, ssh from bastion only
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from bastion-ip to any port 22
sudo ufw default deny incoming
sudo ufw enable

Containers and VMs add another isolation layer. Even if an attacker escapes the application, they're stuck inside a sandbox with limited access.

Harden server and application configurations

Default configurations prioritize convenience, not security. Lock them down.

Disable unused services. If you're not running FTP, stop vsftpd. If you're not using IPv6, disable it. Fewer services mean fewer attack surfaces.

sudo systemctl disable vsftpd
sudo systemctl stop vsftpd

Change default ports for SSH and databases. It won't stop a determined attacker, but it cuts down on automated scans.

# /etc/ssh/sshd_config
Port 2222

Set resource limits to prevent denial-of-service. Apache's MaxRequestWorkers, Nginx's limit_req, MySQL's max_connections—cap them at realistic values.

Disable directory listings, server signatures, and error detail in production. An attacker shouldn't see your software versions or file structure.

ServerTokens Prod
ServerSignature Off
Options -Indexes
server_tokens off;
autoindex off;

Run applications as non-root users. If something gets exploited, the attacker inherits those limited privileges, not root.

Test and drill your incident response plan

An incident response plan sitting in a wiki doesn't help when you're scrambling at 2 AM. Drill it regularly so everyone knows their role.

Your plan should cover detection, containment, eradication, recovery, and post-incident review. Who gets paged first? Who talks to customers? Who preserves evidence for forensics?

Run tabletop exercises quarterly. Walk through a scenario—database exposed, ransomware on a server, stolen credentials—and talk through each step. Identify gaps before a real incident exposes them.

Automate containment where possible. A runbook or script that isolates a compromised server, rotates credentials, and snapshots volumes for forensics saves precious minutes.

Post-incident reviews aren't about blame. They're about finding the control that failed and fixing it so the same breach doesn't happen twice.

Monitor and alert on anomalies

Detection speed determines how much damage a breach causes. Catch it in minutes, not weeks.

Set up alerting for suspicious patterns: login from a new country, privilege escalation, bulk data export, changes to critical files, port scans, brute-force attempts.

Intrusion detection systems like Fail2ban, OSSEC, or Suricata watch for known attack patterns and block offending IPs automatically.

sudo apt install fail2ban

Configure jails for SSH, web server, and application logs. After a threshold of failed attempts, Fail2ban adds a firewall rule to block the source.

File integrity monitoring detects unauthorized changes. AIDE or Tripwire baseline your system, then alert when files change unexpectedly.

sudo apt install aide
sudo aideinit
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

Run aide --check daily via cron. Investigate every alert.

Back up data and test restoration

Backups are your last line of defense when everything else fails. But an untested backup is a gamble.

Automate backups of databases, application data, configurations, and logs. Store them offsite with encryption and versioning. Keep at least three copies: one onsite, one offsite, one offline or immutable.

# mysqldump with compression
mysqldump --single-transaction --routines --triggers myapp | gzip > myapp_$(date +%F).sql.gz

Rsync or Borg for file-level backups, database-native tools for consistent snapshots. Test restoration monthly. Spin up a fresh server, restore from backup, and verify the application works.

Immutable or append-only backups protect against ransomware. S3 Object Lock, Backblaze B2 with retention policies, or offline tape—attackers can't encrypt what they can't modify.

How often should I rotate encryption keys?

Rotate data encryption keys annually or after any suspected compromise. Rotate TLS certificates before expiry—Let's Encrypt does this every 90 days automatically. Access keys and API tokens should rotate every 90 days at most.

What's the fastest way to detect a breach?

Centralized logging with real-time alerting. Ship logs off-server, set up alerts for auth failures, privilege escalations, and unusual access patterns. Intrusion detection systems catch attack signatures within seconds.

Do I need all ten controls or can I pick a few?

Each control addresses a different failure mode. Skip one and that's the gap an attacker will find. Start with the highest-impact controls—encryption, MFA, least privilege—then layer in the rest.

How do I prove compliance with these controls?

Audit logs, configuration snapshots, and vulnerability scan reports. Automated compliance scanners (OpenSCAP, Prowler, ScoutSuite) generate evidence for PCI-DSS, HIPAA, SOC 2, and GDPR.

Can I automate most of this?

Yes. Configuration management tools like Ansible, Puppet, or Chef enforce hardening policies, manage encryption, and deploy monitoring. CI/CD pipelines run vulnerability scans and dependency checks on every build. Incident response playbooks trigger containment scripts automatically.

Start with the three that matter most

If you only have time to implement three controls today, pick these: encrypt data in transit with TLS everywhere, enforce MFA on every admin account, and ship logs to a centralized collector with alerting.

Those three stop the majority of opportunistic attacks and give you visibility into the rest. Build from there.