Skip to content
Back to Blog
Security11 min read

Server Security Best Practices 2026: 9 Essential Steps

Harden your infrastructure against modern threats with nine tested security controls that infrastructure teams rely on in 2026.

Written by Abdul AbrorTechnical Hosting Support Engineer
Server Security Best Practices 2026: 9 Essential Steps
On this page

Attack surfaces keep growing. The servers I worked with last year had fewer exposed services, simpler authentication paths, and smaller software stacks than what infrastructure teams manage today. Threat actors automate reconnaissance at scale now, scanning entire IPv4 ranges in hours and exploiting unpatched CVEs within days of disclosure.

You need a repeatable hardening process. These nine steps form the baseline security posture I recommend for any production Linux server in 2026, whether you're running a single VPS or a fleet of application hosts.

1. Lock down SSH immediately

SSH is the front door. Disable password authentication entirely and rely only on key pairs.

Edit /etc/ssh/sshd_config and enforce these lines:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Port 2289
AllowUsers deploy admin

Changing the default port from 22 to something higher cuts automated bot scans by more than half in my experience. The AllowUsers directive whitelists specific accounts, so even if an attacker guesses a valid username, SSH won't honor the attempt unless that user is listed.

Restart SSH after changes:

sudo systemctl restart sshd

Test your new config from a second terminal session before closing your current connection. If you lock yourself out, you'll need console access through your hosting control panel.

2. Configure a host-based firewall

Every server should run a firewall that defaults to DENY and explicitly permits only the ports you need. UFW on Ubuntu and Debian makes this simple.

Install and enable UFW:

sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2289/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw enable

For CentOS, Rocky, or AlmaLinux, use firewalld:

sudo firewall-cmd --set-default-zone=drop
sudo firewall-cmd --zone=public --add-port=2289/tcp --permanent
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --reload

Audit open ports quarterly. Every listening service is a potential entry point.

3. Enable automatic security updates

Manual patching doesn't scale. Automate updates for security packages at minimum, and schedule full system updates during maintenance windows.

On Debian and Ubuntu, install unattended-upgrades:

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

Edit /etc/apt/apt.conf.d/50unattended-upgrades to enable automatic reboots if needed:

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";

For RHEL-family distros, enable dnf-automatic:

sudo dnf install dnf-automatic
sudo systemctl enable --now dnf-automatic.timer

Configure /etc/dnf/automatic.conf to apply security updates:

[commands]
upgrade_type = security
apply_updates = yes

Log all updates and monitor for failures. A botched kernel update that breaks boot is better caught early.

4. Deploy fail2ban for brute-force protection

Even with SSH keys, you'll see login attempts. Fail2ban watches log files and temporarily bans IPs after repeated failures.

Install fail2ban:

sudo apt install fail2ban    # Debian/Ubuntu
sudo dnf install fail2ban    # RHEL/Rocky/Alma

Create /etc/fail2ban/jail.local:

