๐ŸŽ New User? Get 20% off your first purchase with code NEWUSER20 ยท โšก Instant download ยท ๐Ÿ”’ Secure checkout Register Now โ†’
Menu

Categories

Kernel Module & Modprobe Security Check: Linux Guide

Kernel Module & Modprobe Security Check: Linux Guide

Every kernel module you load is code running with full ring-0 privilege. An out-of-tree module with a backdoor, a legitimate module with a known CVE, or an unwanted filesystem driver loaded automatically when the wrong USB stick appears โ€” each is a path to root that bypasses every userspace defence you have. This guide covers the security-focused side of modprobe: signature verification, automatic load auditing, hard blacklisting, and post-boot lockdown.

What is loaded right now

lsmod                            # name, size, refcount, used-by
lsmod | wc -l                    # total module count
lsmod | awk '$3==0 {print $1}'   # loaded but unused (candidates for removal)
modinfo nf_tables | head          # description, parameters, signature, license

The "license" line in modinfo tells you whether the module taints the kernel. License: GPL is clean; License: Proprietary taints, which limits the support you can expect from upstream.

Signed modules and Secure Boot

Distribution kernels with Secure Boot enforce signature verification โ€” only modules signed by a trusted key can load. Verify your host:

mokutil --sb-state                          # Secure Boot enabled?
cat /sys/kernel/security/lockdown            # current lockdown mode
dmesg | grep -E 'taint|signature|loaded kernel'
modinfo MODULE | grep -E '^sig_'

If lockdown is integrity or confidentiality, unsigned modules cannot be loaded at all โ€” even by root. This is the recommended baseline for internet-facing servers.

Loading and unloading safely

sudo modprobe -v dummy                    # verbose; shows dependencies
sudo modprobe --dump-modversions /lib/modules/$(uname -r)/.../mod.ko
sudo modprobe -r dummy                    # unload, fails if in use
sudo dmesg -T | tail                       # kernel feedback after load

Always use modprobe rather than insmod โ€” only modprobe resolves dependencies and respects modprobe.d configuration.

Persisting load and parameters

echo dummy | sudo tee /etc/modules-load.d/dummy.conf
echo 'options dummy numdummies=4' | sudo tee /etc/modprobe.d/dummy.conf
sudo update-initramfs -u                  # Debian/Ubuntu
sudo dracut --force                       # RHEL family

Hard-deny: blacklist plus install-false

Blacklist alone only stops automatic loading; an attacker can still modprobe the module manually. The combination of blacklist and install-redirect closes both:

# /etc/modprobe.d/CIS.conf
install cramfs    /bin/true
install freevxfs  /bin/true
install jffs2     /bin/true
install hfs       /bin/true
install hfsplus   /bin/true
install squashfs  /bin/true
install udf       /bin/true
install usb-storage /bin/true
install dccp      /bin/true
install sctp      /bin/true
install rds       /bin/true
install tipc      /bin/true
install firewire-core /bin/true
blacklist cramfs
blacklist freevxfs
blacklist jffs2
blacklist hfs
blacklist hfsplus
blacklist squashfs
blacklist udf
blacklist usb-storage
blacklist dccp
blacklist sctp
blacklist rds
blacklist tipc
blacklist firewire-core

Each entry closes a specific attack vector: rare filesystem drivers used by USB exploits, obscure protocols used in CVEs, and DMA-attack interfaces. The list is the CIS Linux Benchmark recommendation; apply, rebuild initramfs, reboot.

Post-boot lockdown

For appliances or any host where module loading should stop after boot:

echo 1 | sudo tee /proc/sys/kernel/modules_disabled
# or persistent:
echo 'kernel.modules_disabled = 1' | sudo tee /etc/sysctl.d/99-modules.conf

Once set, no module can be loaded or unloaded until reboot. Apply only after all expected modules are loaded; mistime it and you cannot load nf_conntrack when iptables decides it needs it.

Auditing module load events

# /etc/audit/rules.d/modules.rules
-w /sbin/insmod       -p x -k modules
-w /sbin/modprobe     -p x -k modules
-w /sbin/rmmod        -p x -k modules
-a always,exit -F arch=b64 -S init_module,delete_module,finit_module -k modules
sudo augenrules --load
sudo ausearch -k modules -ts today | head

Now every module load attempt โ€” successful or not, automatic or manual โ€” is recorded with the originating UID, parent process, and exact syscall arguments. This is the single most useful audit rule for catching kernel-rootkit installation.

Module integrity baseline

An attacker may replace a legitimate .ko file on disk and wait for next reboot. Defend by snapshotting hashes:

find /lib/modules/$(uname -r) -name '*.ko*' \
  -exec sha256sum {} + | sort > /var/lib/modules-baseline.sha256
# later:
diff /var/lib/modules-baseline.sha256 \
     <(find /lib/modules/$(uname -r) -name '*.ko*' -exec sha256sum {} + | sort)

Wrap into a daily cron and ship the diff to your log collector. Any non-empty diff outside an apt/dnf upgrade window is suspicious.

The audit script

#!/bin/bash
echo "== Loaded modules count =="
lsmod | tail -n +2 | wc -l
echo "== Tainted? =="
cat /proc/sys/kernel/tainted
echo "== Lockdown =="
cat /sys/kernel/security/lockdown 2>/dev/null || echo "n/a"
echo "== Modules-disabled =="
cat /proc/sys/kernel/modules_disabled
echo "== Recently loaded (audit) =="
ausearch -k modules -ts today 2>/dev/null | grep -c 'type=SYSCALL'
echo "== Unsigned loaded modules =="
for m in /sys/module/*/sections; do
  d=$(dirname "$m"); n=$(basename "$d")
  modinfo "$n" 2>/dev/null | grep -q '^sig_id' || echo "  $n"
done | head -10

Common pitfalls

  • Blacklisting usb-storage on a server, then needing it for an emergency backup; document an "emergency unblock" runbook before locking down.
  • Setting kernel.modules_disabled=1 in sysctl too early; if a service later requires a not-yet-loaded module the host hangs.
  • Forgetting initramfs rebuild after blacklist changes โ€” the unwanted module loads anyway from the early ramdisk.
  • Using install MODULE /bin/false instead of /bin/true; /bin/false exits non-zero and pollutes logs.

Module security is configured once at provisioning, validated weekly, and forgotten the rest of the year โ€” until it saves you. Apply the CIS deny list, sign in audit rules, snapshot hashes, and your kernel attack surface shrinks dramatically without losing a single feature you actually use.

Share this article:
Dargslan Editorial Team (Dargslan)
About the Author

Dargslan Editorial Team (Dargslan)

Collective of Software Developers, System Administrators, DevOps Engineers, and IT Authors

Dargslan is an independent technology publishing collective formed by experienced software developers, system administrators, and IT specialists.

The Dargslan editorial team works collaboratively to create practical, hands-on technology books focused on real-world use cases. Each publication is developed, reviewed, and...

Programming Languages Linux Administration Web Development Cybersecurity Networking

Stay Updated

Subscribe to our newsletter for the latest tutorials, tips, and exclusive offers.