Hardening Linux Kernel

Version 1.

The Linux kernel is at the heart of every Linux system. With its extensive configuration options, it comes to no surprise that specific settings can be enabled to further harden your system.

In this guide, we focus on Linux kernel configuration entries that support additional hardening of your system, as well as the configuration through the syctl settings.

Applicable platforms

  • cpe:/o:gentoo:linux

Revision history

  • draft (as of 2012-07-21)

1. Kernel Configuration

The Linux kernel should be configured using a sane security standard in mind. When using grSecurity, additional security-enhancing settings can be enabled.

In this guide, kernel configuration is shown in the short-hand notation. This allows us to document configuration settings in a way that is somewhat more future proof, since the position of the settings in the kernel configuration changes often. In the resources below you will find instructions on how to convert short-hand notation to the current, right location in the configuration.

Kernel configuration can be handled through make menuconfig within the Linux kernel source code repository (usually /usr/src/linux).

References

  1. Gentoo Kernel Configuration Guide - Shorthand notation information. URL: <http://www.gentoo.org/doc/en/kernel-config.xml#shorthand>.

1.1. General kernel configuration settings

Next to the grSecurity-related settings, general Linux kernel configuration entries have a positive influence on the security of your system. These settings are described further in this section

1.1.1. Enable random number generator

If supported by your platform, enable the random number generator to provide a high bandwidth, secure source of random numbers (which is important for cryptographic functions). This can be accomplished using the CONFIG_ARCH_RANDOM setting.

Next, enable hardware-supported random generators (CONFIG_HW_RANDOM) and select the random number generator for your platform. Examples are the Intel i8xx-based random number generator (CONFIG_HW_RANDOM_INTEL) or the AMD 76x-based ones (CONFIG_HW_RANDOM_AMD) but others exist as well.

1.1.2. Enable audit support

If you need to enable auditing on the system (which definitely is a best practice to follow), you will need to enable auditing in the kernel configuration (CONFIG_AUDIT) together with support for auditing system calls (CONFIG_AUDITSYSCALL)

1.1.3. Enable TCP SYN cookie protection support

To support SYN cookies (a method to work around a denial-of-service attack using a flood of SYN requests) the Linux kernel first needs to be configured to support the method. This is handled through the CONFIG_SYN_COOKIES parameter.

Further configuration of this setting is then handled by the sysctl settings (which we describe later in this guide).

1.1.4. Enable compiler-driven stack protection

In Gentoo Hardened, the use of stack protection in the compiler is by default enabled, but for the Linux kernel, this feature is only selectable through the CONFIG_CC_STACKPROTECTOR selection.

Enabling this will provide some level of protection against stack based buffer overflows within the Linux kernel memory (not the user processes). If detected, the kernel will die with a kernel panic.

1.1.5. Mark read-only data pages as write-protected

When CONFIG_DEBUG_RODATA is set, the memory pages containing the Linux kernel read-only data are marked as write-protected, so that any attempt to update the data is trapped, prevented and reported.

1.1.6. Restrict memory access through /dev/mem

Do not allow root processes full access to all of the systems' memory through /dev/mem (which includes kernel memory and process memory). This should only be needed for kernel programmers or kernel debugging.

By enabling CONFIG_STRICT_DEVMEM the (root) user can only access memory regions expected for all legitimate common usage of /dev/mem.

1.1.7. Disable /proc/kcore support

When CONFIG_PROC_KCORE is selected, the system will have a /proc/kcore pseudo-file which corresponds to the system memory. As we do not want users snooping around in our memory, support for this must be disabled.

1.1.8. Restrict access to the kernel syslog

Users that hold no administrator function on the system should not need to access the kernel system logs (through dmesg). You can enforce this through the CONFIG_SECURITY_DMESG_RESTRICT option, but if you chose not to, you can still enable it through the sysctl kernel.dmesg_restrict.

Also, grSecurity has a related kernel setting for this (CONFIG_GRKERNSEC_DMESG) which accomplishes the same. As a matter of fact, the CONFIG_SECURITY_DMESG_RESTRICT setting is somewhat based on the grSecurity patch and available in the main kernel tree.

1.2. Use grSecurity

