Library / SDK
dkms-project/dkms avatar
dkms-project/dkms

DKMS: keeping out-of-tree kernel modules across kernel upgrades

Dynamic Kernel Module System

874 stars186 forksShellGPL-2.0

At a glance

What is it?
DKMS is the shell-driven framework that rebuilds out-of-tree Linux kernel modules whenever the kernel changes, and this repository documents how it consumes tarballs carrying a dkms.conf file, how it signs modules for Secure Boot, and how its Makefile templates produce the dkms command. The README is explicit that distribution packages are not built here.
Who is it for?
Use DKMS when you depend on out-of-tree kernel modules and want them rebuilt automatically across kernel upgrades, and follow the tarball path in the README when a vendor ships a dkms.conf you can load.
Can I use it commercially?
Yes, with conditions. GPL-2.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 1 day ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

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

Editorial analysis

A rebuild framework for modules the kernel does not ship

DKMS is the Dynamic Kernel Module System, and the problem it solves is narrow and durable. A module built for one kernel cannot be loaded by the next one, so an out-of-tree module needs to be recompiled every time the kernel package is replaced, and that is a step nobody wants to remember on a machine that updates kernels without asking.

DKMS takes that step over. It keeps the module source and a dkms.conf description in a known location, and rebuilds and reinstalls the module against whatever kernel version is now running. The primary language of this repository is Shell, and the licence is GPL-2.0, with the COPYING file in the repository root.

The README here has a specific purpose, and it is worth saying so up front, because it changes what you will find here. Its stated intention is to explain how DKMS can be used in conjunction with tarballs which contain a dkms.conf file. In other words, this document is aimed at the vendor or administrator who has a module to distribute, not at a general user guide for the framework.

Maintenance is current. The last push was on 2026-10-22, the repository is not archived, and the releases are v3.4.2 on 2026-07-20, v3.4.3 on 2026-08-16 and v3.4.4 on 2026-10-05, with the Makefile carrying the release string dkms-3.4.4 and the date 05 Oct 2026.

make install is the whole source install, and the paths are fixed

Installation from this source tree is three possible commands, and the README gives no longer form of it:

bash
make install
make install-debian
make install-redhat

The choice is about the packaging conventions of the distribution, since the generic target installs to fixed locations that the other two adapt. Whatever you pick, the README is blunt about the limit of this repository: distribution specific installations (RPM, DEB, etc.) are not contained in this source repository. If your distribution already ships a DKMS package, this tree is the wrong place to get one from, and the packaged version is the one that will match your distribution's own kernel handling.

The Makefile explains the rest. It is a template build rather than a hand-written install script, with every generated file produced from a .in source by a sed substitution pass:

bash
SBIN = /usr/sbin
LIBDIR = /usr/lib/dkms
MODDIR = /lib/modules
KCONF = /etc/kernel
KINSTALL = /usr/lib/kernel/install.d
SYSTEMD = /usr/lib/systemd/system

Those six variables are the whole address space of the tool, and they explain most of what the framework touches on a running system: the dkms command itself in /usr/sbin, its library directory under /usr/lib/dkms, module trees under /lib/modules, kernel configuration under /etc/kernel, the kernel install hook directory at /usr/lib/kernel/install.d, and a systemd unit directory.

The install target also encodes a policy decision worth noting before you package it. Setting VAR or ETC is rejected outright with an error, and using a DESTDIR as a prefix for SBIN, LIBDIR or KCONF is reported as no longer supported. The install rules write dkms into the sbin directory and dkms_framework.conf into /etc/dkms/framework.conf, so the tool lands on a fixed, known set of paths rather than a configurable prefix.

Four kinds of tarball, and one command that loads them

The README's core contribution is the tarball taxonomy, and it matters because the four cases need different amounts of trust and different amounts of local tooling.

The list starts with generic module source tarballs which contain a dkms.conf file, then adds specially created tarballs with module source, pre-built module binaries and a dkms.conf file, then tarballs with pre-built module binaries and a dkms.conf file alone, and finally the option of manual placement of module source and the dkms.conf file into the /usr/src/<module>-<moduleversion>/ directory.

The single entry point for all of that is one command:

bash
# dkms ldtarball /path/to/dkms_enabled.tar.gz

The command first inspects the archive to ensure that it contains a dkms.conf configuration file for that module, and if it cannot find that file anywhere within the archive, the ldtarball command fails. It then places the source from the tarball into /usr/src/<module>-<moduleversion>/, and it will not overwrite existing source there unless the --force option is specified.

