sbctlでセキュアブート環境を構築する
セットアップ
Section titled “セットアップ”まずはPCのUEFIでセキュアブートの状態をセットアップモードにする。その状態で起動して以下を実行。
pacman -S sbctl
sbctl create-keyssbctl enroll-keys -msbctl verify最初は sbctl verify すると署名が必要なファイルが列挙されるので署名をする。このとき sbctl sign は最初の引数を1つだけしか処理しないので、必要な回数だけ実行する。
$ run0 sbctl verifyVerifying file database and EFI images in /boot...✓ /boot/EFI/Boot/bootx64.efi is signed✓ /boot/vmlinuz-linux is signed✗ /boot/EFI/systemd/systemd-bootx64.efi is not signed
$ run0 sbctl sign -s /boot/EFI/systemd/systemd-bootx64.efiSigned /boot/EFI/systemd/systemd-bootx64.efi各ファイルの役割は次のようになっている。
- /boot/EFI/Boot/bootx64.efi: systemd-bootバイナリ
- /boot/EFI/systemd/systemd-bootx64.efi: systemd-bootバイナリ(bootx64.efi と同じ)
- /boot/vmlinuz-linux: Linuxカーネル
sbctl sign の -s オプションは署名したファイルパスを /var/lib/sbctl/files.json に保存する。おそらく sbctl sign-all で使うのだろう。
セキュアブートの状態確認
Section titled “セキュアブートの状態確認”$ sbctl statusInstalled: ✓ sbctl is installedOwner GUID: df0e94ce-ddbd-4a1c-bbab-8fd8c37ad193Setup Mode: ✓ DisabledSecure Boot: ✓ EnabledVendor Keys: microsoft署名の自動化
Section titled “署名の自動化”カーネルを更新したときの署名は、sbctl をインストールすると /usr/lib/initcpio/post/sbctl に入っているので、mkinitcpio 実行後に自動で行われる。
[!Info] sbctl には同等のsystemdのkernel-installスクリプトが /usr/lib/kernel/install.d/91-sbctl.install にも存在する。UKIを作るときに実行されるのは分かるが、そうでない場合にも動いているようで、mkinitcpio フックとの棲み分けがよく分からない。なんなら /usr/lib/initcpio/post/sbctl もある。
上でみた bootx64.efi と systemd-bootx64.efi は /usr/lib/systemd/boot/efi/ にあるものが bootctl update でコピーされる。なので systemd をアップデートした後はファームウェアの署名が必要となるので自動化しておく。
vi /etc/pacman.d/hooks/systemd-boot.hook/etc/pacman.d/hooks/systemd-boot.hook
Section titled “/etc/pacman.d/hooks/systemd-boot.hook”systemd パッケージが更新されて変わるのはEFIファイルなので、ここではEFI実行ファイルの署名を行う。pacman hook: execute two commands instead of oneをみると Exec 行は複数書けない。
[Trigger]Type = PackageOperation = UpgradeTarget = systemd
[Action]Description = Upgrading systemd-boot...When = PostTransactionExec = /bin/sh -c 'bootctl update --graceful && sbctl sign -s /boot/EFI/Boot/bootx64.efi && sbctl sign -s /boot/EFI/systemd/systemd-bootx64.efi'ファイル名を間違えて署名したとき以下のような状態になる。
$ run0 sbctl verify
Verifying file database and EFI images in /boot...✓ /boot/EFI/systemd/systemd-bootx64.efi is signed‼ /boot/EFI/systemd/systemd-bootx64.efi} does not exist✓ /boot/vmlinuz-linux is signed✓ /boot/EFI/Boot/bootx64.efi is signedこのファイルは確認して消せる。
$ run0 sbctl list-files/boot/EFI/Boot/bootx64.efiSigned: ✓ Signed
/boot/EFI/systemd/systemd-bootx64.efiSigned: ✓ Signed
/boot/EFI/systemd/systemd-bootx64.efi}: open /boot/EFI/systemd/systemd-bootx64.efi}: no such file or directory
/boot/vmlinuz-linuxSigned: ✓ Signed$ run0 sbctl remove-file '/boot/EFI/systemd/systemd-bootx64.efi}'Removed /boot/EFI/systemd/systemd-bootx64.efi} from the database.