Open-source project
a13xp0p0v/kernel-hardening-checker avatar
a13xp0p0v/kernel-hardening-checker

kernel-hardening-checker reads config, cmdline and sysctl as one problem

A tool for checking the security hardening options of the Linux kernel

2,140 stars193 forksPythonGPL-3.0

At a glance

What is it?
kernel-hardening-checker is a Python tool that compares a Linux kernel's compile-time Kconfig options, its boot command line and its runtime sysctl values against a curated rule set drawn from KSPP, grsecurity, CLIP OS, GrapheneOS and the CIS benchmark, and tags every finding with where the recommendation came from. Its JSON output mode and functional test suite make it usable as a build gate rather than a reading exercise.
Who is it for?
Adopt kernel-hardening-checker if you ship kernels or kernel-derived images, because a setting can be right in .config and still be undone on the command line or in sysctl, and no single-source checklist catches that. Do not adopt it as a hardening guide, since it tells you which options are off and never what turning them on costs, and the README says so directly.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A hardening option lives in three places, and this checks all three

The design idea is in the first line of the feature list. A kernel security setting can be a compile-time Kconfig option, a boot-time kernel command line argument, or a runtime sysctl parameter, and a system can have a correct .config and still lose most of the protection because the bootloader appends a permissive argument or because a sysctl was written at boot. Checking one source of truth and calling it hardened is the mistake this tool exists to prevent, and the README's motivation is exactly that nobody wants to check configs by hand. So there are three input types, each pointing at a file: a Kconfig file for compile-time options, a command line file for boot arguments, and a sysctl output file for runtime values. Running the same rule set across all three turns three lists into one report, and it is the reason this is more than a diff against a reference .config.

Every check carries a group tag and a provenance column

The verbose output is where the design becomes concrete, and it is worth reading slowly. Each row names the option, the kind of check it belongs to, a group tag such as cut_attack_surface, and a column showing which upstream source recommends it, with entries like defconfig and kspp. Complex checks are printed as their internals: the example in the README shows a check labelled OR that passes if CONFIG_STRICT_DEVMEM is set or, failing that, if CONFIG_DEVMEM is not set, which is the grsecurity style of shrinking attack surface rather than adding a lock. Two things follow. First, the tool is an opinion, encoded: the rule set is a set of choices made by the author about what hardened means, and knowing which source each choice came from is how you argue with it. Second, a boolean expression over several options is not something you can hand-check with a shell loop, which is the practical argument for using the tool at all.

Where the rules come from, and the map beside them

The README lists what the recommendations are based on, and the list is the argument for trusting them: KSPP recommended settings, direct feedback from the Linux kernel maintainers, options that grsecurity disables to cut attack surface, the CLIP OS kernel configuration, GrapheneOS recommendations, the SECURITY_LOCKDOWN_LSM patchset, and the CIS Benchmark. That is a set of sources with different goals, which is exactly why the provenance column exists. A desktop distribution, a mobile one, a general purpose server and a CIS compliance target will not agree on every option, and a tool that presented one list as universal truth would be less useful than one that tells you which list a check came from. The author has also built a Linux Kernel Defence Map, a graphical view of how hardening features relate to vulnerability classes and exploitation techniques, which is a better way to decide what to enable than a pass or fail report when your threat model is specific.

Three ways to install, one of which installs nothing

From the repository, with pip:

bash
python3 -m pip install git+https://github.com/a13xp0p0v/kernel-hardening-checker

The README anticipates the objection from a modern distribution and tells you to create a virtual environment with python3 -m venv if pip refuses because of an externally managed environment. Some GNU/Linux distributions package it, and the README points at repology rather than naming them, so the availability depends on your distribution rather than on the project. The third route is the one that suits a quick look: clone the repository and run the script from the bin directory, with no installation at all.

bash
./bin/kernel-hardening-checker -h

pyproject.toml requires Python 3.9 or newer, takes the version dynamically from the package's own __version__ attribute, and declares the licence as GPL-3.0-only with the LICENSE.txt file. There is no runtime dependency list to speak of, which is worth noticing in a tool meant to run inside build pipelines.

The flags decide whose kernel you are checking

The command line is the interface, and the options separate checking a live machine from auditing someone else's. -a autodetects and checks the hardening options of the running kernel, which is the quick self-assessment. -c points at a Kconfig file and also accepts gzipped ones, which is how you check an image you built. -v takes a kernel version read from a version file such as /proc/version instead of inferring it from a Kconfig, which matters because the recommended option set changes with the kernel release and because a Kconfig fragment alone does not tell you which version it targets. -l takes a command line file such as /proc/cmdline. -s takes a file containing sysctl output, produced on the target by:

bash
sudo sysctl -a > file

The remaining two do not check anything. -p prints the recommendations for a chosen architecture, which is how you read the rule set before you apply it, and -g generates a Kconfig fragment for that architecture, which is the starting point for a build. Architectures covered are X86_64, X86_32, ARM64, ARM and RISC-V. Together, -c, -l, -s and -v are also how you audit a host you do not have shell access to, by asking for those three files and running the check offline.

