In this article, we describe several kernel parameters that have implications in the security of the system and how to harden these parameters. Note that for certain parameters, there are tighter values. However, for the sake of the balance between security and usability, this article does not include the ‘strictest’ values for those kernel parameters.
Enable Exec Shield protection
Exec Shield is first introduced by Red Hat. The goal is to protect against stack/buffer/function pointer overflows. In most of the newer Linux distributions, the option to disable Exec Shield through
sysctl was removed. For example, In Debian 10, if you do
sudo sysctl kernel.exec-shield=1, you will get
sysctl: cannot stat /proc/sys/kernel/exec-shield: No such file or directory.. You can check if Exec Shield is enabled in your system via:
sudo dmesg | grep "Execute Disable"
If you see an output similar to:
[ 0.000000] NX (Execute Disable) protection: active
then it is enabled. If it is not active, and you cannot enable it with
sysctl, it is also possible that the Exec Shield is disabled from the BIOS. Go to your BIOS settings and look for the following keywords: “NX”, “XD”, “No Execute” or “Execute Disable”.
Exec Shield project also brought address space randomization, to enable it:
sudo sysctl kernel.randomize_va_space=2
A value of 2 randomizes heap and the addresses of mmap base, stack and VDSO page. Sources [1,2,3].
Restrict ptrace call with Yama LSM
Yama Linux Security Module (LSM) brings a function which limits the scope of
ptrace is used frequently in debugging. From the
ptrace man page
The ptrace() system call provides a means by which one process (the “tracer”) may observe and control the execution of another process (the “tracee”), and examine and change the tracee’s memory and registers.
Thus, it is important to restrict the scope of
# Restrict ptrace scope sudo sysctl kernel.yama.ptrace_scope=1
A value of 1 means that only the parent process can be debugged. Sources [4,5].
Restrict core dumps
A core dump is a file which contains valuable information about why a software has crashed/closed unexpectedly. Core dumps can also be generated upon developer’s action, e.g. debugging. Although they have many benefits for troubleshooting problems, they might contain sensitive information. Disable processes with elevated privileges from making core dumps:
sudo sysctl fs.suid_dumpable=0
Restrict access to kernel pointers
If you want to prevent access to kernel symbol addresses to users without
CAP_SYSLOG, you can set the parameter via:
sudo sysctl kernel.kptr_restrict=1
If a value of 2 is set, the kernel will hide the symbol addresses regardless of the user privilege. Keep in mind that this might cause problems. Source .
Restrict access to kernel logs for unauthorized users
You can prevent access to kernel logs to users without
CAP_SYS_ADMIN capability via:
sudo sysctl kernel.dmesg_restrict=1
Network stack hardening
Harden BPF Just-in-Time (JIT) compiler
Before the famous Spectre vulnerability, it was a recommended practice to disable BPF Just-in-Time (JIT) compiler. Newer kernels set BPF JIT compiler to always ON, as recommended against Spectre-like vulnerabilities. In addition, Linux kernel has a parameter to harden BPF JIT compiler:
sudo sysctl net.core.bpf_jit_harden=1
which hardens unprivileged code. If you would like to harden all code, use a value of 2.
Protect against SYN flood attack
Prevent SYN flood attack, enable SYNcookies. These will kick-in when the
sudo sysctl net.ipv4.tcp_syncookies=1 sudo sysctl net.ipv4.tcp_syn_retries=2 sudo sysctl net.ipv4.tcp_synack_retries=2 sudo sysctl net.ipv4.tcp_max_syn_backlog=4096
Protect against IP spoofing
Enable IP spoofing protection, turn on source route verification.
sudo sysctl net.ipv4.conf.all.rp_filter=1 sudo sysctl net.ipv4.conf.default.rp_filter=1
Harden Bootstrap Protocol (BOOTP)
Disable BOOTP relay. Bootstrap Protocol (BOOTP) is similar to Dynamic Host Configuration Protocol (DHCP), both are used assign IP addresses to network-attached devices. Note that BOOTP is superseded by DHCP, and only used by legacy devices. To disable packet capturing and forwarding with BOOTP daemon:
sudo sysctl net.ipv4.conf.all.bootp_relay=0
Harden Address Resolution Protocol (ARP)
Disable proxy ARP. ARP stands for Address Resolution Protocol. What ARP does is that it maps IP address to a physical network address e.g. media access control (MAC) address. If you do not have a very specific reason, you can safely disable proxy ARP. This means that your computer would not answer ARP queries for an address which is not on the same subnet. You can also improve further by restricting the replies and ignoring the source address:
# Don't proxy arp for anyone sudo sysctl net.ipv4.conf.all.proxy_arp=0 # Modes for sending replies in response to received ARP requests that resolve local target IP addresses # Mode '1': reply only if the target IP address is local address configured on the incoming interface sudo sysctl net.ipv4.conf.all.arp_ignore=1 # Restriction levels for announcing the local source IP address from IP packets in ARP requests sent on interface # Mode '2': ignore the source address in the IP packet and try to select local address that we prefer for talks with the target host sudo sysctl net.ipv4.conf.all.arp_announce=2
Other network hardening
- Disable packet forwarding. If you are not doing packet forwarding, you can disable it in the kernel via:
sudo sysctl net.ipv4.ip_forward=0 sudo sysctl net.ipv4.conf.all.forwarding=0 sudo sysctl net.ipv4.conf.default.forwarding=0 sudo sysctl net.ipv6.conf.all.forwarding=0 sudo sysctl net.ipv6.conf.default.forwarding=0
- Disable ICMP redirect acceptance:
sudo sysctl net.ipv4.conf.all.accept_redirects=0 sudo sysctl net.ipv4.conf.default.accept_redirects=0 sudo sysctl net.ipv4.conf.all.secure_redirects=0 sudo sysctl net.ipv4.conf.default.secure_redirects=0 sudo sysctl net.ipv6.conf.all.accept_redirects=0 sudo sysctl net.ipv6.conf.default.accept_redirects=0
- Disable ICMP redirect sending:
sudo sysctl net.ipv4.conf.all.send_redirects=0 sudo sysctl net.ipv4.conf.default.send_redirects=0
- Disable source routing:
sudo sysctl net.ipv4.conf.all.accept_source_route=0 sudo sysctl net.ipv4.conf.default.accept_source_route=0 sudo sysctl net.ipv6.conf.all.accept_source_route=0 sudo sysctl net.ipv6.conf.default.accept_source_route=0
- Disable the logging of bogus responses from certain routers. From the kernel docs:
Some routers violate RFC1122 by sending bogus responses to broadcast frames. Such violations are normally logged via a kernel warning. If this is set to TRUE, the kernel will not give such warnings, which will avoid log file clutter.
To ignore such bogus responses:
sudo sysctl net.ipv4.icmp_ignore_bogus_error_responses=1
In addition, you can ignore ICMP ECHO and TIMESTAMP requests from broadcasts via:
sudo sysctl net.ipv4.icmp_echo_ignore_broadcasts=1
- Protect against time-wait assassination hazards in TCP:
sudo sysctl net.ipv4.tcp_rfc1337=1
Apply the settings to new connections
Lastly, ensure that the subsequent connections use the new configurations:
# Comes last sudo sysctl net.ipv4.route.flush=1 sudo sysctl net.ipv6.route.flush=1
Make the sysctl configuration permanent
The commands applied by
sudo sysctl <parameter>=<value> are only preserved for the current session. To make them persist across the reboots, you need to put parameter:value pairs (without
sudo sysctl) into a config file, e.g.
/etc/sysctl.d/99-sysctl.conf . Therefore, create it and fill with the desired values. Below is the convenience snippet which includes all the parameters shown in the previous parts, ready-to-be used in a configuration file:
### ### SYSTEM SECURITY ### ### # Enable address Space Randomization kernel.randomize_va_space = 2 # Restrict core dumps fs.suid_dumpable = 0 # Hide kernel pointers kernel.kptr_restrict = 1 # Restrict access to kernel logs kernel.dmesg_restrict = 1 # Restrict ptrace scope kernel.yama.ptrace_scope = 1 ### ### Deprecated/Not-in-use keys for security ### # The contents of /proc/<pid>/maps and smaps files are only visible to # readers that are allowed to ptrace() the process # kernel.maps_protect = 1 # Enable ExecShield # kernel.exec-shield = 1 ### ### NETWORK SECURITY ### ### # Harden BPF JIT compiler net.core.bpf_jit_harden = 1 # Prevent SYN attack, enable SYNcookies (they will kick-in when the max_syn_backlog reached) net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_max_syn_backlog = 4096 # Disable packet forwarding net.ipv4.ip_forward = 0 net.ipv4.conf.all.forwarding = 0 net.ipv4.conf.default.forwarding = 0 net.ipv6.conf.all.forwarding = 0 net.ipv6.conf.default.forwarding = 0 # Enable IP spoofing protection # Turn on source route verification net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 # Disable Redirect Acceptance 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 # Disable Redirect Sending net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 # Disable IP 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 net.ipv6.conf.default.accept_source_route = 0 # Don't relay bootp net.ipv4.conf.all.bootp_relay = 0 # Disable proxy ARP net.ipv4.conf.all.proxy_arp = 0 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2 # Mitigate time-wait assassination hazards in TCP net.ipv4.tcp_rfc1337 = 1 # Enable bad error message Protection net.ipv4.icmp_ignore_bogus_error_responses = 1 # Enable ignoring broadcasts request net.ipv4.icmp_echo_ignore_broadcasts = 1 # Ensure that subsequent connections use the new values # PUT TO THE END net.ipv4.route.flush = 1 net.ipv6.route.flush = 1
After the configuration file is set, apply the settings via:
sudo sysctl --system
- Exec Shield. Wikipedia. Retrieved from https://en.wikipedia.org/wiki/Exec_Shield
- NX bit. Wikipedia. Retrieved from https://en.wikipedia.org/wiki/NX_bit
- What is NX/XD feature? Red Hat. Retrieved from https://access.redhat.com/solutions/2936741
- Security. ArchWiki. Retrieved from https://wiki.archlinux.org/index.php/Security
- ptrace Linux Man Page. die.net. Retrieved from https://linux.die.net/man/2/ptrace
- Core dump. ArchWiki. Retrieved from https://wiki.archlinux.org/index.php/Core_dump
- Berkeley Packet Filter. Wikipedia. Retrieved from https://en.wikipedia.org/wiki/Berkeley_Packet_Filter
- bpf: Introduce bpf_jit_always_on config. Linux Kernel Organization Git Repository. Retrieved from https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=290af86629b25ffd1ed6232c4e9107da031705cb
- Sysctl. ArchWiki. Retrieved from https://wiki.archlinux.org/index.php/Sysctl
- Linux Kernel Documentation - Networking. Linux Kernel Organization. Retrieved from https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
- Bootstrap Protocol. Wikipedia. Retrieved from https://en.wikipedia.org/wiki/Bootstrap_Protocol
- Address Resolution Protocol. Wikipedia. Retrieved from https://en.wikipedia.org/wiki/Address_Resolution_Protocol