The tarballs that carry pre-built binaries are handled with care. For the type that has binaries but no source, loading only continues if existing module source is found in that directory or if --force is given. For the two types that include binaries, the binaries are loaded into the DKMS tree but installation stops short: they end up in the built state when checked with dkms status, and dkms install is the separate step that installs them.

The tarball side has a creation command too. A tarball of the first type only needs module source and a dkms.conf file zipped together. Types two and three are produced with the dkms mktarball command, and a type three tarball, binaries only, additionally needs the --binaries-only flag.

Binary-only tarballs work without a compiler, and then stop working

There is a case where the machine has no module source and no compiler, and the README treats it directly. DKMS can still be used to install modules, through the binary only tarballs it calls type c. Without source, the normal load would fail, so the documented workaround is the force flag:

bash
# dkms ldtarball /path/to/dkms_enabled.tar.gz --force

That loads the pre-built binaries into the DKMS tree and creates the /usr/src/<module>-<moduleversion>/ directory containing only the module's dkms.conf configuration file. The README then states the limitation plainly: since the module source will not be located in your DKMS tree, you will not be able to build any modules with DKMS for this package.

That is the trade-off in its clearest form. A binary-only tarball lets you install a module on a machine that cannot compile one, and it also means that when the kernel changes, there is no source for the framework to rebuild from, so the module is good for the kernel it was built for and no further. A vendor who ships type three tarballs has decided that the target machines are fixed, or that a new package will be provided for the next kernel.

The failure mode is quiet rather than loud. Nothing in the framework's tree tells you that the package is now unbuildable, and the check to run is whether the source directory for the module still holds real source.

Self-signed MOK keys in /var/lib/dkms, overridable in framework.conf

Module signing is where most of the operational risk of a kernel module lives, and DKMS handles it with a Machine Owner Key that it generates for you.

By default, DKMS generates a self signed certificate for signing modules at build time and signs every module that it builds before it gets compressed in the configured kernel compression mechanism of choice. The private key and certificate are auto generated the first time DKMS is run and placed in /var/lib/dkms, and the README notes that these certificate files can be pre-populated with your own certificates of choice.

The location and the files can be changed through variables in /etc/dkms/framework.conf. The example given is for a system using the default Ubuntu update-secureboot-policy, which points DKMS at the machine owner key that the shim already trusts:

bash
mok_signing_key="/var/lib/shim-signed/mok/MOK.priv"
mok_certificate="/var/lib/shim-signed/mok/MOK.der"

Two details in that mechanism are easy to miss. The paths can use the variable ${kernelver} to represent the target kernel version, which matters for a key that has to be found per kernel tree, and the same substitution is available for sign_file, which the README shows pointing at the kernel's own signing helper:

bash
sign_file="/lib/modules/${kernelver}/build/scripts/sign-file"

The mok_signing_key can also be a pkcs11:... string for a PKCS#11 engine, as long as the sign_file program supports it, which moves a signing key into a hardware or token store. One more note: if any of the files specified by mok_signing_key, mok_certificate and sign_file are non-existent, DKMS will re-create both files, so a typo in a path produces a fresh self-signed key rather than an error.

Secure Boot enrolment, and the openssl version that breaks old keys

On a UEFI system with Secure Boot enabled, a module has to be signed and the firmware has to know the right public certificate. The README walks through the whole path from checking the state to enrolling the key.

The state check is a single command:

bash
# mokutil --sb-state
SecureBoot enabled

Enrolment then imports the public certificate that DKMS generated, and the README requires mokutil to be installed for that step:

bash
# mokutil --import /var/lib/dkms/mok.pub

You are prompted to create a password, which can be blank, and after a reboot the MOK Manager EFI interface appears, where you press a key, select Enroll MOK, then Continue, and confirm with Yes when asked. The README includes screenshots of each of those four screens.

There is a sharper edge in the signing rules, and it is the one to check on an existing installation. If the kernel is patched and compiled with CONFIG_CHECK_CODESIGN_EKU, the operating system validates the extendedKeyUsage field of the certificate, and the specification quoted in the README requires that certificates used for trusted updates and executable code integrity verification carry the Code Signing purpose. Since DKMS 3.1.7 the MOK self signed certificate is generated with the extendedKeyUsage set to codeSigning, which requires version 1.1.1 or newer of the openssl command on the system.