[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3

[sshd]
enabled = true
port = 2289
logpath = /var/log/auth.log

Restart and verify:

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

You can add jails for HTTP services, mail servers, or any daemon that logs authentication events. Check /var/log/fail2ban.log to confirm it's catching attacks.

5. Harden kernel parameters with sysctl

The Linux kernel exposes hundreds of tunables. A few settings significantly improve security with zero performance cost.

Edit /etc/sysctl.conf or create /etc/sysctl.d/99-security.conf:

# Disable IP forwarding
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

# Enable SYN cookies
net.ipv4.tcp_syncookies = 1

# Ignore ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

# Ignore source-routed packets
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

# Log martian packets
net.ipv4.conf.all.log_martians = 1

# Disable ICMP echo for the host
net.ipv4.icmp_echo_ignore_all = 0

# Protect against time-wait assassination
net.ipv4.tcp_rfc1337 = 1

Apply immediately:

sudo sysctl -p

These controls close off classes of spoofing and redirection attacks that older servers were vulnerable to by default.

6. Run a host-based intrusion detection system

Firewalls block traffic, but HIDS monitors file integrity, processes, and rootkit signatures. AIDE and OSSEC both work well.

Install AIDE:

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

Schedule daily checks via cron:

0 2 * * * /usr/bin/aide --check | mail -s "AIDE Report" [email protected]

AIDE will alert you when critical binaries, config files, or libraries change unexpectedly. That's your early warning for compromised packages or backdoors.

For deeper inspection, deploy OSSEC with centralized log aggregation if you manage multiple hosts. OSSEC correlates events across your fleet and flags suspicious patterns like privilege escalation attempts or unusual network connections.

7. Enforce least privilege with sudo policies

Never log in as root. Create individual user accounts and grant elevated permissions only when needed.

Add a user and allow specific commands:

sudo adduser deploy
sudo usermod -aG sudo deploy    # Debian/Ubuntu
sudo usermod -aG wheel deploy   # RHEL/Rocky/Alma

For granular control, edit /etc/sudoers with visudo:

deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload php8.2-fpm

This lets the deploy user restart web services without a password prompt, but nothing else. Audit sudo logs in /var/log/auth.log or /var/log/secure regularly.

What about container and orchestration security?

If you run Docker or Kubernetes, treat the host OS as a critical boundary. Harden it with the steps above, then layer container-specific controls on top.

For Docker:

  • Run the daemon in rootless mode where possible.
  • Use --read-only and --tmpfs for ephemeral containers.
  • Scan images with Trivy or Clair before deployment.
  • Limit container capabilities with --cap-drop=ALL and add back only what's required.

Kubernetes demands Pod Security Standards, Network Policies, and RBAC audits. The host hardening checklist still applies to your worker nodes.

8. Centralize and monitor logs

Logs are forensic gold. Ship them off the host so an attacker can't cover their tracks by deleting local files.

Install rsyslog or syslog-ng and forward to a remote collector:

# /etc/rsyslog.d/50-remote.conf
*.* @@log-collector.example.com:514

Restart rsyslog:

sudo systemctl restart rsyslog

For smaller setups, configure logrotate to compress and retain logs for at least 90 days. Check /etc/logrotate.d/ for per-service configs.

Integrate with a SIEM or log analysis platform if budget allows. Real-time alerting on failed auth attempts, privilege escalations, or outbound connections to known malicious IPs gives you response time measured in minutes, not days.

9. Implement a backup and disaster recovery plan

Security controls reduce risk but don't eliminate it. A compromise or hardware failure will happen eventually.

Automate daily backups of:

  • Application data and databases
  • Configuration files in /etc
  • Home directories for service accounts
  • SSL/TLS certificates and private keys

Store backups off-site, encrypted, and test restoration quarterly. A backup you've never restored is just wishful thinking.

For VPS environments, snapshot the entire disk weekly. Most hosting providers offer API-driven snapshot automation.

# Example with DigitalOcean CLI
doctl compute droplet snapshot create <droplet-id> --snapshot-name "weekly-backup-$(date +%F)"

Document your restore process. Under pressure, you won't remember every step.

Start with SSH and the firewall

You don't need to implement all nine steps in one sitting. Harden SSH and enable your firewall first—those two alone block the majority of opportunistic attacks. Then add automated patching, fail2ban, and intrusion detection over the following week.

Document every config change in version control or a runbook. When you build your next server, you'll have a tested playbook to follow. Security is a process, not a one-time checklist.

FAQ

How often should I audit server security settings?

Quarterly at minimum. Schedule a checklist review every 90 days and after any major software deployment or infrastructure change.

Do I need a WAF if I already have a firewall?

Host firewalls operate at OSI layer 4 and below. A web application firewall inspects HTTP/HTTPS traffic at layer 7 and blocks SQL injection, XSS, and other app-layer attacks. They're complementary, not redundant.

Should I disable IPv6 if I'm not using it?

Yes. Unused protocols expand your attack surface. If you're not routing IPv6 traffic, disable it in /etc/sysctl.conf with net.ipv6.conf.all.disable_ipv6 = 1.

What's the biggest mistake you see in server security?

Running outdated software. Patch management is boring and breaks things occasionally, but unpatched vulnerabilities get exploited in the wild faster than you can manually review changelogs.