Disable automatic kernel module loading on Linux. Single-file Python 3 script, no dependencies.
“In the beginning, modprobe was created. This has made many people very angry and has been widely regarded as a bad move.” - Douglas Adams
Automatic module loading is a huge and mostly-ignored attack surface. Userspace can poke the kernel into loading ancient, rarely-audited kernel modules on demand. Disabling autoloading can prevent many zero-day vulnerabilities such as copy.fail
- Snapshot the currently-loaded modules (
lsmod) into/etc/modulesso they get loaded at boot. - Write
/bin/trueto/proc/sys/kernel/modprobeso the kernel can no longer satisfy userspace module requests. - Install a systemd unit that re-applies step 2 on every boot, immediately after
systemd-modules-load.serviceprocesses/etc/modules.
Note: The kernel has a stronger option (kernel.modules_disabled=1) but once set you can't undo it without a reboot. modlock is intentionally reversible.
Boot normally. Make sure every device you care about is up and every service you need has started. Modules not loaded at this moment will not be loaded after install.
./modlock --setup
Done.
Anything that wants a new module will fail until you unlock:
modlock --unlock # autoload back on
# plug / install / configure the new thing
modlock --update # capture the expanded module set
modlock --lock # autoload off
modlock --update |
Snapshot loaded modules → /etc/modules (overwrites) |
modlock --lock |
Set /proc/sys/kernel/modprobe = /bin/true |
modlock --unlock |
Set /proc/sys/kernel/modprobe back to the real modprobe |
modlock --install |
Copy script to /usr/local/sbin/modlock, install + enable modlock.service |
modlock --uninstall |
Disable + remove the service, restore autoloading |
modlock --setup |
Run --update, --install, and --lock in sequence |
All commands require root.
Linux with systemd, Python 3, root.