Secure BootでブロックされるNvidiaドライバーとVirtualBoxの修正:カーネルモジュールの署名(Sign)ガイド

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

最新のUbuntu 22.04やFedoraをインストールし、AIやグラフィックスのためにNvidiaドライバーを導入したとしましょう。しかし、再起動後もドライバーが認識されず、画面解像度が低いまま。lsmod | grep nvidiaを実行しても結果が出ず、dmesgには「Required key not available」というエラーが赤く表示されます。

原因はSecure Bootです。これはBIOS/UEFI層のセキュリティ機能で、OSカーネルに悪意のあるコードがロードされるのを防ぎます。Microsoftやメーカー(OEM)によってデジタル署名されたカーネルモジュールのみが実行を許可されます。

NvidiaドライバーやVirtualBoxは、インストール時にマシン上で直接ビルド(コンパイル)されることが一般的です。ローカルでビルドされるため、有効なデジタル署名が欠けています。Secure Bootを無効にしてセキュリティを低下させる代わりに、独自のキーペアを作成し、システムにそれを信頼させる方法をとります。この技術にはMOK (Machine Owner Key)を使用します。

なぜ手動で署名する必要があるのか?

通常、Ubuntuなどのディストリビューションでは、公式リポジトリのドライバーを使用すれば自動的に処理されます。しかし、Nvidiaの公式サイトから最新版をインストールしたり、特定のモジュールを使用したりする場合、署名ステップがスキップされます。

実際、最新のゲーミングノートPC(ASUS ROG、Dell XPS noteなど)でWindowsとLinuxをデュアルブートしているユーザーの約90%がこの問題に直面しています。自己署名を行うことで、自身のデバイス上で信頼された「パブリッシャー」になることができます。

ステップ1:キー管理ツールのインストール

まず、MOK証明書を作成・管理するためのツールセットが必要です。Ubuntu/Debianでは、ターミナルを開いて以下を実行してください:

sudo apt update
sudo apt install openssl mokutil shim-signed

FedoraやRHELユーザーの場合は、以下のコマンドになります:

sudo dnf install openssl mokutil

ステップ2:Machine Owner Key (MOK) ペアの作成

署名用の秘密鍵(private key)と、BIOSにロードするための公開証明書(public certificate)のペアを作成します。

セキュリティのため、鍵はrootディレクトリに保存しましょう:

sudo mkdir -p /root/mok-keys
cd /root/mok-keys

# 100年間有効な2048ビットのRSAキーを作成
sudo openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=My Linux Driver Key/"

実行後、MOK.privMOK.derというファイルが作成されます。システムへの侵入を防ぐため、.privファイルは決して公開しないでください。

ステップ3:システムへのキーの登録(インポート)

次に、公開証明書をシステムの確認待ちリストに追加します:

sudo mokutil --import MOK.der

パスワードの設定を求められます。これを忘れないでください。 次のステップで再起動する際に一度だけ使用します。

ステップ4:ブルースクリーン(MOK Manager)での確認

ここが重要なステップです。PCを再起動してください。メーカーのロゴが表示された直後に、Perform MOK managementというブルースクリーン(通常はテキストインターフェース)が表示されます。

  1. Enroll MOKを選択します。
  2. View key 0を選択:先ほど作成した「My Linux Driver Key」という名前が表示されているか確認します。
  3. Continue -> Yesを選択して確定します。
  4. ステップ3で設定したパスワードを入力します(注:キーボードがデフォルトのUS配列になっている場合があります)。
  5. Rebootを選択します。

もしEnrollせずに「Continue boot」を選んでしまった場合、ドライバーはブロックされたままになります。その場合は、再度mokutil --importコマンドを実行する必要があります。

ステップ5:ドライバーの署名実行

Linuxにログインし直したら、作成したキーを使用してドライバーファイル(拡張子 .ko)に「印」を付けます。まず、カーネルの署名スクリプトの場所を探します:

# sign-fileのパスを検索
KBUILD_DIR=$(find /lib/modules/$(uname -r) -name "sign-file" | head -n 1)

次に、Nvidiaモジュールに署名します。以下のコマンドは自動的にモジュールのパスを見つけて署名を行います:

sudo perl "$KBUILD_DIR" sha256 /root/mok-keys/MOK.priv /root/mok-keys/MOK.der $(modinfo -n nvidia)

VirtualBoxの場合は、4つの主要モジュール(vboxdrv, vboxnetadp, vboxnetflt, vboxpci)に署名する必要があります:

sudo perl "$KBUILD_DIR" sha256 /root/mok-keys/MOK.priv /root/mok-keys/MOK.der $(modinfo -n vboxdrv)

ステップ6:結果の確認

modprobeコマンドでモジュールをロードしてみます。エラーメッセージが表示されなければ成功です:

sudo modprobe nvidia
# 署名が付与されているか確認
modinfo nvidia | grep signature

ヒント:DKMSによる自動化

Linuxカーネルが更新されるたびに(例:6.5から6.8へ)、ドライバーの署名は消えてしまいます。毎週手動で署名する手間を省くために、DKMSを設定することをお勧めします。

新しいUbuntuバージョンでは、キーペアを/var/lib/shim-signed/mok/にコピーしておくと、新しいモジュールがビルドされるたびにDKMSが自動的に署名を行ってくれます。これにより、手動での介入なしにシステムを安定させることができます。

Secure Bootは敵ではありません。MOKを使いこなせば、高いセキュリティを維持しつつ、高性能なドライバーを動作させることができます。

Share: