« コンテナで GUI / GPU を使う | トップページ | FreeDOS で SATA 接続 CD/DVD が利用可能に »

2023-03-06

Debian Linux を Secure Boot 環境で使う

以前から Windows と Linux のデュアルブート (実際には別ディスク上の Ubuntu も入れてトリプルブート) 環境で使用している。 Windows 11 ではセキュアブートが必須との話もあり、今のうちに Secure Boot 環境でも Linux が使えるようにしておく。

Linux のインストール

これは今のディストリビューション (Debian bullseye や Ubuntu 22.04 LTS など) ならば問題ないはず。 非セキュアブート状態で EFI インストールし、後からセキュアブートに変えても起動する。

DKMS ドライバ

以前の記事 でも書いたようにディストリビューション側で用意していない (センサー等の) ドライバを DKMS でインストールすることがある。 DKMS でインストールされるモジュールは自環境でコンパイルするためそのままでは署名はされておらず、セキュアブート環境ではロードされない。

参考

MOK (Machine Owner Key) というマシンの所有者用のキーを作成して UEFI に登録することで、そのキーを使って署名したカーネルモジュール(ドライバ)はセキュアブート環境でも使えるようになる。

大筋は決まっているものの、セキュアブート自体が比較的新しいものということもあり、ディストリビューションによってやり方は異なる。 まずは共通の手順として (まだインストールしていなければ) dkms パッケージをインストールする。

$ sudo apt install dkms
Debian 11 (bullseye)

bullseye の dkms はセキュアブートに関してはあまりやってくれないので、ほとんど手作業で…

MOK の作成

適当な作業ディレクトリで OpenSSL を使用して MOK を作成する

$ openssl req -new -x509 -nodes -days 36500 -subj "/CN=DKMS module signing key" -newkey rsa:2048 -keyout mok.priv -outform DER -out mok.der

bullseye の dkms では /root 配下に MOK が置かれていることを想定しているので移動してパーミッションを変更する

$ sudo mv mok.priv mok.der /root
$ sudo chown root:root /root/mok.priv /root/mok.der
DKMS の設定

DKMS でモジュールをインストールする際に自動的に証明する際には /etc/dkms/sign_helper.sh が使われる。 ただし、デフォルトでは自動署名処理は有効となっていないため設定を変更する。

/etc/dkms/framework.conf の一番下のコメントを外して有効にする。

## Script to sign modules during build, script is called with kernel version
## and module name
sign_tool="/etc/dkms/sign_helper.sh"    ★ コメントを外す

これを見てもわかるように、もし /etc/dkms/sign_helper.sh のやり方が気に入らない (MOK を /root に置くのがイヤ等) ならば、自前でツールを書いてそのツールの場所を指定してもいい。 [1]

この後に DKMS でカーネルモジュールをインストールすればあとは自動的にモジュールが署名される。

MOK の UEFI への登録

MOK の UEFI への登録方法にはいくつかあるが mokutil を使用するのが一番簡単。

$ sudo mokutil --import /root/mok.der
input password:          ★ 実際に MOK を Enroll する際に使う一過性のパスワードを指定
input password again:
$ sudo mokutil --list-new
[key 1]
SHA1 Fingerprint: xx:xx:....
Certificate:
    Data:
...
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=DKMS module signing key
        Validity
            Not Before: Mar  5 09:42:50 2023 GMT
            Not After : Feb  9 09:42:50 2123 GMT
        Subject: CN=DKMS module signing key
...
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
...

次回 PC の再起動時に実際の MOK を UEFI に登録する画面が表示されるので Enroll MOK を選択し、先程入力したパスワードを入れれば登録される。 具体的な画面は PC により異なるが Ubuntu の例 を参考に…

再起動後に mokutil --list-enrolled コマンドを実行すると登録済みの MOK が表示され sudo mokutil --list-new では何も表示されなくなる。

Debian 12 (bookworm)

(現時点ではまだ bookworm はリリースされていないが) dkms のアップストリームに合わせてやり方が変わっている。

  • 事前に MOK を作成する必要はなく、その時点で MOK が存在しなければ DKMS が MOK を自動的に作成
  • MOK はデフォルトでは /var/lib/dkms/ 配下に作成
    /etc/dkms/framework.conf/etc/dkms/framework.conf.d/ 配下のファイルで mok_signing_keymok_certificate を設定すれば変更可
  • 特に設定をしなくても DKMS が自動的にモジュールを署名

ただし MOK を UEFI に登録するところまではやってくれないので bullseye と同様に mokutil で enroll してやる必要がある。

$ sudo mokutil --import /var/lib/dkms/mok.pub
input password:
input password again:

なお、 bullseye からのアップグレードで既に作成済みの MOK をそのまま流用する場合には、上記のように新しい MOK を登録せずに以下のように旧 MOK を移動した方がいいかもしれない。 ただし、アップグレードの際に既に DKMS の管理下になっていたモジュールは dkms により自動的に作成された MOK で署名されている可能性があるので、その場合には dkms でモジュールを再インストールする必要がある。

