Forked from Underknowledge/fedora_v4l2loopback_and_signing.sh
Created
May 30, 2022 10:47
-
-
Save 2ndBillGates/3e0b9d78c31b7a8452b92e6ef44274e8 to your computer and use it in GitHub Desktop.
Install and sign v4l2loopback in 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
#!/usr/bin/env bash | |
build_dir="${build_dir:-/usr/src}" | |
tmp_dir="${tmp_dir:-/tmp}" | |
mokutil_out_dir="${mokutil_out_dir:-/root/.ssh/mokutil-module-signing}" | |
mokutil_509key_pass=$(cat "${mokutil_out_dir}"/.openssl_pass) | |
mokutil_509key_pass="${mokutil_509key_pass:-$(openssl rand -hex 6)}" | |
# https://github.com/umlaeute/v4l2loopback/issues/394 | |
# https://unix.stackexchange.com/questions/445772/how-to-add-a-public-key-into-system-keyring-for-kernel-without-recompile | |
# https://docs.fedoraproject.org/en-US/fedora/rawhide/system-administrators-guide/kernel-module-driver-configuration/Working_with_Kernel_Modules/#sect-signing-kernel-modules-for-secure-boot | |
# ToDo: | |
# pkg_check_cmd for gentoo | |
# cleanup of strange quoteing | |
source /etc/os-release || source /usr/lib/os-release | |
case ${ID,,} in | |
*suse*) pkg_mgr_cmd="zypper -n in"; sign_file_dir="/usr/src/linux-obj/x86_64/default/scripts" ;; | |
centos|rhel|fedora) pkg_mgr_cmd="dnf install -y"; pkg_check_cmd="rpm -qa" ;; | |
ubuntu|debian) pkg_mgr_cmd="apt-get install -y"; pkg_check_cmd="dpkg-query -l" ;; | |
# Gentoo needs to have version set since it's rolling | |
gentoo) pkg_mgr_cmd="emerge --jobs=4"; export VERSION="rolling" ;; | |
*) warn "unsupported distribution: ${ID,,}" ;; | |
esac | |
function info { echo -e "\e[32m[info] $*\e[39m"; } | |
function warn { echo -e "\e[33m[warn] $*\e[39m"; } | |
function error { echo -e "\e[31m[error] $*\e[39m"; exit 1; } | |
function check_install { ${pkg_check_cmd} "$*" | grep -q "$*" || ( ${pkg_mgr_cmd} "$*"; warn "you probably have to reboot" ; false ); } | |
check_install kernel-headers | |
check_install kernel-devel | |
command -v openssl > /dev/null 2>&1 || ( warn "missing openssl"; ${pkg_mgr_cmd} openssl ) | |
command -v jq > /dev/null 2>&1 || ( warn "missing jq"; ${pkg_mgr_cmd} jq ) | |
command -v curl > /dev/null 2>&1 || ( warn "missing curl"; ${pkg_mgr_cmd} curl ) | |
command -v mokutil > /dev/null 2>&1 || ( warn "missing mokutil" ; ${pkg_mgr_cmd} mokutil ) | |
Git_status=$(curl --silent -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/umlaeute/v4l2loopback/tags" ) | |
TAR_dl=$( echo "${Git_status}" | jq -r ".[].tarball_url" | head -n1) | |
TAR_v=$( echo "${Git_status}" | jq -r ".[].name" | head -n1) | |
function check_key () { | |
if [ -f "${mokutil_out_dir}"/MOK.priv ]; then | |
info "probing MOK.der" | |
if mokutil --test-key "${mokutil_out_dir}/MOK.der" | grep -q "already enrolled"; then | |
info "The Key is already trusted" | |
install_v4l2loopback | |
else | |
warn "info the key exist but is not trusted yet, reimporting it because it does not hurt. You missing a reboot?" | |
import_trust | |
fi | |
else | |
info "Generating keys to sign" | |
mokutil_setup | |
fi | |
} | |
function signing_ko () { | |
export KBUILD_SIGN_PIN="${mokutil_509key_pass}" | |
sign_file_dir="${sign_file_dir:-/usr/src/kernels/"$(uname -r)"/scripts}" | |
if [[ -f /lib/modules/"$(uname -r)"/extra/v4l2loopback.ko.xz || -f /lib/modules/"$(uname -r)"/extra/v4l2loopback.ko ]]; then | |
ko_folder="${ko_folder:-/lib/modules/$(uname -r)/extra}" | |
elif [[ -f /lib/modules/"$(uname -r)"/extra/v4l2loopback/v4l2loopback.ko.xz || -f /lib/modules/"$(uname -r)"/extra/v4l2loopback/v4l2loopback.ko ]]; then | |
ko_folder="${ko_folder:-/lib/modules/$(uname -r)/extra/v4l2loopback}" | |
else | |
warn "Can not locate the folder used for v4l2loopback.ko.xz to unxz and sign. Find the file and try to set the var 'ko_folder'" | |
fi | |
if [[ ! -f "${ko_folder}"/v4l2loopback.ko.xz || ! -f "${ko_folder}"/v4l2loopback.ko ]]; then | |
warn "there might be no file to sign. Please check ${ko_folder}" ; ko_folder="${ko_folder:-/lib/modules/$(uname -r)/extra}" | |
fi | |
info "Cert Password:" | |
info "$mokutil_509key_pass" | |
unxz -f "${ko_folder}/v4l2loopback.ko.xz" | |
${sign_file_dir}/sign-file sha256 "${mokutil_out_dir}/MOK.priv" "${mokutil_out_dir}/MOK.der" "${build_dir}/v4l2loopback.ko" && info "${build_dir}/v4l2loopback.ko" | |
${sign_file_dir}/sign-file sha256 "${mokutil_out_dir}/MOK.priv" "${mokutil_out_dir}/MOK.der" "${ko_folder}/v4l2loopback.ko" && info "${ko_folder}/v4l2loopback.ko" | |
xz -f "${ko_folder}/v4l2loopback.ko" | |
info "finished signing_ko" | |
} | |
function mokutil_setup () { | |
if [ ! -f "${mokutil_out_dir}"/MOK.priv ]; then | |
info "Still no Private key found, Generating one" | |
mkdir -p "${mokutil_out_dir}" | |
name="$(hostname)_signing_key" | |
echo "${mokutil_509key_pass}" > "${mokutil_out_dir}/.openssl_pass" | |
openssl \ | |
req -new -x509 \ | |
-passin pass:"${mokutil_509key_pass}" \ | |
-passout pass:"${mokutil_509key_pass}" \ | |
-newkey rsa:2048 \ | |
-keyout "${mokutil_out_dir}/MOK.priv" \ | |
-outform DER \ | |
-out "${mokutil_out_dir}/MOK.der" \ | |
-days 31500 \ | |
-subj "/CN=${name}/" \ | |
-addext "extendedKeyUsage=codeSigning" || error "issue creating cert" | |
openssl x509 -inform der -in "${mokutil_out_dir}"/MOK.der -out "${mokutil_out_dir}"/MOK.pem | |
mkdir -p /usr/src/kernels/"$(uname -r)"/certs/ | |
cat "${mokutil_out_dir}"/MOK.pem > /usr/src/kernels/"$(uname -r)"/certs/signing_key.pem | |
# cp "${mokutil_out_dir}"/MOK.der /usr/src/kernels/"$(uname -r)"/certs/signing_key.pem | |
chmod 600 "${mokutil_out_dir}"/MOK* | |
chmod 600 "${mokutil_out_dir}"/.openssl_pass | |
echo "The pasword for the x509 cert is: ${mokutil_509key_pass}" | |
import_trust | |
else | |
echo "Private key already present" | |
fi | |
info "finished mokutil_setup" | |
} | |
function import_trust () { | |
info "Enroling new cert" | |
warn "Set a one-time import password, Make it memorablel, you have to type it into later" | |
warn "for a example check https://gist.github.com/reillysiemens/ac6bea1e6c7684d62f544bd79b2182a4" | |
mokutil --import "${mokutil_out_dir}"/MOK.der | |
info "A Key has been generated and importet into mokutil" | |
mokutil --list-new | |
info "Now reboot your machine and import the certificate with the just typed password" | |
exit 0 | |
info "finished import_trust" | |
} | |
function install_v4l2loopback () { | |
info "start install_v4l2loopback" | |
curl -SL "${TAR_dl}" -o "${tmp_dir}"/v4l2loopback_"${TAR_v}".tar.gz | |
mkdir -p "${build_dir}" | |
tar xfv "${tmp_dir}"/v4l2loopback_"${TAR_v}".tar.gz --directory="${build_dir}" | |
mv "${build_dir}"/umlaeute-v4l2loopback-*/* "${build_dir}"/. | |
rm -r "${build_dir}"/umlaeute-v4l2loopback-* | |
pushd "${build_dir}" || exit | |
make clean | |
make || build_failed | |
mkdir -p /usr/src/kernels/"$(uname -r)"/certs/ | |
if [[ -z "$skip_signing" ]]; then | |
info "Cert Password:" | |
info "$mokutil_509key_pass" | |
export KBUILD_SIGN_PIN="${mokutil_509key_pass}" | |
cp "${mokutil_out_dir}"/MOK.pem /usr/src/kernels/"$(uname -r)"/certs/signing_key.pem | |
chmod 444 /usr/src/kernels/"$(uname -r)"/certs/signing_key.pem | |
# info "stat file" | |
# stat /usr/src/kernels/"$(uname -r)"/certs/signing_key.pem | |
fi | |
make install | |
ls /lib/modules/"$(uname -r)"/extra/ | |
if [[ -z "$skip_signing" ]]; then | |
info "Now Manually singing" | |
signing_ko | |
fi | |
ls -lah /usr/src/kernels/"$(uname -r)"/certs/ | |
popd || return | |
depmod -a | |
modprobe v4l2loopback | |
modinfo v4l2loopback | |
info "finished install_v4l2loopback" | |
lsmod | grep -q v4l2loopback && info "v4l2loopback loaded!" | |
} | |
function slr_as_webcam () { | |
# https://medium.com/nerdery/dslr-webcam-setup-for-linux-9b6d1b79ae22 | |
command -v ffmpeg > /dev/null 2>&1 || ( warn "missing ffmpeg"; ${pkg_mgr_cmd} ffmpeg ) | |
command -v gphoto2 > /dev/null 2>&1 || ( warn "missing gphoto2" ; ${pkg_mgr_cmd} gphoto2 ) | |
# Best formats | |
# https://stackoverflow.com/a/59574988 | |
warn "quick 5s test" | |
timeout 5 gphoto2 --stdout --capture-movie | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -threads 0 -f v4l2 "$(v4l2-ctl --list-devices | grep v4l2loopback -A 1 | grep -oe "/dev/video.*" | head -n 1)" | |
# https://github.com/umlaeute/v4l2loopback/issues/391#issuecomment-800941494 | |
echo "v4l2loopback" > /etc/modules-load.d/v4l2loopback.conf | |
cat << EOF > /etc/modprobe.d/v4l2loopback.conf | |
# Module options for v4l2loopback | |
options v4l2loopback exclusive_caps=1 | |
options v4l2loopback devices=2 | |
options v4l2loopback max_buffers=2 | |
options v4l2loopback video_nr=101,102 | |
options v4l2loopback card_label="obs,slr" | |
EOF | |
info "Config to Automaticaly load Kernel module added" | |
} | |
function build_failed () { | |
echo " | |
When you see | |
*** No rule to make target 'clean'. Stop. | |
Probably kernel-headers and kernel do not have the same version… Install, reboot and try again! | |
otherwise you could try running 'dnf donwgrade gcc' https://ask.fedoraproject.org/t/fedora-34-beta-and-oot-kmod-nvidia-virtualbox-v4l2loopback-etc/12778 | |
" | |
} | |
function help () { | |
echo " | |
just run the script, reboot (you will have to type a pass you set) and run again! | |
you can also run '$0 slr_as_webcam' to install tools you need to use a dslr as webcam | |
" | |
} | |
if [ "$EUID" -ne 0 ] | |
then error "Please run as root" | |
else | |
if [ "$#" -eq "1" ] | |
then | |
$1 | |
exit 0 | |
else | |
if mokutil --sb-state | grep -q "SecureBoot enabled"; then | |
info "Secure boot is enabled and you have to setup singing" | |
check_key | |
else | |
warn "no need to sing Stuff!" | |
export skip_signing=1 | |
grep -q "v4l2loopback" /proc/modules || install_v4l2loopback | |
fi | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment