Guide: How to Use Secure Boot with Virtualbox-Whonix on Linux Host

It has been difficult for me to figure out how to get virtualbox to work with Secure Boot. However, I have found a process that seems to work for me. I am documenting this process so that it might help other people. I am also documenting the process so that other people who are more knowledgeable than me can comment on what I did and provide suggestions on better ways to do this.

Host: Zorin OS 18.0
Requirements:

  • Secure boot should be enabled.
  • Virtualbox should already be installed and have Whonix Gateway/Workstations imported.
  • You should have a USB stick which you are willing to wipe and keep safe for the sole purpose of managing the signing keys that you are going to create.
  • You should have a password manager installed on your computer, such as KeePassXC,

Step 1: Create a USB stick.

  • Enter the USB stick into a port on your ZorinOS 18 computer.
  • Install USB Stick Formatter from the ZorinOS repositories (Note, this might not be strictly necessary, but it is what I did).
sudo apt install mintstick
  • Use USB Stick Formatter to make a new USB. Call it MOK-KEYS and format it in the ext4 filesystem.

Step 2: Encrypt the USB stick

  • Open up the Disks program that comes pre-installed in ZorinOS 18.
  • Select your external USB.
  • Unmount the partition on the USB.
  • Go to the gear icon (additional partition options), and click on format partition.
  • Enter the volume name MOK-KEYS.
  • Select the type as “Internal disk for use with Linux systems only (Ext4).”
  • Underneath that, select the option to “Password protect volume (LUKS).”
  • Select next, and password-protect the volume with a strong password generated by your password manager. Continue, and the program will format your USB stick to be encrypted and password-protected.

Step 3: Make your MOK keys.

Re-mount your encrypted USB. Open up a terminal. We are going to enter the following commands one at a time.

sudo mkdir -p /media/user/MOK-KEYS/mok/
sudo openssl req -nodes -new -x509 -newkey rsa:4096 -outform DER -addext "extendedKeyUsage=codeSigning" -keyout /media/user/MOK-KEYS/mok/MOK.priv -out /media/user/MOK-KEYS/mok/MOK.der

There will be fields to enter, but you can leave some blank. Make something up that is memorable and will help you distinguish these keys from the other signing certificates on your system. Come up with a memorable organization name (for example, Wayne Enterprises).

Step 4: Enroll your MOK keys.

sudo mokutil --import /media/user/MOK-KEYS/mok/MOK.der

The software will ask you to create a password for importing the key later, during the boot process. As far as I am aware, this is a one-time password. But I could be wrong. Choose something, and write it down on a piece of paper.

Reboot the computer.

During the boot process, you’ll see the MOK manager screen. This will look different depending on your hardware, so these steps might vary.

  • Select “Enroll MOK”.
  • Choose “Continue”.
  • Enter the password you set when importing the key.
  • Select “Yes” to confirm enrolling the key.

Step 5: Sign the VirtualBox Modules

After rebooting and enrolling the MOK, sign the required VirtualBox kernel modules.

  • First, plug in your encrypted USB and enter your password to unlock and mount it.
  • Then, locate the Virtualbox kernel modules (usually in /lib/modules/$(uname -r)/).
cd /lib/modules/$(uname -r)/updates/dkms

Then uncompress the kernel modules

sudo zstd -d vboxdrv.ko.zst 
sudo zstd -d vboxnetadp.ko.zst
sudo zstd -d vboxnetflt.ko.zst

Then sign the modules.

sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 /media/user/MOK-KEYS/mok/MOK.priv /media/user/MOK-KEYS/mok/MOK.der vboxdrv.ko
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 /media/user/MOK-KEYS/mok/MOK.priv /media/user/MOK-KEYS/mok/MOK.der vboxnetadp.ko
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 /media/user/MOK-KEYS/mok/MOK.priv /media/user/MOK-KEYS/mok/MOK.der vboxnetflt.ko

See:

Now delete the original .zst files.

sudo rm vboxdrv.ko.zst vboxnetadp.ko.zst vboxnetflt.ko.zst

Then recompress the modules that you signed.

sudo zstd vboxdrv.ko vboxnetadp.ko vboxnetflt.ko

Finally, load the signed modules:

sudo modprobe vboxdrv
sudo modprobe vboxnetflt
sudo modprobe vboxnetadp

If this does not work, you may need to reinstall virtualbox-dkms and go through step 5 again.

sudo apt install virtualbox-dkms

Step 6: Store your USB in a safe place

Store your USB in a safe place. You may or may not need to have it plugged in when you update your kernel. Otherwise, keep the USB unplugged from your computer. That way, if a hacker gets access to your system, they will not be able to use these keys in order to sign malicious modules. You may want to label the USB so that you remember which USB you stored the keys on.

