This one is a just-works work in progress. It will end up in GitHub when I feel it's OK, but worth sharing.
It is based on
this Gist by
Reilly Tucker Siemens.
Signs kernel modules with your Machine Owner Key. If you use Secure Boot with your Linux installation, you will need to do this for any module not included in the official update repositories
every time you update the Kernel. Examples are plenty: NVIDIA and VirtualBox modules,
v4l2loopback
, and many other.
It works in Fedora, and some changes needed for Debian, as per the under-the-hood fragmentation. Details in the comments.
The usage is
sudo ./signmodule.sh [path-to]/MOK.priv [path-to]/MOK.der module
In case of modules coming with dependencies, it will sign all modules in the directory of the module to sign. This is the case, for example, of VirtualBox;
vboxdrv
is the sort of main module, but comes with a handful more of them.
Before finishing:
- It will restart the service
systemd-modules-load
, which may be failing when this script needs to be run, and this should insert the newly signed modules for the current session and all reboots until the next kernel update.
- It will tell you which else systemd services you need to restart, in case of any of them depending on the modules you just signed and loaded. This is an obvious example of what can be improved: parse the list in the output of the
systemctl list-unit --failed
and restart them before exiting.
It doesn't check parameters or observe any extra decency other than the necessary to do the work.
Bash:
#!/bin/sh
readonly hash_algo='sha256'
readonly key="$1" # 'MOK.priv'
readonly x509="$2" # 'MOK.der'
readonly module="$3" # The name of the module (no extensions)
readonly name="$(basename $0)"
readonly fullver=$(uname -r)
log() { local string="${1}"; echo "[$name] ${string}"; }
# The exact location of `sign-file` might vary depending on your platform.
# This is for Fedora
alias sign-file="/usr/src/kernels/${fullver}/scripts/sign-file"
[ -z "${KBUILD_SIGN_PIN}" ] && read -p "Passphrase for ${key}: " KBUILD_SIGN_PIN
export KBUILD_SIGN_PIN
# In Fedora, modinfo is in the PATH for root users. In other
# distributions it may not, and may be located at either /sbin
# or /usr/sbin
# Another difference is whether your distribution compresses the
# modules (.ko.xz) or not (just .ko).
for mod in $(dirname $(modinfo -n $module))/*.ko.xz; do
log "Unpacking ${mod}..."
unxz ${mod}
mod_basename=${mod:0:-3}
log "Signing ${mod_basename}..."
sign-file "${hash_algo}" "${key}" "${x509}" "${mod_basename}"
log "Recompressing ${mod_basename}"
xz -f ${mod_basename}
done
systemctl restart systemd-modules-load
log "-------------------------------------------------------------------------------"
log "Restart the following units (if any shown) with 'systemctl restart <unitname>':"
systemctl list-units --state failed
log "------------------------------------DONE---------------------------------------"