The Linux kernel exposes hundreds of tunable parameters through the /proc/sys virtual filesystem, and sysctl is the tool used to read and write these values persistently. Many default kernel settings prioritize compatibility and functionality over security, leaving attack surface that can be closed with targeted configuration. On RHEL 8, persistent sysctl settings are stored in drop-in files under /etc/sysctl.d/, ensuring hardening survives reboots and package updates. This tutorial applies a comprehensive set of kernel hardening parameters covering network stack protection, memory randomization, and kernel information disclosure.
Prerequisites
- RHEL 8 server with sudo or root access
- Understanding that some network parameters (e.g.,
ip_forward) will break routing if enabled on a router or gateway — apply only to servers that do not forward traffic - Access to a second terminal session in case a parameter breaks network connectivity
- A snapshot or backup of the system recommended before applying kernel changes
Step 1 — Understand sysctl and Persistent Configuration
Parameters set with sysctl -w are lost on reboot. Permanent changes require a configuration file in /etc/sysctl.d/. Files are applied in lexical order, so naming your file 99-hardening.conf ensures it loads last and can override distribution defaults.
# View current value of a parameter
sysctl net.ipv4.ip_forward
sysctl kernel.randomize_va_space
# List all current kernel parameters
sysctl -a 2>/dev/null | wc -l
# View existing sysctl drop-in files on RHEL 8
ls /etc/sysctl.d/
ls /usr/lib/sysctl.d/
# Apply all sysctl.d files without rebooting (used after creating/editing files)
sudo sysctl --system
# Create the hardening configuration file (empty for now)
sudo touch /etc/sysctl.d/99-hardening.conf
echo "sysctl hardening file created"
Step 2 — Apply Network Stack Hardening Parameters
The network hardening parameters disable IP forwarding (appropriate for non-router servers), reject ICMP redirects that could hijack routing, enable TCP SYN cookie protection against SYN flood attacks, and harden the reverse path filter to drop packets with spoofed source addresses.
# Write network hardening parameters to the configuration file
sudo tee /etc/sysctl.d/99-hardening.conf > /dev/null <<'EOF'
##############################################################################
# Network hardening — RHEL 8
##############################################################################
# Disable IP forwarding (servers that do not route traffic)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
# Disable ICMP redirect acceptance (prevents routing table hijacking)
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
# Disable sending ICMP redirects (this server is not a router)
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Enable TCP SYN cookies — protection against SYN flood DoS attacks
net.ipv4.tcp_syncookies = 1
# Enable reverse path filtering — drop packets with spoofed source addresses
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Ignore ICMP broadcast requests (Smurf attack mitigation)
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Ignore bogus ICMP error responses
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Log packets with impossible source addresses
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# Disable source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
EOF
echo "Network parameters written"
Step 3 — Apply Kernel Memory and Randomization Parameters
Address Space Layout Randomization (ASLR) randomizes the memory addresses used by the kernel and processes, making it significantly harder for attackers to exploit memory corruption vulnerabilities. Additional parameters restrict core dump behavior and hide kernel memory addresses from unprivileged users.
# Append kernel memory hardening parameters
sudo tee -a /etc/sysctl.d/99-hardening.conf > /dev/null <<'EOF'
##############################################################################
# Kernel memory and information hardening
##############################################################################
# Enable full ASLR (0=off, 1=conservative, 2=full)
kernel.randomize_va_space = 2
# Disable core dumps for setuid programs (prevents memory disclosure)
fs.suid_dumpable = 0
# Hide kernel symbol addresses from unprivileged users
# 0=unrestricted, 1=hide from non-root, 2=hide from all (including root)
kernel.kptr_restrict = 1
# Restrict access to kernel message buffer (dmesg)
# 1=restrict dmesg to CAP_SYSLOG
kernel.dmesg_restrict = 1
# Restrict perf events to privileged users
kernel.perf_event_paranoid = 2
# Disable magic SysRq key (prevents dangerous kernel commands via keyboard)
kernel.sysrq = 0
# Restrict ptrace to parent processes (limits debugger attachment)
# 1=only parent can ptrace, 2=only root can ptrace, 3=no ptrace
kernel.yama.ptrace_scope = 1
EOF
echo "Kernel memory parameters appended"
Step 4 — Apply File System Hardening Parameters
File system sysctl parameters control behaviors such as hard link and symbolic link restrictions that can be exploited in time-of-check/time-of-use (TOCTOU) attacks, as well as process tracing restrictions.
# Append filesystem hardening parameters
sudo tee -a /etc/sysctl.d/99-hardening.conf > /dev/null <<'EOF'
##############################################################################
# Filesystem hardening
##############################################################################
# Protect hard links — only allow links to files owned by the user or root
fs.protected_hardlinks = 1
# Protect symlinks — only follow symlinks in world-writable sticky dirs
# if owned by the directory owner or the current user
fs.protected_symlinks = 1
# Protect FIFOs in world-writable sticky directories
fs.protected_fifos = 1
# Restrict regular file opens in world-writable sticky directories
fs.protected_regular = 2
EOF
echo "Filesystem parameters appended"
# Review the complete configuration file
echo "=== /etc/sysctl.d/99-hardening.conf ==="
cat /etc/sysctl.d/99-hardening.conf
Step 5 — Load the Parameters and Verify
Apply all sysctl parameters immediately without rebooting using sysctl --system, which reads all files in /etc/sysctl.d/, /usr/lib/sysctl.d/, and /etc/sysctl.conf in order. Then verify that the critical parameters took effect.
# Apply all sysctl.d files (reads all drop-in files in order)
sudo sysctl --system
# Verify individual critical parameters
echo "=== Verification ==="
sysctl net.ipv4.ip_forward
sysctl net.ipv4.conf.all.accept_redirects
sysctl net.ipv4.tcp_syncookies
sysctl net.ipv4.conf.all.rp_filter
sysctl kernel.randomize_va_space
sysctl fs.suid_dumpable
sysctl kernel.kptr_restrict
sysctl kernel.dmesg_restrict
sysctl fs.protected_hardlinks
sysctl fs.protected_symlinks
# Confirm all hardening values match expectations
sysctl -a 2>/dev/null | grep -E
"(ip_forward|accept_redirects|tcp_syncookies|rp_filter|randomize_va_space|suid_dumpable|kptr_restrict)" |
grep -v "arp_"
echo "All parameters applied and verified"
Step 6 — Verify Settings Persist Across Reboots
Confirm that the hardening configuration survives a reboot by checking the file is present, then optionally testing with a controlled reboot. Also validate that the settings do not conflict with any other sysctl files that might override them.
# Check for any conflicting sysctl files that might override the hardening settings
echo "=== Checking for override conflicts ==="
# List all sysctl config files in load order
find /usr/lib/sysctl.d/ /etc/sysctl.d/ /etc/sysctl.conf
-maxdepth 1 -name "*.conf" -o -name "sysctl.conf" 2>/dev/null | sort
# Check if any earlier file sets ip_forward to 1 (which our file would override)
grep -r "ip_forwards*=s*1" /usr/lib/sysctl.d/ /etc/sysctl.d/ 2>/dev/null |
grep -v "99-hardening"
# Confirm hardening file will win (99 sorts last)
ls /etc/sysctl.d/ | sort
# Optionally: apply a single parameter interactively to test
sudo sysctl -w net.ipv4.tcp_syncookies=1
# After a reboot (test optional):
# sudo reboot
# After reboot, verify:
# sysctl net.ipv4.ip_forward # should be 0
# sysctl kernel.randomize_va_space # should be 2
echo "Sysctl hardening configuration is persistent and complete"
Conclusion
You have applied a comprehensive set of kernel hardening parameters to RHEL 8 via /etc/sysctl.d/99-hardening.conf, covering network stack protection against SYN floods, ICMP redirect attacks, and packet spoofing; full ASLR; core dump restrictions; kernel address hiding; and filesystem protection against symlink and hard link abuse. These parameters complement other hardening measures and impose negligible performance overhead. Review the settings against your specific workload — for example, re-enable net.ipv4.ip_forward if the system is a router or container host, and adjust kernel.yama.ptrace_scope if legitimate debugging tools require it.
Next steps: Auditing kernel parameter compliance with OpenSCAP on RHEL 8, Configuring SELinux in enforcing mode for mandatory access control on RHEL 8, and Hardening the GRUB2 bootloader with a password and secure boot on RHEL 8.