ubuntu16.04でvirtualboxを起動できない

タイトルどおりの現象。virtualboxを起動して適当な仮想マシンを作成、「起動」するとこんなエラー。

Kernel driver not installed (rc=-1908)

The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please install virtualbox-dkms package and load the kernel module by executing

modprobe vboxdrv
as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.

ん?

# sudo modprobe vboxdrv

と実行してもなにやらエラーになる。
調べてみるとhttps://stegard.net/2016/10/virtualbox-secure-boot-ubuntu-failにこうするといいよってのが書いてありました。なにやらUEFIシステムのキーでカーネルにサインしないとイカンらしい。
手順は以下。上記ウェブページの適当訳です。

鍵ペア作成

パーソナルなパブリック/プライベートRSAキーペアを作成する。この鍵ペアでカーネルモジュールにサインする。rootで/root/module-signing/ディレクトリでカーネルモジュールにサインするために必要なブツをすべて集めた。
以下の通り実行。

$ sudo -i
# mkdir /root/module-signing
# cd /root/module-signing
# openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=name/"
# chmod 600 MOK.priv

上記例のnameのところは適当に名前をいれればいい。

MOKユーティリティで鍵をインポートする

MOK("Machine Owner Key")ユーティリティをつかってシステムが信用できるためのパブリックキーをインポートする。これは、まずキーをインポートして、次回マシンがリブートしたときにenrollするという2つのステップが実施される。
パスワードを設定するが、一時的に利用するだけなので単純なもので大丈夫。

# mokutil --import /root/module-signing/MOK.der 
input password:
input password again:

リブート

マシンをリブートする。リブート時にMOKマネージャEFIユーティリティが自動的に起動される。上記ステップで設定したパスワードを入力して、"Enroll MOK"を選択する。すると、上記ステップでインポートしたキーが参照できる。enrollmentステップが完了したら、"boot"を選択して起動する。Linuxカーネルにキーがロードされたかどうかはdmesgで確認することができる。

# dmesg | grep 'EFI: Load cert'

virutualboxモジュールへサイン

カーネルビルドファイルに同梱されているサインユーティリティを利用して、すべてのVirtualBoxモジュールへプライベートMOKキーでサインする。以下のスクリプトを用意したので /root/module-signing/sign-vbox-module等へ保存して実行権をつけて実行すると良い。新しいカーネルがインストールされるたびにこれを実行しなくてはならない。

#!/bin/bash

for modfile in $(dirname $(modinfo -n vboxdrv))/*.ko; do
  echo "Signing $modfile"
  /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 \
                                /root/module-signing/MOK.priv \
                                /root/module-signing/MOK.der "$modfile"
done

vboxdrvモジュールをロードする

# modprobe vboxdrv