Skip to content

Instantly share code, notes, and snippets.

@Era-Dorta
Last active April 16, 2024 08:10
Show Gist options
  • Star 65 You must be signed in to star a gist
  • Fork 16 You must be signed in to fork a gist
  • Save Era-Dorta/74a0040f50ae7987885a0bebe5eda1aa to your computer and use it in GitHub Desktop.
Save Era-Dorta/74a0040f50ae7987885a0bebe5eda1aa to your computer and use it in GitHub Desktop.
Sign kernel modules on Ubuntu, useful for Nvidia drivers in UEFI system
# VERY IMPORTANT! After each kernel update or dkms rebuild the modules must be signed again with the script
# ~/.ssl/sign-all-modules.sh
# Place all files in ~/.ssl folder
mkdir ~/.ssl
cd ~/.ssl
# Generate custom keys with openssl
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -subj "/CN=Owner/"
# Set more restrictive permisions as these are private keys
chmod 600 MOK.*
# Add the sign-all-modules script to the .ssl folder
cat <<EOT > sign-all-modules.sh
#!/bin/bash
sudo -v
echo "Signing the following modules"
for filename in /lib/modules/\$(uname -r)/updates/dkms/*.ko; do
sudo /usr/src/linux-headers-\$(uname -r)/scripts/sign-file sha256 ~/.ssl/MOK.priv ~/.ssl/MOK.der \$filename
echo "\$filename"
done
EOT
chmod +x ~/.ssl/sign-all-modules.sh
#Run the script
~/.ssl/sign-all-modules.sh
#Add the key to the trusted keys database
sudo apt-get install mokutil
sudo mokutil --import ~/.ssl/MOK.der
cd ~
#Reboot and in the boot screen select add/import key
@halfelf
Copy link

halfelf commented Jul 7, 2017

Very helpful. Thanks.

For anyone installing nvidia driver from commandline without apt, the NVIDIA-Linux-x86_64-xxx.xx.run binary can generate key pairs for you, in /usr/shared/nvidia, with sha512 algorithm. Though this binary also do the signing part, it won't add the keys to database, which causes driver install failed.

After the failed installing, manually exec the mokutil part in this gist. Follow the instructions here after reboot.

@troth
Copy link

troth commented Nov 18, 2017

Lines 15-26 are a bit broken. They should look like this instead:

cat <<EOT > sign-all-modules.sh
#!/bin/bash

sudo -v

echo "Signing the following modules"

for filename in /lib/modules/\$(uname -r)/updates/dkms/*.ko; do
    sudo /usr/src/linux-headers-\$(uname -r)/scripts/sign-file sha256 ~/.ssl/MOK.priv ~/.ssl/MOK.der \$filename

    echo "\$filename"
done

If you run your version more than once, then sign-all-modules.sh will be appended to instead of over written.

If you don't escape the $ as \$ then when you run the create script, the shell will expand the variables and the written file will have no $ in it. The generated sign script looked like this when run on my system:

#!/bin/bash

sudo -v

echo "Signing the following modules"

for filename in /lib/modules/4.4.0-98-generic/updates/dkms/*.ko; do
    sudo /usr/src/linux-headers-4.4.0-98-generic/scripts/sign-file sha256 ~/.ssl/MOK.priv ~/.ssl/MOK.der 

    echo ""
done

which is not the intended output and will not work when used to sign the kernel modules.

@Era-Dorta
Copy link
Author

Thanks for the fix @troth, I've updated the script with your changes.

@derek-shnosh
Copy link

derek-shnosh commented Feb 22, 2018

For what it's worth, the cat function wasn't working for me, and I'm relatively new to all of this so I just created the file in nano and pasted the script without the \.

nano ~/.ssl/sign-all-modules.sh

Pasted script, wrote it out.

#!/bin/bash

sudo -v

echo "Signing the following modules"

for filename in /lib/modules/$(uname -r)/updates/dkms/*.ko; do
    sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ~/.ssl/MOK.priv ~/.ssl/MOK.der $filename

    echo "$filename"
done

chmod +x ~/.ssl/sign-all-modules.sh

@boospy
Copy link

boospy commented Oct 1, 2018

Since last kernelupdate on Ubuntu 18.04 it didn't work anymore...

Signing the following modules
At main.c:291:
- SSL error:02001002:system library:fopen:No such file or directory: ../crypto/bio/bss_file.c:74
- SSL error:2006D080:BIO routines:BIO_new_file:no such file: ../crypto/bio/bss_file.c:81
sign-file: /lib/modules/4.15.0-36-generic/updates/dkms/*.ko: No such file or directory
/lib/modules/4.15.0-36-generic/updates/dkms/*.ko

Maybe you have an idea?

@Era-Dorta
Copy link
Author

@boospy, it looks like the script didn't find any .ko files to sign. The location for them is still the same on Ubuntu 18.04. Maybe the nvidia drivers were not installed for that particular kernel. Note that the script tries to sign the files for the kernel that is running at the moment, not the most recent one. So most of the times, you'd need to reboot twice, once to get into the most recent kernel and sign the modules there and another to boot with the signed modules. Let me know if that helps.

@boospy
Copy link

boospy commented Dec 27, 2018

Hello @Garoe, sorry for the late answer, didn't get an notification from github. So the problem exists. Strange, i've installed only one kernel. And nvidiadrivers are installed and loaded. I had a lot of kernelupdates in the past, and never had a probem with your script, it was working fine a long time :) maybe i can set some paths.... or other options to solve the problem?

@Era-Dorta
Copy link
Author

Try running locate nvidia_*.ko, where you substitute the * with the nvidia driver version that you have installed, for example locate nvidia_387.ko. That should tell you where the modules are located, then all you need to do is, to substitute the path in line 22 (line 6 on the sign-all-modules.sh file) with your path.

P.S. I use https://giscus.co/ to get email notifications for gist comments.

@boospy
Copy link

boospy commented Feb 9, 2019

I've changed the path in the script, not it is working again:

#!/bin/bash

sudo -v

echo "Signing the following modules"

for filename in /lib/modules/$(uname -r)/updates/*.ko; do
    sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ~/.ssl/MOK.priv ~/.ssl/MOK.der $filename

    echo "$filename"
done

for filename in /lib/modules/$(uname -r)/kernel/drivers/char/drm/*.ko; do
    sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ~/.ssl/MOK.priv ~/.ssl/MOK.der $filename

    echo "$filename"
done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment