Table of Contents

Linux Hardening Guide - sysctl

The Linux kernel is flexible, and can be modified on the fly by dynamically changing some of its parameters using the sysctl command.

Sysctl changes can be:

IMPORTANT NOTE: Editing the sysctl.conf file might break the system - this is for advanced users only.


Make a backup of the existing /etc/sysctl.conf file

sudo cp /etc/sysctl.conf /etc/sysctl.conf.orig

NOTE: This is for safety reasons to allow switching back to the original.


Recommended sysctl settings to change for Kernel self-protection

kernel.kptr_restrict=2

A kernel pointer points to a specific location in kernel memory.


kernel.dmesg_restrict=1

dmesg is the kernel log.

NOTE: Capabilities:

  • In the Linux kernel, “root privileges” are split up into various different capabilities.
  • This is helpful in applying the principle of least privilege — instead of giving a process total root privileges, you can grant them only a specific subset instead.
  • For example, if a program simply needs to set your system time, then it only needs CAP_SYS_TIME rather than total root.
  • This could limit the potential damage that can be done; however, you must still be cautious with granting capabilities, as many of them can be abused to gain full root privileges anyway.

kernel.printk=3 3 3 3

Despite the value of dmesg_restrict, the kernel log will still be displayed in the console during boot.


kernel.unprivileged_bpf_disabled=1
net.core.bpf_jit_harden=2

eBPF exposes quite large attack surface


dev.tty.ldisc_autoload=0

This restricts loading TTY line disciplines to the CAP_SYS_MODULE capability to prevent unprivileged attackers from loading vulnerable line disciplines with the TIOCSETD ioctl, which has been abused in a number of exploits before.


vm.unprivileged_userfaultfd=0

The userfaultfd() syscall is often abused to exploit use-after-free flaws.


kernel.kexec_load_disabled=1

kexec is a system call that is used to boot another kernel during runtime.


kernel.sysrq=4

The SysRq key exposes a lot of potentially dangerous debugging functionality to unprivileged users.


kernel.unprivileged_userns_clone=0

User namespaces are a feature in the kernel which aim to improve sandboxing and make it easily accessible for unprivileged users.

NOTE: This sysctl only exists on certain Linux distributions, as it requires a kernel patch.

  • If your kernel does not include this patch, you can alternatively disable user namespaces completely (including for root) by setting user.max_user_namespaces=0.

kernel.perf_event_paranoid=3

Performance events add considerable kernel attack surface and have caused abundant vulnerabilities.

This sysctl restricts all usage of performance events to the CAP_PERFMON capability (CAP_SYS_ADMIN on kernel versions prior to 5.8).

NOTE: This sysctl also requires a kernel patch that is only available on certain distributions.


Recommended sysctl settings to change for Networks

net.ipv4.tcp_syncookies=1

This helps protect against SYN flood attacks, which are a form of denial-of-service attack, in which an attacker sends a large amount of bogus SYN requests in an attempt to consume enough resources to make the system unresponsive to legitimate traffic.


net.ipv4.tcp_rfc1337=1

This protects against time-wait assassination by dropping RST packets for sockets in the time-wait state.


net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1

These enable source validation of packets received from all interfaces of the machine.


net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.default.accept_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0

These disable ICMP redirect acceptance and sending to prevent man-in-the-middle attacks and minimize information disclosure.


net.ipv4.icmp_echo_ignore_all=1

This setting makes your system ignore all ICMP requests to avoid Smurf attacks, make the device more difficult to enumerate on the network and prevent clock fingerprinting through ICMP timestamps.


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

Source routing is a mechanism that allows users to redirect network traffic.


net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.default.accept_ra=0

Malicious IPv6 router advertisements can result in a man-in-the-middle attack, so they should be disabled.


net.ipv4.tcp_sack=0
net.ipv4.tcp_dsack=0
net.ipv4.tcp_fack=0

This disables TCP SACK.


Recommended sysctl settings to change for User Space

kernel.yama.ptrace_scope=2

ptrace is a system call that allows a program to alter and inspect another running process, which allows attackers to trivially modify the memory of other running programs.


vm.mmap_rnd_bits=32
vm.mmap_rnd_compat_bits=16

ASLR is a common exploit mitigation which randomises the position of critical parts of a process in memory. This can make a wide variety of exploits harder to pull off, as they first require an information leak. The above settings increase the bits of entropy used for mmap ASLR, improving its effectiveness.

The values of these sysctls must be set in relation to the CPU architecture. The above values are compatible with x86, but other architectures may differ.


fs.protected_symlinks=1
fs.protected_hardlinks=1

This only permits symlinks to be followed when outside of a world-writable sticky directory, when the owner of the symlink and follower match or when the directory owner matches the symlink's owner.


fs.protected_fifos=2
fs.protected_regular=2

These prevent creating files in potentially attacker-controlled environments, such as world-writable directories, to make data spoofing attacks more difficult.



Modify the sysctl file

Add the following entries to the bottom of the /etc/sysctl.conf file to stop some spoofing attacks and enhance other security measures:

/etc/sysctl.conf
...
...
# Network Security.
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5
 
# IPv6 Security (if enabled).
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0
 
# Process Security.
kernel.randomize_va_space = 2
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
kernel.perf_event_paranoid = 3
kernel.yama.ptrace_scope = 2
kernel.panic_on_oops = 1
kernel.panic = 60
kernel.sysrq = 0
 
 
# File System Security.
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
fs.suid_dumpable = 0
fs.protected_fifos = 2
fs.protected_regular = 2
 
# Additional Security Measures.
#dev.tty.ldisc_autoload = 0
#kernel.modules_disabled = 1
kernel.core_uses_pid = 1
kernel.panic_on_unrecovered_nmi = 1
kernel.panic_on_io_nmi = 1
kernel.unprivileged_bpf_disabled = 1
net.core.bpf_jit_harden = 2

Save the /etc/sysctl.conf file.


Activate the kernel settings that have been modified

This reloads the sysctl parameters:

sudo sysctl -p