Last active
May 25, 2024 14:49
-
-
Save amaksoft/2495d0bf4df406793b5082ebb6d4aa4d to your computer and use it in GitHub Desktop.
Virtualbox and VMware modules signing for Fedora
This file contains hidden or 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 | |
# | |
# Inspired by: | |
# http://gorka.eguileor.com/vbox-vmware-in-secureboot-linux-2016-update/ | |
# http://elemc.name/?p=1020 | |
# | |
# Designed and tested on Fedora 24/25 | |
# | |
# This script is designed to automate Virtualbox and VMware module signing for SecureBoot | |
# Run it after each "vmware-modconfig --console --install-all", "/sbin/rcvboxdrv setup", "sudo /etc/init.d/vboxdrv setup" or kernel update | |
# | |
# Step 1. Generate a certificate: | |
# | |
# $ sudo mkdir /etc/pki/my-secureboot | |
# $ cd /etc/pki/my-secureboot | |
# $ sudo openssl req -new -x509 -newkey rsa:4096 -keyout private_key.priv -outform DER -out public_key.der -nodes -days 36500 -subj "/CN=MySecureBoot/" | |
# | |
# Or use Fedora manual https://docs.fedoraproject.org/en-US/Fedora/25/html/System_Administrators_Guide/sect-generating-a-public-private-x509-key-pair.html | |
# | |
# Step 2. Install certificate: | |
# | |
# $ sudo mokutil --import public_key.der | |
# | |
# Step 3a. Reboot after installing certificate and enter the password you set in previous step | |
# | |
# $ sudo reboot | |
# | |
# Step 3b. Check if certificates are loaded | |
# | |
# $ dmesg | grep 'EFI: Loaded cert' | |
# | |
# Step 4. Get and run this script | |
# | |
# $ sudo wget https://gist.github.com/amaksoft/2495d0bf4df406793b5082ebb6d4aa4d/raw/f6b8ae4a8257ca721e263e68741e5df516309b66/70-sign-virtual.sh | |
# $ sudo chmod +x 70-sign-virtual.sh | |
# $ sudo ./70-sign-virtual.sh | |
# | |
# Step 5. Add to kernel postinstall scripts | |
# | |
# $ sudo mv 70-sign-virtual.sh /etc/kernel/postinst.d/ | |
########################### Settings ############################# | |
# Signing keys names (change if you name your keys differently) | |
KEYS="private_key.priv public_key.der" | |
# Signing keys location (change if you put your keys in different directory) | |
KEYS_DIR="/etc/pki/my-secureboot" | |
# Kernel modules names to check | |
# (We will sign every module located in the same directory with those) | |
MOD_NAMES="vboxdrv vmmon vmnet" | |
# Services to restart after signing modules | |
SERVICES="vboxdrv vmware" | |
############################# Code ############################## | |
ERROR_PREFIX="ERROR ($BASH_SOURCE:$LINENO)" | |
error () { | |
printf "\e[31m$ERROR_PREFIX\e[0m $2\n" | |
exit $1 | |
} | |
# Check if running as root (for manual run) | |
if [ "$EUID" -ne 0 ]; then | |
error 1 "Please run this script as root!"; | |
fi | |
# Get script directory | |
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"; | |
KCUR=$(uname -r) # Current kernel version | |
if [[ $SCRIPT_DIR == "/etc/kernel/postinst.d" ]] && [[ ! -z "${1// }" ]]; then | |
KINST=$1 | |
KVER=$KINST | |
echo "Running as postinstall script for kernel $KVER" | |
else | |
KVER=$KCUR | |
echo "Running manually for kernel $KVER" | |
fi | |
# Use script directory for keys if declared keys directory doesn't exist (for manual run) | |
if [ -d $KEYS_DIR ]; then | |
DIR=$KEYS_DIR | |
else | |
DIR=$SCRIPT_DIR | |
fi | |
# Append directory to keys names | |
for k in $KEYS; do | |
KEYS_+="$DIR/$k " | |
done | |
KEYS=$KEYS_ | |
# Check if keys exist | |
for f in $KEYS; do | |
if [ ! -f $f ]; then | |
error 2 "$(basename $f) not found! \n Please generate keys and copy them in $KEYS_DIR or $SCRIPT_DIR."; | |
fi | |
done | |
# Get modules locations | |
for m in $MOD_NAMES; do | |
if modinfo -n $m > /dev/null 2>&1; then | |
M_DIR=$(dirname $(modinfo -n $m)) | |
if [[ $KCUR != $KVER ]]; then | |
M_DIR=${M_DIR/$KCUR/$KVER} | |
fi | |
for d in $MODULE_DIRS; do | |
if [[ $d == $M_DIR ]]; then | |
M_DIR="" | |
break | |
fi | |
done | |
MODULE_DIRS+="$M_DIR " | |
fi | |
done | |
if [[ -z "${MODULE_DIRS// }" ]]; then | |
error 3 "no modules found. Checked [$MOD_NAMES]"; | |
fi | |
# Sign modules | |
MOD_TO_SIGN=$(find $MODULE_DIRS -name '*.ko') | |
if [[ -z "${MOD_TO_SIGN// }" ]]; then | |
error 4 "no modules found in dirs $MODULE_DIRS"; | |
fi | |
for f in $MOD_TO_SIGN; do | |
echo "Signing $f"; | |
/usr/src/kernels/$KVER/scripts/sign-file sha256 $KEYS $f; | |
done | |
# Restart services | |
for serv in $SERVICES; do | |
MSG="Restart $serv service" | |
# check if service exists | |
if systemctl -t service -a | grep -Fq $serv; then | |
if systemctl restart $serv; then | |
echo "$MSG successful"; | |
else | |
error 5 "$MSG failed"; | |
fi | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment