On systems with UEFI Secure Boot enabled, recent Linux kernels will only load signed modules, so it's about time DKMS grew the capability to sign modules it's building.
These scripts are extended and scriptified variants of https://computerlinguist.org/make-dkms-sign-kernel-modules-for-secure-boot-on-ubuntu-1604.html and https://askubuntu.com/questions/760671/could-not-load-vboxdrv-after-upgrade-to-ubuntu-16-04-and-i-want-to-keep-secur/768310#768310 and add some error checking, a passphrase around your signing key, and support for compressed modules.
dkms-sign-module
is a wrapper for the more generic sign-modules
which can also be used outside of DKMS.
- Create a directory under
/root
, say/root/module-signing
, put the three scripts below in there and make them executable:chmod u+x one-time-setup sign-modules dkms-sign-module
- Run
one-time-setup
- Reboot your computer to deploy the MOK
- For each module you will want to sign via DKMS, create a file
/etc/dkms/<module_name>.conf
with the following content:
The awkward relative pathname is important since DKMS prepends its own path to it, so an absolute path will not work.POST_BUILD=../../../../../../root/module-signing/dkms-sign-module
I am using the following for my
/etc/dkms/<module_name>.conf
file, which removes the need fordkms-sign-module
:I made this change because I found
dkms autoinstall
provides neither$kernelver
nor$arch
to thedkms-sign-module
script. Instead, I had to usedkms install <module>/<version>
(ordkms build <module>/<version>
) in order to get those values, making automation further up the stack more difficult.The root cause can be found in the
dkms
binary and the problem is outlined below:When running
dkms build …
, the script ends up callingmaybe_build_module()
, which sets the two variables ($kernelver
&$arch
), along with$module
&$module_version
, in a global scope before it callsbuild_module
and, similarly,maybe_install_module
sets the 4 variables before it callsinstall_module
(which, itself, callsbuild_module
as needed). This means that all 4 variables are available to thePOST_BUILD
script.However, when
autoinstall()
callsinstall_module
(and the implicitbuild_module
, as needed), it only sets$module
&$module_version
in the global scope. For$kernelver
&$arch
, it relies on the already defined values, which were previously declared in a local scope; as such, they are not passed on to thePOST_BUILD
script.