Skip to content

sbctlでセキュアブート環境を構築する

まずはPCのUEFIでセキュアブートの状態をセットアップモードにする。その状態で起動して以下を実行。

Terminal window
pacman -S sbctl
sbctl create-keys
sbctl enroll-keys -m
sbctl verify

最初は sbctl verify すると署名が必要なファイルが列挙されるので署名をする。このとき sbctl sign は最初の引数を1つだけしか処理しないので、必要な回数だけ実行する。

Terminal window
$ run0 sbctl verify
Verifying 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.efi
Signed /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 で使うのだろう。

Terminal window
$ sbctl status
Installed: ✓ sbctl is installed
Owner GUID: df0e94ce-ddbd-4a1c-bbab-8fd8c37ad193
Setup Mode: ✓ Disabled
Secure Boot: ✓ Enabled
Vendor Keys: microsoft

カーネルを更新したときの署名は、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.efisystemd-bootx64.efi/usr/lib/systemd/boot/efi/ にあるものが bootctl update でコピーされる。なので systemd をアップデートした後はファームウェアの署名が必要となるので自動化しておく。

Terminal window
vi /etc/pacman.d/hooks/systemd-boot.hook

systemd パッケージが更新されて変わるのはEFIファイルなので、ここではEFI実行ファイルの署名を行う。pacman hook: execute two commands instead of oneをみると Exec 行は複数書けない。

[Trigger]
Type = Package
Operation = Upgrade
Target = systemd
[Action]
Description = Upgrading systemd-boot...
When = PostTransaction
Exec = /bin/sh -c 'bootctl update --graceful && sbctl sign -s /boot/EFI/Boot/bootx64.efi && sbctl sign -s /boot/EFI/systemd/systemd-bootx64.efi'

ファイル名を間違えて署名したとき以下のような状態になる。

Terminal window
$ 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

このファイルは確認して消せる。

Terminal window
$ run0 sbctl list-files
/boot/EFI/Boot/bootx64.efi
Signed: ✓ Signed
/boot/EFI/systemd/systemd-bootx64.efi
Signed: ✓ Signed
/boot/EFI/systemd/systemd-bootx64.efi}: open /boot/EFI/systemd/systemd-bootx64.efi}: no such file or directory
/boot/vmlinuz-linux
Signed: ✓ Signed
Terminal window
$ run0 sbctl remove-file '/boot/EFI/systemd/systemd-bootx64.efi}'
Removed /boot/EFI/systemd/systemd-bootx64.efi} from the database.