Last active
November 16, 2021 07:49
-
-
Save xenithorb/df08970b9e70bb3c6576e1fd91460afe to your computer and use it in GitHub Desktop.
Akmod kernel module auto-signer for kernel upgrades on Fedora
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# /etc/kernel/postinst.d script to sign akmods kmods after kernel upgrade | |
# | |
# Author: Michael Goodwin Date: 2016-09-21 | |
# 1. Copy this script to /etc/kernel/postinst.d/ and `chmod +x` it | |
# | |
# 2. Create signing keys (store these somewhere useful and safe): | |
# $ mkdir -p /etc/pki/tls/private/mok | |
# $ cd !$ | |
# $ openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv \ | |
# -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=Descriptive name/" | |
# | |
# 3. Replace PRIVATE_KEY and CERTIFICATE variables below with the | |
# key/cert paths from above. (Unless you kept the same paths) | |
# | |
# 4. Run the script as root to do a first-sign of the modules | |
# | |
# 5. Import the new certificate into MOK (one time thing): | |
# $ sudo mokutil --import MOK.der | |
# | |
# 6. Reboot and follow the instructions to authorize the key: | |
# https://sourceware.org/systemtap/wiki/SecureBoot | |
# | |
#set -x | |
KMOD_RPM_DIR=/var/cache/akmods | |
KERNEL_VER="${1:-$(ls -1 /usr/lib/modules | sort -V | tail -n1)}" | |
SIGN_SCRIPT="/usr/src/kernels/${KERNEL_VER}/scripts/sign-file" | |
PRIVATE_KEY=/etc/pki/tls/private/mok/MOK.priv | |
CERTIFICATE=/etc/pki/tls/private/mok/MOK.der | |
( | |
# Wait on backgrounded akmods build and install to finish | |
count= | |
while pgrep -f -- '/usr/sbin/akmods --from-kernel-posttrans' >/dev/null; do | |
sleep 1 | |
(( count++ )) | |
(( count >= 300 )) && exit | |
done | |
# Find all kernel modules packaged by akmods | |
get_ko_array() { | |
readarray -t kmod_ko_array < <( | |
find "${KMOD_RPM_DIR}" -name "*${KERNEL_VER}*.rpm" -exec sh -c 'rpm -qlp "{}" | grep ".ko$"' \; | |
) | |
} | |
# Build the modules if we don't find anyway | |
get_ko_array | |
if [[ ! $kmod_ko_array ]]; then | |
akmods --kernels "${KERNEL_VER}" && | |
get_ko_array | |
fi | |
# Sign all the modules from akmods | |
for ((i=0; i<${#kmod_ko_array[@]}; i++)); do | |
if ! strings "${kmod_ko_array[i]}" | tail -n1 | grep -q '~Module signature appended~'; then | |
"$SIGN_SCRIPT" sha256 "$PRIVATE_KEY" "$CERTIFICATE" "${kmod_ko_array[i]}" | |
fi | |
# uncomment this to strip the cert | |
# strip --strip-debug "${kmod_ko_array[i]}" | |
done | |
)& | |
wait; exit 0 |
This script does not work as expected in fedora 34. It only signs modules correctly if run manually. If run automatically from postinst.d here's what happens: the script is run right after new kernel is installed, but before dnf exits. Because of this akmod build does not even start because it is only started by systemd-inhibit after dnf transaction is fully finished. So this script just waits for 5 minutes for nothing and then does nothing, because all akmod modules will be installed only after this script and dnf finish execution.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Fair point! This is obviously quite old and was from when I had a discrete NVIDIA GPU. Well, as it turns out, my shiny new laptop now has one once again after a few years of being AMD-only (for this very reason). So, I might have to polish this up and see if it still works.
Certainly, let me do the above and then I'll republish it with an MIT most likely.