Skip to content
Back to Blog
Security11 min read

Advanced Server Security Hardening Checklist: 8 Moves [2026]

Beyond firewall rules and SSH keys—eight deep hardening steps that close the gaps most guides skip, from syscall filtering to entropy tuning.

Written by Abdul AbrorTechnical Hosting Support Engineer
Advanced Server Security Hardening Checklist: 8 Moves [2026]
On this page

Most server hardening guides stop at firewalls, fail2ban, and disabling root login. You've done that already. The real vulnerabilities live deeper—in syscall access, kernel parameters, filesystem mount options, and the audit pipeline. I've spent years responding to intrusions that bypassed the standard playbook, and the patterns are clear: attackers probe for weak entropy, abuse SUID binaries, and exploit overly permissive syscalls. Here are eight advanced hardening moves that close those gaps.

1. Lock down syscalls with seccomp profiles

Seccomp filters which system calls a process can make. Most services need fewer than fifty syscalls, but by default every process can invoke all three hundred-plus. That's a massive attack surface.

Create a seccomp profile for your web server or application. For systemd services, add this to the unit file:

[Service]
SystemCallFilter=@system-service
SystemCallFilter=~@privileged @resources @obsolete
SystemCallErrorNumber=EPERM

The @system-service group allows common syscalls. The second line denies privileged operations, resource manipulation, and obsolete calls. Test carefully—if the service breaks, check journalctl -xe for denied syscalls and whitelist only what's necessary.

For containers, seccomp is even more important. Default Docker profiles are permissive. Generate a minimal profile with docker run --security-opt seccomp=profile.json and iterate until the container runs cleanly.

2. Harden mount options on every filesystem

Default mount options allow execution, device files, and SUID binaries everywhere. Lock them down per partition.

Edit /etc/fstab and add restrictive flags:

/dev/sda2  /tmp      ext4  defaults,nodev,nosuid,noexec  0 2
/dev/sda3  /var      ext4  defaults,nodev                 0 2
/dev/sda4  /home     ext4  defaults,nodev,nosuid          0 2
  • noexec prevents execution from /tmp and /var/tmp, common staging grounds for exploits.
  • nosuid disables SUID bit respect, blocking privilege-escalation binaries.
  • nodev denies device file interpretation.

After editing, remount with mount -o remount /tmp. Check with mount | grep tmp. If an application breaks, identify which binary needs execution and move it or create a narrower exception.

3. Restrict kernel pointers and symbols

Kernel address leaks make exploitation easier. Two sysctl settings hide them.

sysctl -w kernel.kptr_restrict=2
sysctl -w kernel.dmesg_restrict=1

The first hides kernel pointers even from root. The second restricts dmesg to CAP_SYSLOG, blocking unprivileged users from reading kernel logs that often leak addresses. Add both to /etc/sysctl.d/99-hardening.conf to persist across reboots.

Check with sysctl kernel.kptr_restrict. You'll still see 0000000000000000 in /proc/kallsyms, which is correct.

4. Tune entropy availability for cryptographic operations

Low entropy delays TLS handshakes and key generation, but it also creates weaker random numbers. Many VPS platforms provide poor entropy by default.

Check available entropy:

cat /proc/sys/kernel/random/entropy_avail

If it's consistently below 1000, install haveged or rng-tools. Haveged uses CPU timing jitter as an entropy source:

apt install haveged
systemctl enable haveged

After starting, entropy should stabilize above 2000. For cloud instances with virtio-rng, load the kernel module and point rngd at it:

modprobe virtio_rng
rngd -r /dev/hwrng

Don't rely on /dev/urandom alone for long-term keys. Generate them on a local machine with good entropy and upload securely.

5. Enable and tune auditd for forensic visibility

If an intrusion happens, you need to know what changed. Auditd logs syscalls and file access. Most servers either don't run it or log too much, filling disks.

Install and start:

apt install auditd audispd-plugins
systemctl enable auditd

Add targeted rules in /etc/audit/rules.d/hardening.rules:

# Watch authentication files
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k privilege

# Monitor privilege escalation attempts
-a always,exit -F arch=b64 -S setuid -S setgid -S setreuid -S setregid -k privilege_escalation

# Track network configuration changes
-w /etc/hosts -p wa -k network_config
-w /etc/sysconfig/network -p wa -k network_config