Looks complicated.

We’ll simplify that a lot in the next point release. Version 18.1.3.4 and above. Already avaliable in the testers repository. New upcoming scripts:

Documentation will be updated:

If I’m not mistaken, this is for how to manage Secure Boot signing of VirtualBox on a Zorin OS host? I don’t think this is directly applicable to Whonix, but rather to any use of VirtualBox on Zorin OS.

If you’re using VirtualBox from the Ubuntu repositories Zorin uses by default, module signing should be transparently handled for you. You will need to enroll the MOK generated by DKMS, which will be stored at /var/lib/shim-signed/MOK.der on Ubuntu and Ubuntu-derived systems. (On Debian, /var/lib/dkms/mok.pub is the correct file.) If you don’t like that this means your MOK private key is stores in cleartext on your hard drive, you could also put it on an encrypted USB key like shown here, but bear in mind:

  • You will have to mount the USB key to /var/lib/shim-signed, and probably will have to set it up in fstab so that it somehow automounts there when plugged in (not sure how possible or difficult this is).
  • This will provide bad usability since you will have to plug in the USB key before software updates to keep DKMS from generating a new MOK and signing all your third-party modules with it, forcing you to re-sign them later.
  • This will provide less security than you might hope since Zorin OS doesn’t have a user-sysmaint-split-like feature, so malware could gain root access if it infects your standard user account, and at that point it can steal your MOK private key as soon as it becomes accessible (which will happen when you plug in and decrypt your USB drive).

Signing should also be handled for you transparently, with the same caveats above, if you’re using VirtualBox from Oracle’s repository. This is because Oracle’s repository is designed to have transparent signing working on Ubuntu.

1 Like

