最近、自分の Arch Linux にセキュアブート(security boot)を設定しました。ここでは手順と問題について記録しておきます。
セキュアブートの実現#
セキュアブートの実現方法については、Arch Wikiに詳細な説明がありますが、ウィキ形式で書かれているため手順の説明がやや複雑です。このセクションでは、セキュアブートを実現する最も簡単な方法を説明します。詳細な概念には触れません。
注:この記事では Arch Linux のセキュアブートの設定についてのみ説明しており、Windows との共存については Arch Wiki の該当する項目を参照してください。
キーの生成#
セキュアブートの実現には、以下の 4 つのキーが必要です:
- プラットフォームキー(PK)
- キー交換キー(KEK)
- 署名データベース(db)
- 禁止署名データベース(dbx)
セキュアブートを正常に使用するためには、少なくとも最初の 3 つのキーが必要です。便利のため、スクリプトを使用して自動的に生成することができます:
# カーネルの更新などを自動的に処理するsbupdateツールは、デフォルトで/etc/efi-keysに配置されたキーを使用します。
# 便利のため、このディレクトリを直接作成し、そのディレクトリでキーを生成します
mkdir /etc/efi-keys
cd !$
curl -L -O https://www.rodsbooks.com/efi-bootloaders/mkkeys.sh
chmod +x mkkeys.sh
./mkkeys.sh
<キーに埋め込む任意の名前を入力してください。例:"Secure Boot">
自動署名#
カーネルやブートローダの更新時に自動的に署名するために、sbupdate ツールを使用できます。
インストール#
次のコマンドでインストールします:
yay -S sbupdate-git
設定#
インストール後、設定を書き込む必要があります。自動的に署名するコンテンツを指定するためです。
/etc/sbupdate.conf を開き、設定ファイルを変更します。以下に私の設定例とオプションの説明を示します:
# キーのディレクトリ
KEY_DIR="/etc/efi-keys"
# EFIブートパーティションの場所
ESP_DIR="/boot"
# 個別のEFIブートファイルの場所
OUT_DIR="EFI/Linux"
# 個別のEFIブートファイルに含まれるデフォルトのカーネルパラメータ
CMDLINE_DEFAULT="loglevel=3 quiet nomce rw"
# 追加で署名するファイル(通常は自分自身のブートローダーファイルを含む)
# 理論的にはカーネルは自動的に署名されますが、なぜか私のvmlinuz-linux-zenはうまくいかないので、ここにカーネルファイルも書いています
EXTRA_SIGN=('/boot/EFI/BOOT/BOOTX64.EFI' '/boot/EFI/systemd/systemd-bootx64.efi' '/boot/vmlinuz-linux-zen')
# 個別のカーネル設定
INITRD["linux-zen"]="/boot/initramfs-linux-zen.img"
# カーネルパラメータの設定がない場合、上記のCMDLINE_DEFAULTが使用されます
CMDLINE["linux-zen"]="root=PARTUUID=db9157b1-bed4-fa44-a715-5c1bfc8bdfb4 quiet nomce loglevel=3 rw"
以下は個別のカーネル設定についての特記事項です:
sbupdate は各カーネルに対して直接ブートファイル(${ESP_DIR}/${OUT_DIR} にあり、ファイル名は ${kernel_name}-signed.efi)を生成します。これにはカーネルパラメータと一時ファイルシステムの設定が含まれます(それぞれ設定ファイルの CMDLINE [${kernel_name}] と INITRD [${kernel_name}] に対応します)。
ユーザーが使用できるブート方法は 3 つあります:
- ブートローダー(例:grub/systemd-boot など)の既存の設定を使用してブートする方法
- このファイルを直接使用してブートする方法
- ブートローダーを介してこのファイルを呼び出して間接的にブートする方法
ユーザーが現在使用しているのはおそらく 1 番目の方法です。この方法に問題がない場合、この直接ブートファイルを使用する必要はありません。つまり:
上記の OUT_DIR、CMDLINE_DEFAULT、個別のカーネル設定は無視できます。
署名#
初回の設定が完了したら、手動で署名コマンドを実行する必要があります:
sudo sbupdate
将来のカーネルの更新時には、このツールが自動的に署名します。
systemd-boot の自動署名の特別な処理#
他のブート方法では、上記の設定方法で十分かもしれませんが、systemd-boot をブートローダーとして使用している場合は、さらなる設定が必要かもしれません。
フックの実行順序の処理#
この状況についての説明:
通常、カーネルや systemd の更新時に署名のために pacman フックを使用する必要がありますが、systemd-boot を使用している場合、ブートの更新(つまりsudo bootctl update
、このコマンドは /boot/EFI/BOOT/BOOTX64.EFI と /boot/EFI/systemd/systemd-bootx64.efi を最新バージョンに置き換えます)も更新時に行う必要があります。そのため、フックの実行順序が非常に重要です - ブートの更新が署名の前に行われるようにする必要があります。
systemd-boot を使用しているユーザーは、自動更新の方法について理解しているはずです(systemd boot - 自動更新を参照)。ドキュメントには 2 つの方法が示されています:
- systemd-boot-pacman-hook をインストールする(本質的には systemd-boot.hook をダウンロードする)
- 自分で /etc/pacman.d/hooks/100-systemd-boot.hook に内容を書き込む。
sbupdate には、署名のためのフックとして使用される名前が 95-sbupdate.hook となっていますが、alpm-hooks のドキュメントによれば:
Hooks are run in alphabetical order of their file name, where the ordering ignores the suffix.
フックは、ファイル名のアルファベット順に実行されます。この順序は接尾辞を無視します。
このルールに従うと、方法 1 で得られる system-boot.hook や方法 2 で書き込む 100-systemd-boot.hook は、署名フックよりも前に実行されることはありません。私の解決策は方法 2 を使用し、ファイル名を 90-systemd-boot.hook に変更することで、順序の要件を満たすようにしました。
追加のブートローダーの署名の処理#
EXTRA_SIGN に署名する必要があるブートローダーファイルを記述しましたが、95-sbupdate.hook で使用される署名の更新コマンドは/usr/bin/sbupdate -k
です。sbupdate のソースコードを確認すると、66-72 行、195-205 行で - k オプションが hook から呼び出されることがわかります。また、セキュリティ上の理由から、hook から sbupdate を呼び出すと EXTRA_SIGN の内容がスキップされるため、期待される動作ではありません。
解決策も非常に簡単で、/usr/share/libalpm/hooks/95-sbupdate.hook を開き、-k オプションを削除するだけです。
BIOS へのキーの書き込み#
上記の手順が完了したら、あとは BIOS にキーを書き込むだけです。
既存のキーの削除#
BIOS にはデフォルトで Microsoft のキーが含まれていますので、自分自身のキーを書き込むためには既存のキーを削除する必要があります。
この手順では、BIOS に入り、セキュアブートの証明書管理オプションを見つけ、削除を選択します。
新しいキーの書き込み#
sbsigntools
を使用してキーの書き込みを簡略化します。
まず、次のようなディレクトリが必要です:
/etc/secureboot/keys
├── db
├── dbx
├── KEK
└── PK
次のコマンドを実行して作成します:
mkdir -p /etc/secureboot/keys/{db,dbx,KEK,PK}
次に、以前の*.auth
ファイル(/etc/efi-keys にある)を対応するディレクトリにコピーします(dbx がない場合は正常です)。
最後に、次のコマンドを実行します:
sbkeysync --verbose
sbkeysync --verbose --pk
エラーがなければ、Arch Linux のセキュアブートの設定が完了しました。あとは BIOS でセキュアブートオプションを有効にして起動するだけです!
まとめ#
この記事では、自分のマシンにセキュアブートを設定するために行ったすべての手順を示しました。ただし、読者が私の成功した手順を再現できることを保証することはできません。
記事の手順の実行中に問題が発生した場合は、Arch Wiki の元の記事を参照することをお勧めします。元の記事には同じ手順のさまざまな実装方法が含まれており、詳細なエラー処理も提供されています。より代表的な情報源です。