grSecurity is a set of kernel patches that provides additional countermeasures against popular exploit methods and common vulnerabilities. Although the patchset is not part of the mainstream Linux kernel sources, Gentoo offers grSecurity through the hardened-sources kernel package.

If you do not intend to use grSecurity, then you can ignore the rest of this section.

References

  1. grSecurity Homepage. URL: <https://grsecurity.net>.
  2. Gentoo grSecurity v2 Guide. URL: <http://www.gentoo.org/proj/en/hardened/grsecurity.xml>.

1.2.1. Use PaX

With PaX, additional protection against memory corruption bugs and exploits is enabled. We recommend to enable the following settings:

  • Use legacy ELF header marking (CONFIG_PAX_EI_PAX) and Use ELF program header marking (CONFIG_PAX_PT_PAX_FLAGS) so that you can enable/disable PaX settings on a per-binary basis.

  • Enforce non-executable pages (CONFIG_PAX_NOEXEC) to disable allocation of memory that is both executable (contains runnable code) and writeable. Write- and executable pages are risky as it allows attackers to introduce code (through overflows or other methods) in memory and then execute that code. However, the downside is that there are still applications (or drivers) that depend on RWX memory.

  • Segmentation based non-executable pages (CONFIG_PAX_SEGMEXEC) or Paging based non-executable pages (CONFIG_PAX_PAGEEXEC) will support the non-executable pages through memory segmentation or paging rules.

  • Emulate trampolines (CONFIG_PAX_EMUTRAMP) if you are on x86_32 architecture (the option is not available for x86_64). This will enable emulation of trampolines (small bits of code in non-executable memory pages) for those applications that you enable this on (which can be triggered through chpax or paxctl).

  • Restrict mprotect() (CONFIG_PAX_MPROTECT) will restrict the use of mprotect() so that applications cannot switch the purpose of pages (executable vs non-executable and such) after creating them.

  • Address Space Layout Randomization (CONFIG_PAX_ASLR) to introduce some randomization in the memory allocation so that attackers will find it much more difficult to guess the address of specific pages correctly.

  • Randomize kernel stack base (CONFIG_PAX_RANDKSTACK) to randomize every task's kernel stack on each system call, making it more difficult to both guess locations as well as use leaked information from previous calls.

  • Randomize user stack base (CONFIG_PAX_RANDUSTACK) to randomize every task's userland stack, providing similar protection as mentioned earlier but for user applications.

  • Randomize mmap() base (CONFIG_PAX_RANDMMAP) to randomize the base address of mmap() requests (unless the requests specify an address themselves). This will cause dynamically loaded libraries to appear at random addresses.

1.2.2. Enable file system protection measures