I am glad that the process will be simplified in the future. I had trouble the last time that I was trying to make Virtualbox compatible with secure boot (Error when using whonix linux installer - #2 by qtzvytqr77x4t5cq). But now I switched distributions and computers. So this time, I figured I would document the process that I took in case it would help others in the future.

It might be worth mentioning that as of right now, the version of virtualbox provided by Ubuntu 24.04 LTS and distributions downstream of that (Linux Mint, Zorin OS, etc.) is apparently incompatible with the recent kernel update 6.17.0-14 (Latest hwe kernel upgrade 6.17.0-14-generic conflicts with virtualbox 7.0.16 under 24.04 - Support and Help - Ubuntu Community Hub). Unless Ubuntu fixes it, workarounds seem to be to use an older kernel or to use the version of virtualbox that is provided directly by Oracle.

1 Like

Indeed. I stand corrected.

My previous post can be disregarded. This may only get easier to Kicksecure host operating systems.

Only for Kicksecure host operating systems.

Other Linux distributions would need to port Kicksecure’s enhancements to their Linux distributions or implement similar functionality.

If you want to use the keys generated at /var/lib/shim-signed/mok instead, then the guide changes as follows.

Skip Step 1-4

Step 5-
After rebooting and enrolling the MOK, sign the required VirtualBox kernel modules.

Locate the Virtualbox kernel modules (usually in /lib/modules/$(uname -r)/).

cd /lib/modules/$(uname -r)/updates/dkms

Then uncompress the kernel modules

sudo zstd -d vboxdrv.ko.zst 
sudo zstd -d vboxnetadp.ko.zst
sudo zstd -d vboxnetflt.ko.zst

Then sign the modules.

sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der vboxdrv.ko
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der vboxnetadp.ko
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der vboxnetflt.ko

See:

Now delete the original .zst files.

sudo rm vboxdrv.ko.zst vboxnetadp.ko.zst vboxnetflt.ko.zst

Then recompress the modules that you signed.

sudo zstd vboxdrv.ko vboxnetadp.ko vboxnetflt.ko

Finally, load the signed modules:

sudo modprobe vboxdrv
sudo modprobe vboxnetflt
sudo modprobe vboxnetadp

Skip step 6.

I do not know if this is necessary. I did not do it.

Could this be replicated on non-kicksecure linux distributions by creating another user account that is denied sudo access? In theory one could use that account for regular usage and the original account for updates. Granted, the operating system is not set up like that by default.

Sure, but the original account still has substantial attack surface (you probably don’t want all background services running while you’re logged into the original account, you’ll probably be tempted to open a browser in the original account since you’re right there and it’s in the start menu, etc.), but it would be an improvement. Depending on how far you take it, you probably will end up reinventing user-sysmaint-split for another distro, possibly with different advantages and disadvantages.

If you have to use Zorin OS as the host, I’d recommend looking at the linked wiki page and related ones, and maybe also looking through the code for Kicksecure’s implementation of user-sysmaint-split:

If you don’t have to use Zorin OS as the host though, you can use Kicksecure as the host and get all that (and much more!) for free. :slight_smile:

1 Like

For now, I use ZorinOS on this particular computer because I need a “just works” distro like Linux Mint, but I also wanted to try out wayland and gnome (Linux Mint uses X11). In the future I may try using Secureblue as the host or migrate to Qubes if I can. But for now I need a “just works” setup, which is ironic since apparently Ubuntu messed up and pushed out a kernel before making it compatible with virtualbox.

I am hesistant to use Kicksecure as the host because it is based on debian. Allegedly, debian is the absolute worst for security due to freezing its packages and failing to fix the bugs. From security researcher Daniel Micay:

https://old.reddit.com/r/GrapheneOS/comments/bddq5u/os_security_ios_vs_grapheneos_vs_stock_android/ekzo6c0/

You can also see the following quotation here. http://forums.w5j6stm77zs6652pgsij4awcjeel3eco7kvipheu6mtr623eyyehj4yd.onion/t/grapheneos-attacks-kicksecure-what-should-the-response-be/739

The idea here is that distributions like Fedora Silverblue or Arch have up-to-date packages and therefore benefit from the security and bug fixes of the up-to-date packages. Well, I assume arch would break too much and be too unstable for kicksecure/whonix. But fedora or a fedora variant would also have more up-to-date packages.

Okay, admittedly Daniel Micay is a [redacted] person, and not everything he says is correct. But the criticism of basing debian does not seem so unfair to me.

This point is also made by privsec at Choosing Your Desktop Linux Distribution | PrivSec - A practical approach to Privacy and Security

So, it would be better for my security to use something other than ZorinOS or Linux Mint for my host. But I do not know if Kicksecure on the host system is the correct solution.

I have read http://www.dds6qkxpwdeubwucdiaord2xgbbeyds25rbsgr73tbfpqpt4a6vjwsyd.onion/wiki/Dev/Operating_System#Why_don’t_you_use_<your_favorite_most_secure_operating_system>_for_Whonix? before. It makes good points, but I do not think it overrides the concerns of the people that I have talked about above. There is even http://www.dds6qkxpwdeubwucdiaord2xgbbeyds25rbsgr73tbfpqpt4a6vjwsyd.onion/wiki/Dev/Operating_System#Debian_-_packages_with_many_unfixed_high_severity_security_issues, which reinforces the points that they made.

But who knows, maybe in the future I will change my mind use Kicksecure host instead in the future. I still consider Kicksecure/Whonix to be extremely important projects. Anyone who can should consider donating to it, and they definitely should prefer donating to Whonix over donating to GrapheneOS for example (no need to fund the [redacted] lawsuits of [redacted] people). But that is off-topic.

And the new vulnerabilities (and sometimes backdoors) those new versions come with. See a comparison of the security advantages and disadvantages of stable and rolling distributions here:

There are many packages where a rolling-release model makes a lot of sense, but there are serious security downsides to using that model for the entire distribution. There are also security downsides to using a stable model for an entire distribution, but the nice thing about using a stable base is that you have some freedom to choose what you want to make rolling (for instance, by installing the latest version of an application from upstream). If you start with a rolling release, you don’t really get to “stabilize” some parts of it in a way that gives a meaningful security advantage without a lot of work.

Most of the things in Daniel’s quote are things Kicksecure (and by extension Whonix) are working on, though somewhat slowly due to limited resources. user-sysmaint-split provides much better privilege separation than traditional Linux distros, exploit mitigations are applied basically everywhere we can find them to apply them, we use memory-safe languages where possible and the few bits of C we use are either in non-security-sensitive locations or are heavily sandboxed, and verified boot, sandboxing, and full-system MAC are all actively being planned. See:

Most of the criticisms against desktop Linux Daniel mentions are applicable to Ubuntu derivatives (especially the LTS-only derivatives like Zorin and Mint).

1 Like

It’s possible but difficult to re-implement that. It’s well documented, Open Source but too difficult for users.

One of the reasons why user-sysmaint-split sessions (sysmaint session versus user session) are chosen in the boot menu is to mitigate Login Spoofing. See also: Prevent Malware from Sniffing the Root Password

user-sysmaint-split is based on security research by Kicksecure. You can read more about it here:

It’s a holistic Implementation.

Also related, for additional hardening:

Related wiki chapter where this is elaborated (which I expanded just now):
Dev/user-sysmaint-split, Minimal Services