Tech Guides & Troubleshooting

Linux Production Server Hardening Guide: Kernel Parameters, SSH Lockdown & Memory Defenses

An authoritative, hands-on technical walkthrough for sysadmins hardening Debian, Ubuntu, and RHEL production servers against network and memory exploits.

Linux Production Server Hardening Guide: Kernel Parameters, SSH Lockdown & Memory Defenses
Zero Hour Key Takeaways

An authoritative, hands-on technical walkthrough for sysadmins hardening Debian, Ubuntu, and RHEL production servers against network and memory exploits.

Linux distributions like Debian, Ubuntu, and Red Hat Enterprise Linux (RHEL) ship with default configurations optimized for broad hardware compatibility and ease of deployment. While this philosophy is excellent for local development, it leaves production environments exposed to a wide array of network exploits, privilege escalation vectors, and brute-force attacks. A default installation permits unnecessary network protocols, exposes detailed kernel memory maps to unprivileged users, and allows legacy cryptographic handshakes.

Transforming a stock installation into a hardened production system requires systematic adjustments across three core layers: the network stack via sysctl, the remote access vector via OpenSSH, and the operating system's internal memory space. This guide provides a production-tested blueprint to implement these defenses without disrupting standard application workflows.

Fortifying the Network Stack Against Protocol Exploits

The Linux kernel's network stack is highly configurable through the sysctl interface. By default, it is susceptible to various attacks, including SYN floods, IP spoofing, and malicious routing redirections. To mitigate these threats, we can create a dedicated configuration file that overrides unsafe defaults during the boot sequence.

Create a file named /etc/sysctl.d/99-hardened.conf using your preferred text editor. This file will consolidate our network-hardening parameters:

# Prevent SYN flood attacks by enabling TCP SYN cookies
net.ipv4.tcp_syncookies = 1

# Protect against TCP time-wait assassination (RFC 1337)
net.ipv4.tcp_rfc1337 = 1

# Disable packet forwarding unless the server is acting as a router
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

# Ignore ICMP redirects to prevent routing table manipulation
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

# Do not send ICMP redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# Disable source routing, which allows attackers to spoof packet paths
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

# Enable strict reverse path filtering to mitigate IP spoofing
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

Each parameter serves a distinct defensive purpose:

  • TCP SYN Cookies: When a server is targeted by a SYN flood, the TCP connection queue fills up, causing a denial of service. Enabling SYN cookies forces the server to encode connection state details into the TCP sequence number, eliminating the need to allocate memory for half-open connections.
  • RFC 1337 Compliance: This setting drops RST packets for sockets in the TIME-WAIT state, protecting the system against blind reset attacks.
  • Reverse Path Filtering (rp_filter): Setting this to 1 forces the kernel to validate the source address of packets received on an interface against the routing table. If the return path does not match the receiving interface, the packet is silently discarded, neutralizing basic IP spoofing.

To apply these changes immediately without restarting the server, execute the following command:

sudo sysctl --system

Restricting Remote Access with an OpenSSH Lockdown

OpenSSH is the primary gateway into your production servers, making it a constant target for automated brute-force tools and sophisticated exploit attempts. Securing SSH requires deprecating legacy cryptographic algorithms, disabling password authentication, and enforcing strict session management.

Rather than editing the monolithic /etc/ssh/sshd_config file directly—which can be overwritten during package updates—it is safer to place custom configurations in a drop-in directory. Create the file /etc/ssh/sshd_config.d/hardened.conf:

# Enforce SSH Protocol 2
Protocol 2

# Disable password-based authentication; rely entirely on SSH keys
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes

# Prevent root login via SSH to stop direct administrative attacks
PermitRootLogin no

# Limit authentication attempts before the connection is dropped
MaxAuthTries 3
MaxSessions 2

# Terminate idle sessions automatically (300 seconds / 5 minutes)
ClientAliveInterval 300
ClientAliveCountMax 0

# Disable X11 forwarding and agent forwarding to reduce attack surface
X11Forwarding no
AllowAgentForwarding no

# Restrict cryptography to modern, secure primitives
KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Ciphers [email protected],[email protected]
MACS [email protected]

By disabling PasswordAuthentication and enforcing PubkeyAuthentication, you render automated brute-force attacks useless. The cryptographic selections are highly deliberate: legacy, vulnerable ciphers like RC4, 3DES, and Blowfish are excluded, as are CBC-mode ciphers which are susceptible to padding oracle attacks. We instead mandate modern AEAD (Authenticated Encryption with Associated Data) ciphers like ChaCha20-Poly1305 and AES-GCM.

Before restarting the SSH service, always validate the syntax of your configuration. A single typo can lock you out of your server:

sudo sshd -t

If the configuration test returns no output, it is safe to restart the daemon:

# For Debian/Ubuntu
sudo systemctl restart ssh

