Increase kernel integrity with disabled Linux kernel modules loading

Disable loading kernel module on Linux systems

The Linux kernel can be configured to disallow loading new kernel modules. This feature is especially useful for high secure systems, or if you care about securing your system to the fullest. In this article, we will have a look at the configuration of this option. At the same time allowing legitimate kernel modules to be loaded.

Disable kernel modules

Newer kernel modules have a sysctl variable named kernel.modules_disabled.

Sysctl is the tool which allows you to see and change kernel settings of a running system. The related /etc/sysctl.conf file is used to ensure that your settings are also used at the next boot of the system.

The sysctl key kernel.modules_disabled is very straightforward. If it contains a “1” it will disable loading new modules, where a “0” will still allow loading them.

Using this option will be a great protection against loading malicious kernel modules. For example, it may help to counter rootkits. Needless to say, but when someone was already been able to gain root access, you have a serious problem. Still, setting this security measure can be useful to achieve maximum hardening of your Linux system. An altered script or program has no chance of loading things you didn’t specifically approve.

Loading modules

To show this functionality, we first will load a module and then see how the related sysctl value works. For this demo purpose, we will use the XOR module, which is part of the crypto category.

Background information:

The XOR kernel module uses the “exclusive OR” function, which returns True when an odd number of the given arguments equals to be true, and False when an even are true. Usually it is used with two arguments, so to return True, only 1 of the options can be positive.

Back to the loading of the module. First we ensure this module is not loaded:

Now we load the module with the insmod command and then check if loading was successful:

The module is loaded, as expected. To show normal behavior, we now will remove the kernel module with the rmmod command.

The module is released. Time to disable this functionality, to increase protection against loading malicious modules.

Activating kernel.modules_disabled

By default, the sysctl key is set to “0”, which means new modules can be loaded. This is a safe default for systems but also allows malicious modules to be loaded.

Now we disable loading new modules, by using the sysctl key and set it to “1”. There are two ways of doing it, using sysctl directly or echo the value to a file on the pseudo file system /proc, which holds the kernel settings.

Now we try loading our XOR module again:

Loading the module is now no longer allowed, exactly what we wanted.

Protection against re-enabling

You might think that loading a kernel module is as simple as re-enabling the option and then still load your kernel module. The kernel has a built-in protection, to avoid this from happening. Trying to set the value back to “0” will result in an “invalid argument” message.

As can be seen, sysctl will say the value is set to “0”. However, the value isn’t applied, as this key is read-only. Slightly confusing, and therefore always good to check the value again.

As expected, the value is still set to “1”.

Disable module loading after boot time

By configuring the /etc/sysctl.conf file we can disallow the loading of kernel modules at boot time. Simply add the related line, with the value “1” as shown in the example.

Caveat: Things might break

Depending on your environment, you might be careful with using this option. It may be working very well on servers, but not on desktop systems. The reason is the type of usage is different, especially when it comes with loading new kernel modules. For example inserting a USB drive, mouse or network functionality might break. So before deploying the option, make sure you test these common use cases.

Hybrid option

Instead of enabling the option directly via /etc/sysctl.conf, it might be better to activate this setting after booting and loading required modules.

Your startup script could be looking like:

Usually to get iptables working, these are the related modules: iptables, x_tables, iptable_filter.

Depending on your Linux distribution, the startup should be loaded as late as possible. If you have /etc/rc.local available, that is usually a safe bet.

Do you use this option already? Or found some other caveats? Like to hear!

Relevant commands in this article

Like to learn more about the commands that were used in this article? Have a look, for some there is a cheat sheet available:

Feedback

Small picture of Michael Boelen

This article has been written by our Linux security expert Michael Boelen. With focus on creating high-quality articles and relevant examples, he wants to improve the field of Linux security. No more web full of copy-pasted blog posts.

Discovered outdated information or have a question? Share your thoughts. Thanks for your contribution.

Mastodon icon