$ sudo mv /root/mok.der /var/lib/dkms/mok.pub
$ sudo mv /root/mok.priv /var/lib/dkms/mok.key
Ubuntu

Ubuntu (20.04 以降?) では Debian とは異なる独自のやり方をしている。 (恐らく Debian より先行してセキュアブートに取り組んでいたため) Ubuntu では kmodsign というコマンドを使いカーネルモジュールを署名するようになっているが、 Debian にはそのようなコマンドは無い。 また update-secureboot-policy というコマンドは Debian にも Ubuntu にも存在するが、できることが全く異なり別物と考えたほうが良い。

Ubuntu では DKMS でカーネルモジュールをインストールする際に以下のことをする。

  • (MOK が存在しなければ) update-secureboot-policy --new-key により MOK を /var/lib/shim-signed/mok/ 配下に生成
  • (MOK が登録されていなければ) update-secureboot-policy --enroll-key コマンドで MOK を UEFI に登録
  • kmodsign コマンドでモジュールを署名

以降は DKMS でモジュールがインストールされる度に自動的に署名してくれる。

VMware

Windows とのデュアルブート環境とはいえ、実際に Windows 側を立ち上げるのは GPU 等のハードリソースを使うケースに限られ、単に Windows のソフトを使いたい場合には VMware Player を使って Windows VM を立ち上げている。
VMware を動かす際に vmmon.kovmnet.ko という2つのドライバが必要となるが、これらは署名されていないためにセキュアブート観葉ではロードされない。 これらのドライバに対しても署名してやる必要がある。

MOK は前述の DKMS 用に作成したものを使う。

  • Debian 11 (bullseye)
    $ sudo /lib/modules/$(uname -r)/build/scripts/sign-file sha512 /root/mok.priv /root/mok.der $(sudo modinfo -n vmmon)
    $ sudo /lib/modules/$(uname -r)/build/scripts/sign-file sha512 /root/mok.priv /root/mok.der $(sudo modinfo -n vmnet)
    
  • Debian 12 (bookworm)
    $ sudo /lib/modules/$(uname -r)/build/scripts/sign-file sha512 /var/lib/dkms/mok.key /var/lib/dkms/mok.pub $(sudo modinfo -n vmmon)
    $ sudo /lib/modules/$(uname -r)/build/scripts/sign-file sha512 /var/lib/dkms/mok.key /var/lib/dkms/mok.pub $(sudo modinfo -n vmnet)
    
  • Ubuntu
    $ sudo kmodsign sha512 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der $(sudo modinfo -n vmmon)
    $ sudo kmodsign sha512 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der $(sudo modinfo -n vmnet)
    

DKMS とは違って新しい Kernel がインストールされる度に自動でやってくれることはないので、 VMware や kernel のアップデートの度にこの作業をする必要がある。

参考

rEFInd

実はこれが一番厄介な代物で、この記事を書こうと思ったのもこのため。 結論から言うと Debian や Ubuntu のリポジトリにあるパッケージは使うな。 パッケージの rEFInd を使う限りはうまくいかない。
※ これはたまたま rEFInd の新しい版数 0.14.0 がリリースされ、問題が解決しただけかもしれないが…

まずは、カスタマイズ済みの /boot/efi/EFI/refind/refind.conf を退避したら、パッケージをアンインストールして /boot/efi/EFI/refind ディレクトリごとバッサリ削除する。 ただし rEFInd で必要なパッケージ (sbsigntool) はインストールしたままにしておくこと。

次に rEFInd のサイト からダウンロードした binary zip ファイルを適当な作業ディレクトリに展開し、そのディレクトリに移動する。

$ unzip refind-bin-0.14.0.zip
$ cd refind-bin-0.14.0

続いてインストール済みの shim をディレクトリごとワークディレクトリ下にコピーし、署名されたバイナリを扱うように削除・リネームする。

$ cp -a /usr/lib/shim .
$ cd shim
$ rm fbx64.efi mmx64.efi shimx64.efi
$ mv fbx64.efi.signed fbx64.efi
$ mv mmx64.efi.signed mmx64.efi
$ mv shimx64.efi.signed shimx64.efi
$ cd ..

先程コピーした署名付き shim を指定して rEFInd をインストールする。

$ sudo ./refind-install --shim shim/shimx64.efi

これで rEFInd の MOK の import も済んでいるので、再起動時に MOK の Enroll をすれば rEFInd がブートローダとして動くようになる。

/boot/efi/EFI/refind/refind.conf をカスタマイズしていた場合には、再起動前に新たにインストールされた refind.conf にカスタマイズ内容を反映させることを忘れずに。

参考


[1]: 個人的には bookworm と同じディレクトリ構成にしたスクリプトに変更することをお薦めする。その方がアップグレードに伴うトラブルが少ない。

« コンテナで GUI / GPU を使う | トップページ | FreeDOS で SATA 接続 CD/DVD が利用可能に »

パソコン・インターネット」カテゴリの記事

Linux」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

« コンテナで GUI / GPU を使う | トップページ | FreeDOS で SATA 接続 CD/DVD が利用可能に »

2024年11月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
無料ブログはココログ