# For RHEL/Rocky Linux
sudo systemctl restart sshd

Mitigating Memory Exploits and Kernel-Level Information Leaks

Once an attacker gains an initial foothold on a server—perhaps through a vulnerable web application—their next objective is privilege escalation. This often involves exploiting memory safety vulnerabilities within the kernel or system binaries. We can restrict the kernel's internal interfaces to prevent information disclosure and hinder exploit reliability.

Append the following memory and kernel security settings to /etc/sysctl.d/99-hardened.conf:

# Enforce system-wide Address Space Layout Randomization (ASLR)
kernel.randomize_va_space = 2

# Restrict access to kernel pointers in /proc to prevent memory mapping
kernel.kptr_restrict = 2

# Prevent unprivileged users from viewing kernel log buffer (dmesg)
kernel.dmesg_restrict = 1

# Disable unprivileged eBPF to mitigate speculative execution side-channels
kernel.unprivileged_bpf_disabled = 1

# Restrict ptrace scope to child processes to block process memory dumping
kernel.yama.ptrace_scope = 1

# Prevent hardlink and symlink attacks in shared directories like /tmp
fs.protected_hardlinks = 1
fs.protected_symlinks = 1

These settings establish critical barriers against local privilege escalation:

  • ASLR (randomize_va_space): Randomizes the memory locations of program components (stack, library, heap). This makes buffer overflow exploits highly unpredictable, typically causing a crash rather than code execution.
  • Kernel Pointer Restriction (kptr_restrict): Restricts the visibility of kernel addresses in files like /proc/kallsyms. Attackers rely on these addresses to build exploit payloads targeted at specific memory structures.
  • eBPF Restrictions: Extended Berkeley Packet Filter (eBPF) is a powerful kernel subsystem. However, it has been repeatedly exploited to bypass Spectre mitigations. Disabling unprivileged eBPF limits this massive attack surface to root-level processes.
  • Yama Ptrace Scope: Restricts the ability of processes to attach to other processes using ptrace. This stops a compromised non-root user from reading the memory space of other running processes belonging to the same user (such as extracting active SSH agent keys or web session tokens).

Apply these settings using:

sudo sysctl --system

Resolving Network and Monitoring Edge Cases

Implementing strict security policies occasionally introduces operational friction. Sysadmins must be prepared to troubleshoot and resolve common issues that arise from these hardened settings.

One frequent issue involves asymmetric routing. If your production server is multi-homed (connected to multiple networks or utilizing multiple network interfaces), strict reverse path filtering (rp_filter = 1) may drop legitimate traffic. If a request arrives on eth0 but the routing table dictates that the response should exit via eth1, the kernel will discard the packet.

If you observe dropped connections on multi-homed systems, check your system logs or monitor dropped packets. If asymmetric routing is required, you can downgrade the filter to loose mode (2) rather than disabling it entirely:

# Fallback to loose reverse path filtering for multi-homed hosts
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2

Another operational conflict involves monitoring agents (such as Datadog, Prometheus Node Exporter, or custom APM tools). Many of these agents read /proc or require ptrace access to monitor application performance. If kernel.yama.ptrace_scope is set to 1, these agents may fail to gather process-level metrics.

To resolve this without disabling Yama ptrace protections entirely, you can grant specific capabilities to your monitoring binaries using setcap:

sudo setcap cap_sys_ptrace+ep /usr/bin/monitoring-agent-binary

This grants the monitoring agent the specific capability to trace processes without requiring root privileges or opening the system up to broader exploitation.

By systematically locking down the network stack, hardening the SSH daemon, and restricting access to kernel memory spaces, you dramatically reduce the attack surface of your Linux infrastructure. Regular audits, combined with automated configuration management tools like Ansible, ensure these configurations remain consistent across your entire fleet.

Frequently Asked Questions

No. Container engines like Docker, containerd, and Kubernetes system components run as root or with specific capabilities (CAP_SYS_ADMIN). They can still compile and load eBPF programs for networking and observability. Disabling unprivileged eBPF only prevents non-root, unprivileged container processes or local shell users from executing eBPF system calls, mitigating local privilege escalation vectors.
TOPIC TAGS:#Linux#Security#DevOps#SysAdmin#Kernel
Z
Zero Hour Tech EditorialVerified Analyst

Contributing editor at Zero Hour Tech, specializing in tech guides & troubleshooting analysis, vulnerability response, and emerging software paradigms.

View Full Profile & Articles →

Related Articles in Tech Guides & Troubleshooting

View All (4) →
ZERO HOUR DISPATCH

Never Miss a Zero-Day Threat or AI Breakthrough

Get our concise weekly security briefings covering newly disclosed vulnerabilities, exploit mechanics, and actionable system hardening guides.

100% Privacy guaranteed. One-click unsubscribe at any time.