Reload with augenrules --load. Query logs with ausearch -k identity. In production I rotate audit logs daily and keep 30 days compressed. Disk is cheap; knowing when /etc/shadow was modified is priceless.

6. Isolate services with mandatory access control

Even if an attacker compromises a service, MAC systems like AppArmor or SELinux contain the damage. Most distributions ship with them installed but in permissive mode or with minimal profiles.

For AppArmor (Debian/Ubuntu), check status:

aa-status

If profiles exist but are in complain mode, enforce them:

aa-enforce /etc/apparmor.d/usr.sbin.nginx

Create custom profiles with aa-genprof. Run the service, exercise all features, then review and approve the generated policy. It's tedious but catches lateral movement.

For SELinux (RHEL/CentOS), verify enforcing mode:

getenforce

If it returns Permissive, edit /etc/selinux/config and set SELINUX=enforcing, then reboot. After enabling, watch for denials in /var/log/audit/audit.log and use audit2allow to create targeted policies. Don't disable SELinux to fix an application; fix the policy instead.

7. Restrict core dumps and process tracing

Core dumps can leak secrets and credentials in memory. Disable them for all users:

echo '* hard core 0' >> /etc/security/limits.conf
sysctl -w fs.suid_dumpable=0
sysctl -w kernel.core_pattern=|/bin/false

The first line sets a hard limit. The second prevents SUID programs from dumping. The third redirects dumps to /bin/false. For debugging, enable dumps temporarily for a single user, not system-wide.

Restrict ptrace to prevent process inspection:

sysctl -w kernel.yama.ptrace_scope=2

This blocks ptrace entirely except for children of a process. Debuggers still work, but an attacker can't attach to running processes to scrape memory.

Most servers accept packets from link-local addresses (169.254.0.0/16) and other invalid sources. That creates side channels for local attacks and helps attackers map the network.

Add these to /etc/sysctl.d/99-network.conf:

# Drop martian packets
net.ipv4.conf.all.log_martians=1
net.ipv4.conf.default.log_martians=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1

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

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

Apply with sysctl -p /etc/sysctl.d/99-network.conf. Martian logs will appear in dmesg if attacks occur.

For link-local specifically, add an iptables rule:

iptables -A INPUT -s 169.254.0.0/16 -j DROP

This matters most in cloud environments where metadata services live at 169.254.169.254 and SSRF attacks try to reach them.

Bonus: rotate and limit log files aggressively

Logs grow without bounds, filling disks and slowing searches. Configure logrotate for every service.

Create /etc/logrotate.d/custom:

/var/log/myapp/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}

This keeps two weeks of logs, compresses old ones, and signals the service to reopen files. For audit logs, increase retention but keep compression.

If disk fills anyway, attackers sometimes exploit that to disable logging. Monitor disk usage with df -h in cron and alert below 20% free.

What about intrusion detection?

Host-based IDS like AIDE or Tripwire catch file changes but generate noise. I run AIDE weekly and store the database off-host so an attacker can't tamper with it.

Initialize:

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

Check for changes:

aide --check

Exclude noisy paths like /var/log in /etc/aide/aide.conf. Review output carefully—legitimate package updates will show changes, but unauthorized modifications stand out.

For real-time monitoring, auditd is lighter and more actionable.

FAQ

Does seccomp break application compatibility?
Yes, if you're too aggressive. Start with @system-service and expand only when the service fails. Check logs for denied syscalls.

Can I use all these on a cPanel server?
Most will work. Avoid changing mount options on cPanel-managed partitions. Seccomp and sysctl settings are safe. Test in staging first.

How do I know which syscalls to allow?
Run strace -c on the service to see syscall frequency. Whitelist the top twenty and test. Tools like systemd-analyze security also suggest filters.

Will AppArmor or SELinux slow down my server?
The overhead is negligible—usually under 1%. The real cost is policy creation time. Once policies are correct, performance is fine.

Should I enable all sysctl settings at once?
No. Apply in groups, reboot, and test. A typo in sysctl can prevent boot. Keep a rescue console open.

Where to start

If you implement only two, choose auditd and seccomp. Auditd tells you what happened after an incident. Seccomp prevents many incidents from succeeding in the first place. Mount options come third—they're simple and catch a category of exploits that other tools miss.

Don't treat hardening as one-time work. New services need new seccomp profiles. New vulnerabilities need updated sysctls. Schedule quarterly reviews and check your audit logs monthly. The servers that stay secure are the ones where hardening is routine, not a project.