-
-
Save xenithorb/df08970b9e70bb3c6576e1fd91460afe to your computer and use it in GitHub Desktop.
#!/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 |
@xenithorb Could you please attach a license to this code?
It's not necessary to poll the akmods
process using pgrep
like this. Since the background akmods
is started as a systemd service (see /usr/lib/kernel/install.d/95-akmodsposttrans.install
), we can just install an drop-in config for that service that adds an additional ExecStart
. See e.g. https://github.com/larsks/akmod-sign-modules for one way of implementing this.
It's not necessary to poll the
akmods
process usingpgrep
like this. Since the backgroundakmods
is started as a systemd service (see/usr/lib/kernel/install.d/95-akmodsposttrans.install
), we can just install an drop-in config for that service that adds an additionalExecStart
. See e.g. https://github.com/larsks/akmod-sign-modules for one way of implementing this.
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.
@xenithorb Could you please attach a license to this code?
Certainly, let me do the above and then I'll republish it with an MIT most likely.
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.
Thank you very much! For everyone who is coming here: The script still works for Fedora 32 :)