This is an old revision of the document!
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 allows the viewing and changing of kernel settings on a running system.
- The parameters available are those listed under /proc/sys/.
- Changes take effect immediately.
- The related /etc/sysctl.conf file is used to ensure that the settings persist after a reboot.
Sysctl changes can be:
- temporary - Using sysctl -w $tunable = $value.
- permanent - Add entries to change into /etc/sysctl.conf or the corresponding files within /etc/sysctl.d.
- at boot - Using the sysctl.$tunable=$value boot parameter.
- This seems to be better, as it is set at the beginning of the boot process, without depending on a user space service to read the values from configuration files.
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
kernel.kptr_restrict=2
A kernel pointer points to a specific location in kernel memory.
- These can be very useful in exploiting the kernel, but kernel pointers are not hidden by default — it is easy to uncover them by, for example, reading the contents of /proc/kallsyms.
- This setting aims to mitigate kernel pointer leaks.
- Alternatively, you can set kernel.kptr_restrict=1 to only hide kernel pointers from processes without the CAP_SYSLOG capability.
kernel.dmesg_restrict=1
dmesg is the kernel log.
- It exposes a large amount of useful kernel debugging information, but this can often leak sensitive information, such as kernel pointers.
- Changing the above sysctl restricts the kernel log to the CAP_SYSLOG capability.
kernel.printk=3 3 3 3
Despite the value of dmesg_restrict, the kernel log will still be displayed in the console during boot.
- Malware that is able to record the screen during boot may be able to abuse this to gain higher privileges.
- This option prevents those information leaks.
- This must be used in combination with certain boot parameters described below to be fully effective.
kernel.unprivileged_bpf_disabled=1
eBPF exposes quite large attack surface
- As such, it must be restricted.
- These sysctls restrict eBPF to the CAP_BPF capability (CAP_SYS_ADMIN on kernel versions prior to 5.8) and enable JIT hardening techniques, such as constant blinding.
net.core.bpf_jit_harden=2
Same reason as for kernel.unprivileged_bpf_disabled=1.
eBPF exposes quite large attack surface
- As such, it must be restricted.
- These sysctls restrict eBPF to the CAP_BPF capability (CAP_SYS_ADMIN on kernel versions prior to 5.8) and enable JIT hardening techniques, such as constant blinding.
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.
- Due to this, this sysctl is used to restrict this syscall to the CAP_SYS_PTRACE capability.
kernel.kexec_load_disabled=1
kexec is a system call that is used to boot another kernel during runtime.
- This functionality can be abused to load a malicious kernel and gain arbitrary code execution in kernel mode, so this sysctl disables it.
kernel.sysrq=4
The SysRq key exposes a lot of potentially dangerous debugging functionality to unprivileged users.
- Contrary to common assumptions, SysRq is not only an issue for physical attacks, as it can also be triggered remotely.
- The value of this sysctl makes it so that a user can only use the secure attention key, which will be necessary for accessing root securely.
- Alternatively, you can simply set the value to 0 to disable SysRq completely.
kernel.unprivileged_userns_clone=0
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