Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

@halfelf 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

This comment has been minimized.

Copy link

@troth 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.

@Garoe

This comment has been minimized.

Copy link
Owner Author

@Garoe Garoe commented Nov 19, 2017

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

@derek-shnosh

This comment has been minimized.

Copy link

@derek-shnosh 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

This comment has been minimized.

Copy link

@boospy 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?

@Garoe

This comment has been minimized.

Copy link
Owner Author

@Garoe Garoe commented Oct 2, 2018

@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

This comment has been minimized.

Copy link

@boospy 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?

@Garoe

This comment has been minimized.

Copy link
Owner Author

@Garoe Garoe commented Jan 3, 2019

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

This comment has been minimized.

Copy link

@boospy 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