JSON output, Codecov badges and a functional test suite

The output modes are where this stops being a reporting tool and becomes a piece of infrastructure. The default mode is the human report. -m verbose adds the options that have no corresponding check and prints the internals of AND and OR checks, which is the mode to use when a rule surprises you. -m json prints the results as JSON, and the README states the reason plainly, that it is for combining kernel-hardening-checker with other tools. -m show_ok and -m show_fail let you invert the view, which is what you want in a pipeline that fails on a specific class of finding. The repository layout backs this up: a man directory for the manual page, an issues.md, MANIFEST.in for packaging, and a .woodpecker directory, so continuous integration runs on Woodpecker with separate badges for the functional test and the engine unit test, both feeding Codecov coverage flags. The README does not describe what the functional tests assert, which is the gap to ask about before trusting the JSON schema in a gate.

The tool will not tell you what hardening costs you

The README has a short section headed Attention, and it is the most important paragraph in the document for anyone about to act on a report. It says that changing Linux kernel security parameters may also affect system performance and the functionality of userspace software, and that you should consider the threat model of your system and test its typical workload thoroughly. That warning is the tool's honest boundary. A pass or fail list tells you a hardening option is off; it cannot tell you whether enabling it breaks your network stack, your container runtime, your disk encryption tooling or your performance budget. In practice the options that cause the most trouble are the ones that restrict namespaces, restrict unprivileged user namespaces, lock down module loading and restrict perf events, because each of them has userspace counterparts written under looser assumptions. Treat a full pass as the start of a change with a rollback plan and a load test, not as a target to hit in one sitting.

Against a sysctl file, a CIS tool, or your own baseline

The usual alternatives each cover less ground. A distribution's sysctl drop-in config sets runtime parameters and says nothing about compile-time options, which is the majority of the attack surface the tool looks at. A CIS benchmark scanner reports compliance against a checklist, which is what you need for an audit and what you do not need for a design decision, because a benchmark encodes a generic target rather than your threat model. Keeping a reference .config and diffing against it is the closest approach, and it fails in a specific way: it tells you the option changed, not whether the change reduced exposure, and it has nothing to say about the command line or sysctl overriding it at boot. The difference in approach here is that this tool evaluates boolean expressions over options, tags each one with a group and a source, and offers to generate the fragment to start from. The GPL-3.0-only licence is worth noting next to the MIT licensing of most security tooling, since it is viral for a distributed tool.

Editorial conclusion

Adopt kernel-hardening-checker if you ship kernels or kernel-derived images, because a setting can be right in .config and still be undone on the command line or in sysctl, and no single-source checklist catches that. Do not adopt it as a hardening guide, since it tells you which options are off and never what turning them on costs, and the README says so directly. Verify four things: that you have the kernel version available, because -v reads it from a version file such as /proc/version and the check set depends on it, that your architecture is one of X86_64, X86_32, ARM64, ARM or RISC-V, that ./bin/kernel-hardening-checker -h runs on your Python, which must be 3.9 or newer, and that the recommendations you disagree with are identifiable, which is what the -m verbose tag and provenance columns exist for. The project is GPL-3.0-only, mirrored on GitHub, Codeberg and SourceCraft, with the last push on 2026-09-19.

Frequently asked questions

What does kernel-hardening-checker actually check?

Three kinds of setting: compile-time Kconfig options, boot-time kernel command line arguments, and runtime sysctl parameters. It compares all three against a rule set based on KSPP, grsecurity, CLIP OS, GrapheneOS, SECURITY_LOCKDOWN_LSM and the CIS Benchmark.

How do I install kernel-hardening-checker?

With python3 -m pip install git+https://github.com/a13xp0p0v/kernel-hardening-checker, from a distribution package listed on repology, or by running ./bin/kernel-hardening-checker from a clone without installing anything. Python 3.9 or newer is required.

How do I check a remote host with kernel-hardening-checker?

Collect three files from the host, the kernel command line as /proc/cmdline, a sysctl dump made with sudo sysctl -a into a file, and the version from /proc/version, then run the checks with -l, -s and -v. The -c option takes a Kconfig file, including gzipped ones, for a kernel you built yourself.

Can I use kernel-hardening-checker in CI?

Yes. The json output mode exists for combining the tool with other tools, and the repository ships continuous integration on Woodpecker with separate functional test and engine unit test runs reported to Codecov. The README does not describe what the functional tests assert.

Which architectures does kernel-hardening-checker support?

X86_64, X86_32, ARM64, ARM and RISC-V. The -p flag prints the recommendations for a chosen architecture and -g generates a Kconfig fragment for it.

Will enabling every recommended option be safe?

The README warns that changing these parameters may affect system performance and the functionality of userspace software, and asks you to consider your threat model and test the typical workload. The tool reports what is off; it does not evaluate the cost of the change.

Official sources

  1. a13xp0p0v/kernel-hardening-checker on GitHub
  2. Issues
  3. License: GPL-3.0
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/a13xp0p0v-kernel-hardening-checker.svg)](https://hysenlabs.com/projects/a13xp0p0v-kernel-hardening-checker)