In the grSecurity patches, a set of additional protections are included to thwart information leakage as well as further limit chroot environments. We recommend to enable the following settings:

  • Proc restrictions (CONFIG_GRKERNSEC_PROC) so that the /proc file system will be altered to enhance privacy (prevent information leakage).

  • Restrict /proc to user only (CONFIG_GRKERNSEC_PROC_USER) so that non-root users cannot see processes of other users.

  • Allow special group (CONFIG_GRKERNSEC_PROC_USERGROUP) so that the members of a specific group can see other users' processes and network-related information.

  • Additional restrictions (CONFIG_GRKERNSEC_PROC_ADD) will prevent non-root users to see device information and memory information which can be (ab)used for exploit purposes.

  • Linking restrictions (CONFIG_GRKERNSEC_LINK) will prevent users to follow symlinks that are owned by other users in world-writeable sticky directories such as /tmp (unless that user is the owner of that directory). This prevents a certain kind of race conditions.

  • FIFO restrictions (CONFIG_GRKERNSEC_FIFO) will prevent users to write into FIFOs in world-writeable sticky directories (like /tmp if they do not own these FIFOs themselves.

  • Chroot jail restrictions (CONFIG_GRKERNSEC_CHROOT and all chroot-related options) to make the chroot jails more strict and less easy to break out from.

1.2.3. Enable Trusted Path Execution

When using sys-kernel/hardened-sources, enable CONFIG_GRKERNSEC_TPE, which enabled Trusted Path Execution, a safety measure that ensures that, for a set of users, these users can only execute binaries and scripts from root-owned directories.

References

  1. Gentoo Hardened grSecurity TPE Guide. URL: <http://www.gentoo.org/proj/en/hardened/grsec-tpe.xml>.

2. Kernel Tunables (Sysctl)

The Linux kernel offers an interface, called sysctl, allowing to fine-tune kernel parameters (and even changing its behavior). Many parameters offered through sysctl allow an administrator to further strengthen his systems' security.

To read and change sysctl parameters, you can use the sysctl command or the /etc/sysctl.conf file (which is used by the sysctl service (init script), part of the default boot process.

### Using sysctl command to read and set variables ###
# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
# sysctl -w net.ipv4.ip_forward=0
The sysctl values can also be read through the /proc/sys file system.

2.1. Disable IPv4 Forwarding

The net.ipv4.ip_forward sysctl setting controls if IP forwarding is allowed or not on the system.

Unless the system is used as a router or gateway, IPv4 forwarding should be disabled.

2.2. Enable Source Route Verification

To offer additional protection against IP spoofing, enable source route verification on all interfaces. This is governed through the net.ipv4.conf.*.rp_filter=1 setting.

With source route verification, the Linux kernel validates that an IP packet comes from the right interface. In other words, on a multi-homed system, packets that claim to be from your internal network on your external interface are dropped (and vice versa).

2.3. Disable IP Source Routing

Disable IP source routing on all interfaces through the net.ipv4.conf.*.accept_source_route=0 setting.

IP source routing would allow a remote user (the sender) to specify the route that the packet should take, rather than use the (default) routing tables used by the routers between the sender and the destination. This could be (ab)used to spoof IP addresses and still get the replies (rather than sending the replies to the real owner of the IP address).

2.4. Disable ICMP Redirects

Set net.ipv4.conf.*.accept_redirects=0 to disable ICMP redirect support on the interfaces.

ICMP redirect messages are used by routers to inform hosts to use a different gateway than the one used. These packets should only be sent by the gateway of the system, but since you control that gateway and know when this gateway is changed, there is no point in allowing ICMP redirect messages on your system. After all, this would allow for "remote" updating of your routing table, which could allow an attacker to get all packets you want to send to the outside first (rather than the packets immediately going to the real gateway).

2.5. Ignore ICMP Echo Broadcasts

When net.ipv4.icmp_echo_ignore_broadcasts=1 is set, then your system will not reply to broadcast 'ping' requests (a ping is an ICMP Echo request). Similar to hiding a WIFI SSID, this makes your system just a tiny bit more hidden from scanners.

2.6. Ignore ICMP Bogus Error Responses

When an invalid response is given to broadcast frames (which occurs sometimes in erronous routers), the Linux kernel will by default log this event. To ensure that these (harmless) reports do not clutter your logs, you can disable this through net.ipv4.icmp_ignore_bogus_error_responses by setting it to 1.

2.7. Enable Logging of Martians

When you receive a packet that seemingly originates from a location where you have no route for, this packet is dropped silently. You can enable logging of these packets (which are called martians) so that you at least are aware of them.

Note that martians can only exist if you do not use a "default gateway", since a default gateway always matches (if no other route does) for any IP address.

Logging of martians can be enabled through net.ipv4.conf.*.log_martians=1.

2.8. Enable TCP SYN Cookie Protection

One denial of service attack against a service would be to flood the server with SYN requests (the TCP packet that starts a handshake for a connection). Such a flood can easily lead to a service disruption as connection state handling would consume a lot of resources in a small timeframe.

By enabling net.ipv4.tcp_syncookies, the Linux kernel will change its handshake behavior when its SYN backlog queue overflows: it replies to SYN requests with the appropriate SYN+ACK reply, but it does not store the connection in its backlog queue. Instead, it will only do that when it gets the ACK reply on his SYN+ACK. Based on the information in this reply, the Linux kernel can then reconstruct the necessary information to generate an entry in the backlog queue.

It should be noted that enabling TCP cookies is a last-resort. It changes the TCP stack behavior of the Linux kernel, violating TCP protocol and dropping support for certain TCP extensions whose information is only available in a SYN packet.

To enable TCP SYN cookie protection, enable CONFIG_SYN_COOKIES in the kernel, set net.ipv4.tcp_syncookies=1 and set proper values for net.ipv4.tcp_max_syn_backlog, net.ipv4.tcp_synack_retries and net.ipv4.tcp_abort_on_overflow.