If you are upgrading from a DKMS version before 3.1.7 and your kernel enforces that check, the keys have to be regenerated, and the README gives the exact sequence:

bash
# rm -fr /var/lib/dkms/mok.{key,pub}
# dkms generate_mok
Signing key: /var/lib/dkms/mok.key
Public certificate (MOK): /var/lib/dkms/mok.pub

The trap is the enrolment step that follows. A regenerated certificate is a new key, so the new public certificate has to be enrolled again through mokutil, otherwise the firmware still trusts the old one and modules signed with the new key will be rejected.

Kernel install hooks decide when a rebuild is triggered

The top-level directory shows how the rebuild is wired into the system rather than run by hand. It contains dkms.in, the man page dkms.8.in, dkms.service.in for systemd, dkms.bash-completion.in and dkms.zsh-completion.in for shell completion, dkms_autoinstaller.in, dkms_common.postinst.in and dkms_framework.conf.in, all of them templates that the Makefile fills in.

The kernel-specific integration comes from the hook scripts, debian_kernel_install.d.in, debian_kernel_postinst.d.in, debian_kernel_preinst.d.in, debian_kernel_prerm.d.in and redhat_kernel_install.d.in. Those names describe the two distribution families the framework supports, and they install into the KINSTALL path, /usr/lib/kernel/install.d, which is where a kernel package looks for the scripts it should run when a new kernel is installed. That is the mechanism behind the promise of a rebuild across kernel upgrades, and it is why the generic make install target is not the whole story for a distribution integration.

The rest of the tree supports development rather than runtime. There is a test/ directory and a run_test.sh, and a TESTING_CHANGES.md that documents how the test setup changes, which suggests the project's own guidance for contributors is to read that file before touching the tests. dkms_apport.py is the only Python file in a Shell project, and the name points at reporting module load failures through the distribution's crash reporting mechanism.

The remaining files are ordinary hygiene: an .editorconfig for consistent whitespace across contributors, a .gitignore, an images/ directory for the MOK Manager screenshots, and the .github/ directory that holds the workflows for the build and release tags.

Editorial conclusion

Use DKMS when you depend on out-of-tree kernel modules and want them rebuilt automatically across kernel upgrades, and follow the tarball path in the README when a vendor ships a dkms.conf you can load. Do not build it from this repository on a distribution that already packages DKMS for you, because the README states that distribution specific installations are not contained in the source tree, and do not expect a binary-only tarball to keep working for future kernels, since the README states the module source will not be in your DKMS tree and nothing can be built from it. Before you rely on it, check that openssl 1.1.1 or newer is present if your kernel validates the code signing extended key usage, and confirm that the MOK certificate in /var/lib/dkms is the one your firmware trusts.

Frequently asked questions

How do I install DKMS from source?

The README gives three commands run from the source directory: make install, make install-debian, and make install-redhat. It also states that distribution specific installations such as RPM and DEB packages are not contained in this source repository, so a packaged DKMS comes from your distribution instead.

How do I load a DKMS tarball into the DKMS tree?

Use dkms ldtarball with the path to the archive. The command inspects the tarball for a dkms.conf file and fails if it is missing, then places the source in /usr/src/<module>-<moduleversion>/ without overwriting what is already there unless --force is given.

How does DKMS sign modules for Secure Boot?

By default DKMS generates a self signed certificate at build time and signs every module it builds, with the key and certificate auto generated in /var/lib/dkms on first run. The paths can be changed with mok_signing_key and mok_certificate in /etc/dkms/framework.conf, and the certificate is enrolled with mokutil --import followed by a reboot into the MOK Manager.

Why does DKMS need openssl 1.1.1 or newer?

Since DKMS 3.1.7 the MOK self signed certificate is generated with the extendedKeyUsage set to codeSigning, which that openssl version or newer is required to produce. If your kernel was compiled with CONFIG_CHECK_CODESIGN_EKU and you have keys from an earlier DKMS version, the README shows how to remove /var/lib/dkms/mok.{key,pub} and run dkms generate_mok to regenerate them.

Official sources

  1. dkms-project/dkms on GitHub
  2. Issues
  3. License: GPL-2.0
  4. README
  5. Releases
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/dkms-project-dkms.svg)](https://hysenlabs.com/projects/dkms-project-dkms)

Was this useful?