Unified Extensible Firmware Interface/セキュアブート

提供: ArchWiki
2017年11月22日 (水) 01:33時点におけるKusakata (トーク | 投稿記録)による版 (→‎shim)
ナビゲーションに移動 検索に移動

関連記事

Linux における Secure Boot の概要については Rodsbooks の Secure Boot に関する記事 を見て下さい。この記事では Arch Linux で Secure Boot を設定する方法に焦点を置いています。

署名済みのブートローダーを使う

署名済みのブートローダーを使うというのは Microsoft の鍵で署名されたブートローダーを使うということです。署名済みのブートローダーとしては PreLoader と shim が存在します。どちらも他の EFI バイナリ (通常のブートローダー) をチェインロードします。Microsoft は未署名のあらゆるバイナリを自動起動するブートローダーに署名しないことになっているため、PreLoader と shim は Machine Owner Key リストと呼ばれるホワイトリストを使っています。バイナリの SHA256 ハッシュあるいはバイナリの署名鍵が MokList に存在する場合、バイナリが起動されますが、存在しない場合はハッシュや鍵を登録するための鍵管理ユーティリティが起動します。

archiso の起動

EFI アプリケーション PreLoader.efiHashTool.efi が archiso に追加されたことで Secure Boot を有効にして archiso を起動することが可能になりました。Failed to Start loader... I will now execute HashTool というメッセージが表示されます。HashTool を使って loader.efivmlinzu.efi のハッシュを登録するには、以下の手順に従って下さい:

  • OK を選択してください
  • HashTool のメインメニューから Enroll Hash を選択し、\loader.efi を選んで Yes で確定します。また、Enroll Hasharchiso を選択して archiso のディレクトリに入り、vmlinuz-efi を選んで Yes で確定してください。それから Exit を選択してブートデバイスの選択メニューに戻って下さい。
  • ブートデバイスの選択メニューから Arch Linux archiso x86_64 UEFI CD を選択して下さい

archiso が起動し、シェルプロンプトが表示され、自動的に root でログインがされます。archiso が Secure Boot で起動しているかどうか確認するには、次のコマンドを使って下さい (1234 という所はマシンによって異なります。タブ補完を使ったり efi 変数を表示することで調べることができます):

$ od -An -t u1 /sys/firmware/efi/vars/SecureBoot-1234abcde-5678-/data

このコマンドで返ってくるリストの最後が 1 ならば Secure Boot で起動しています。例:

6  0  0  0  1

次のコマンドを実行すると、詳しい状態を表示できます:

# bootctl status

PreLoader

起動時に PreLoader は loader.efi を実行しようとします。MokList に loader.efi のハッシュが存在しない場合、PreLoader は HashTool.efi を起動します。HashTool で起動したい EFI バイナリのハッシュ、つまりブートローダー (loader.efi) とカーネルを登録する必要があります。

ノート: バイナリ (ブートローダーやカーネル) をアップデートするたびに新しいハッシュの登録が必要です。

PreLoader の設定

警告: efitools パッケージに含まれている PreLoader.efiHashTool.efi は署名されていないため、使い道は限られています。署名済みの PreLoader.efiHashTool.efi を入手するには preloader-signedAUR をインストールするか 手動でダウンロード します。

preloader-signedAUR パッケージをインストールして PreLoader.efiHashTool.efiブートローダーのディレクトリにコピーしてください。systemd-boot の場合、以下を実行:

# cp /usr/share/preloader-signed/{PreLoader,HashTool}.efi esp/EFI/systemd

そしてブートローダーのバイナリをコピーして loader.efi に名前を変更します。systemd-boot の場合、以下を実行:

# cp esp/EFI/systemd/systemd-bootx64.efi esp/EFI/systemd/loader.efi

最後に、PreLoader.efi を起動する NVRAM エントリを新しく作成してください:

# efibootmgr --disk /dev/sdX --part Y --create --label "PreLoader" --loader /EFI/systemd/PreLoader.efi

XEFI システムパーティションのドライブ文字に、Y は同じくパーティション番号に置き換えてください。

上記のエントリは起動リストの一番最初に追加する必要があります。efibootmgr コマンドで確認して、必要であればブートローダーの設定を変更してください。

フォールバック

カスタム NVRAM エントリの起動に問題が発生する場合、HashTool.efiloader.efi を UEFI によって自動的に起動されるデフォルトのブートローダーの場所にコピーしてください:

# cp /usr/share/preloader-signed/HashTool.efi esp/EFI/Boot
# cp esp/EFI/systemd/systemd-bootx64.efi esp/EFI/Boot/loader.efi

PreLoader.efi をコピーして名前を変更します:

# cp /usr/share/preloader-signed/PreLoader.efi esp/EFI/Boot/bootx64.efi

Windows にしか対応しない非協力的な UEFI 実装の場合、PreLoader.efi を Windows で使用されるデフォルトローダーの場所にコピーしてください:

# mkdir -p esp/EFI/Microsoft/Boot
# cp /usr/share/preloader-signed/PreLoader.efi esp/EFI/Microsoft/Boot/bootmgfw.efi
ノート: Windows とデュアルブートする場合、元の bootmgfw.efi はバックアップしておいてください。ファイルを置き換えると Windows のアップデートで問題が発生する可能性があります。

上と同じように、HashTool.efiloader.efiesp/EFI/Microsoft/Boot にコピーしてください。

Secure Boot を有効にした状態でシステムを起動したら、上のセクションの手順に従って loader.efi/vmlinuz-linux (あるいは使用している他のカーネルイメージ) を登録します。

PreLoader の削除

ノート: 以下を実行する前にバックアップを作成すると良いでしょう。

インストールした preloader-signedAUR パッケージやコピーしたファイルを削除して、設定を元に戻します。systemd-boot の場合、以下を実行:

# rm esp/EFI/systemd/{PreLoader,HashTool}.efi
# rm esp/EFI/systemd/loader.efi
# efibootmgr -b N -B
# bootctl update

NPreLoader.efi を起動するために作成した NVRAM のブートエントリに置き換えてください。efibootmgr コマンドで確認を行なって、必要に応じてブート順序を修正してください。

ノート: 上記のコマンドは一番簡単な場合です。他のファイルを作成した場合はそれらも削除する必要があります。

shim

起動時に shim は grubx64.efi を実行しようとします。MokList に grubx64.efi のハッシュあるいは署名鍵が存在しない場合、shim は mmx64.efi を起動します。MokManager で起動したい EFI バイナリ (ブートローダー (grubx64.efi) とカーネル) のハッシュか署名鍵を登録する必要があります。

ノート: ハッシュを使用する場合、バイナリ (ブートローダーやカーネル) をアップデートするたびに新しいハッシュの登録が必要です。

shim の設定

shim-signedAURインストールしてください。

使用している ブートローダーの名前を grubx64.efi に変更してください:

# mv esp/EFI/BOOT/BOOTX64.efi esp/EFI/BOOT/grubx64.efi

shimMokManager を ESP のブートローダーディレクトリにコピーします。ブートローダーの元の名前を shimx64.efi の名前として使います:

# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTX64.efi
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/

shim は Machine Owner Key と MokList に保存されたハッシュでバイナリを認証できます:

Machine Owner Key (MOK)
ユーザーが生成して EFI バイナリの署名に使用する鍵。
ハッシュ
EFI バイナリの SHA256 ハッシュ。

ハッシュを使うほうが簡単ですが、ブートローダーやカーネルのアップデートのたびに MokManager でハッシュを追加する必要があります。MOK を使用する場合、鍵の追加は一度だけですが、ブートローダーやカーネルをアップデートするたびに署名が必要です。

shim でハッシュを使う

shim は MokList に grubx64.efi の SHA256 ハッシュが存在しない場合、mmx64.efi を起動します。

MokManagerEnroll hash from disk を選択してから grubx64.efi を探して MokList に追加してください。同じようにカーネルの vmlinuz-linux も追加してください。完了したら Continue boot を選択してください。ブートローダーが起動してカーネルが起動します。

shim で鍵を使う

sbsigntools をインストールしてください。

以下のファイルが必要です:

.key
EFI バイナリに署名するための PEM 形式の秘密鍵。
.crt
sbsign で使うための PEM 形式の証明書。
.cer
MokManager で使うための DER 形式の証明書。

Machine Owner Key を作成:

$ openssl req -newkey rsa:2048 -nodes -keyout MOK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Machine Owner Key/" -out MOK.crt
$ openssl x509 -outform DER -in MOK.crt -out MOK.cer

(grubx64.efi という名前の) ブートローダーとカーネルに署名:

# sbsign --key MOK.key --cert MOK.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux
# sbsign --key MOK.key --cert MOK.crt --output esp/EFI/BOOT/grubx64.efi esp/EFI/BOOT/grubx64.efi

ブートローダーとカーネルをアップデートするたびに上記の署名が必要です。

MOK.cer を FAT でフォーマットされたファイルシステムにコピーしてください (EFI System Partition を使うことができます)。

再起動してセキュアブートを有効にしてください。shim は MokList に grubx64.efi を署名するときに使った証明書がない場合、mmx64.efi を起動します。

MokManagerEnroll key from disk を選択してから MOK.cer を探して MokList に追加してください。完了したら Continue boot を選択してください。ブートローダーが起動して、Machine Owner Key で署名されたバイナリを起動できるようになります。

shim の削除

shim-signedAURアンインストールして、コピーした shimMokManager のファイルを削除してブートローダーを元の名前に戻してください。

自分で署名した鍵を使う

ヒント:
  • Rod Smith's Controlling Secure Boot を読むことを推奨します。
  • cryptbootAUR パッケージに含まれている cryptboot-efikeys スクリプトを使うことで鍵の作成・登録・ブートローダーの署名・署名の検証が簡単に行なえます。

Secure Boot では以下の鍵が使われます:

Platform Key (PK)
トップレベル鍵
Key Exchange Key (KEK)
署名データベースや EFI バイナリに署名するのに使われる鍵
Signature Database (db)
EFI バイナリに署名するのに使われる鍵やハッシュが含まれます
Forbidden Signatures Database (dbx)
EFI バイナリをブラックリスト化するのに使われる鍵やハッシュが含まれます

詳しい説明は The Meaning of all the UEFI Keys を見てください。

カスタム鍵

Secure Boot を使用するには最低でも PK, KEK, db 鍵が必要です。KEK, db, dbx 証明書は複数追加できますが、Platform Key はひとつしか使えません。

Secure Boot を "User Mode" にすると、上位の鍵を使用してアップデートに署名しないかぎり鍵を更新できなくなります (sign-efi-sig-list を使用)。Platform key は自分自身で署名することができます。

鍵の作成

鍵を生成するには、efitoolsインストールが必要です。

鍵と複数の形式の証明書を作成する必要があります:

  1. 鍵を作成して sbsign のための PEM 形式の証明書を作成
  2. ファームウェア用に証明書を DER 形式に変換
  3. KeyTool のために証明書を EFI Signature List に変換
.key
EFI バイナリと EFI 署名リストの署名に必要な PEM 形式の秘密鍵。
.crt
sbsign で必要な PEM 形式の証明書。
.cer
ファームウェアが使用する DER 形式の証明書。
.esl
KeyTool やファームウェアのための EFI 署名リストの証明書。
.auth
KeyTool やファームウェアのための認証ヘッダが付いた EFI 署名リストの証明書 (署名済みの証明書アップデートファイル)。

所有者を識別する GUID を作成:

$ uuidgen --random > GUID.txt

Platform Key:

$ openssl req -newkey rsa:2048 -nodes -keyout PK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Platform Key/" -out PK.crt
$ openssl x509 -outform DER -in PK.crt -out PK.cer
$ cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl
$ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth

空のファイルを使って "User Mode" で Platform Key を削除できるように署名:

$ sign-efi-sig-list -g "$(< GUID.txt)" -c PK.crt -k PK.key PK /dev/null rm_PK.auth

Key Exchange Key:

$ openssl req -newkey rsa:2048 -nodes -keyout KEK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Key Exchange Key/" -out KEK.crt
$ openssl x509 -outform DER -in KEK.crt -out KEK.cer
$ cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl
$ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl KEK.auth

Signature Database:

$ openssl req -newkey rsa:2048 -nodes -keyout db.key -new -x509 -sha256 -days 3650 -subj "/CN=my Signature Database key/" -out db.crt
$ openssl x509 -outform DER -in db.crt -out db.cer
$ cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl
$ sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth

鍵のアップデート

一度 Secure Boot を "User Mode" にしたら KEK, db, dbx を変更するには上位の鍵による署名が必要です。

例えば、db 鍵を新しく置き換えたい場合:

  1. 新しい鍵を作成
  2. EFI 署名リストに変換
  3. EFI 署名リストに署名
  4. 署名された証明書アップデートファイルを登録
$ cert-to-efi-sig-list -g "$(< GUID.txt)" new_db.crt new_db.esl
$ sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db new_db.esl new_db.auth

db 鍵を置き換えるかわりに Signature Database に別の鍵を追加したい場合、-a オプションを使う必要があります (sign-efi-sig-list(1) を参照):

$ sign-efi-sig-list -a -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db new_db.esl new_db.auth

new_db.auth が作成されたら登録してください。

ブートローダーとカーネルの署名

Secure Boot を有効にすると ("User Mode")、署名したバイナリしか起動できなくなるため、カーネルとブートローダーに署名が必要です。

sbsigntools をインストールしてください。

ノート: --output を付けずに sbsign を実行すると作成されるファイルは filename.signed となります。詳しくは sbsign(1) を参照。
# sbsign --key db.key --cert db.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux
# sbsign --key db.key --cert db.crt --output esp/EFI/BOOT/BOOTX64.EFI esp/EFI/BOOT/BOOTX64.EFI
ヒント:
  • バイナリが署名されたかどうか確認するには: $ sbverify --list /path/to/binary
  • sbupdate-gitAUR を使うことでアップデート時にカーネルを自動的に署名できます。保護されていない initramfs とカーネルコマンドラインが署名済みの UEFI イメージに組み込まれてしまう可能性があるため注意してください。

pacman フックを使ってカーネルに署名

pacman フックを使ってカーネルのインストール・アップデート時に署名することも可能です。

/etc/pacman.d/hooks/99-secureboot.hook
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = linux

[Action]
Description = Signing Kernel for SecureBoot
When = PostTransaction
Exec = /usr/bin/sbsign --key db.key --cert db.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux
Depends = sbsigntools

ファームウェアを "Setup Mode" にする

Platform Key を削除するとき Secure Boot は Setup Mode になります。ファームウェアを Setup Mode にするには、ファームウェアのセットアップユーティリティを起動して証明書を削除・消去するオプションを探して下さい。

ファームウェアに鍵を登録

*.cer, *.esl, *.auth を全て FAT でフォーマットされたファイルシステムにコピーしてください (EFI システムパーティションを使うことができます)。

ファームウェアのセットアップユーティリティあるいは KeyTool を起動して db, KEK, PK 証明書を登録してください。

使用しているツールが .auth.esl をサポートしている場合 .cer よりも優先して使って下さい。

警告: Platform Key を登録すると Secure Boot が "User Mode" になるため、Platform Key は最後に登録してください。

ファームウェアのセットアップユーティリティを使う

ファームウェアには様々なインターフェイスがあります。鍵を登録する例が Replacing Keys Using Your Firmware's Setup Utility に載っています。

KeyTool を使う

KeyTool.efiefitools パッケージに含まれているので、ESP にコピーしてください。鍵を登録した後に使用するには、sbsign で署名する必要があります:

# sbsign --key db.key --cert db.crt --output esp/EFI/KeyTool-signed.efi /usr/share/efitools/efi/KeyTool.efi

ファームウェアのセットアップユーティリティやブートローダー、あるいは UEFI シェルKeyTool-signed.efi を起動して鍵を登録してください。

KeyTool のメニューオプションの解説は Replacing Keys Using KeyTool を参照。

他のオペレーティングシステムとのデュアルブート

Microsoft Windows

Windows のデュアルブートをするには、Microsoft の証明書を Signature Database に追加する必要があります。Microsoft は2つの db 証明書を用意しています:

Microsoft の証明書は DER 形式なので、openssl で PEM 形式に変換してください:

$ openssl x509 -inform DER -outform PEM -in MicWinProPCA2011_2011-10-19.crt -out MicWinProPCA2011_2011-10-19.crt.pem
$ openssl x509 -inform DER -outform PEM -in MicCorUEFCA2011_2011-06-27.crt -out MicCorUEFCA2011_2011-06-27.crt.pem

Microsoft の GUID (77fa9abd-0359-4d32-bd60-28f4e78f784b) を使って EFI 署名リストを作成してひとつのファイルにまとめます:

$ cert-to-efi-sig-list -g 77fa9abd-0359-4d32-bd60-28f4e78f784b MicWinProPCA2011_2011-10-19.crt.pem MS_Win_db.esl
$ cert-to-efi-sig-list -g 77fa9abd-0359-4d32-bd60-28f4e78f784b MicCorUEFCA2011_2011-06-27.crt.pem MS_UEFI_db.esl
$ cat MS_Win_db.esl MS_UEFI_db.esl > MS_db.esl

KEK を使って db アップデートに署名してください。sign-efi-sig-list-a オプションを付けて db 証明書を追加します:

$ sign-efi-sig-list -a -g 77fa9abd-0359-4d32-bd60-28f4e78f784b -k KEK.key -c KEK.crt db MS_db.esl add_MS_db.auth

#ファームウェアに鍵を登録に従って add_MS_db.auth を Signature Database に追加してください。

Secure Boot の無効化

Secure Boot 機能は UEFI ファームウェアのインターフェイスから無効化することができます。ファームウェアの設定を開くには起動時に特定のキーを押下します。ファームウェアによって押すキーは違います。大抵は Esc, F2, Del, Fn キーのどれかです。

ホットキーが使用できず Windows が起動する場合、次の方法で強制的にファームウェア設定を開くように再起動できます (Windows 10 の場合): Settings > Update & Security > Recovery > Advanced startup (Restart now) > Troubleshoot > Advanced options > UEFI Firmware settings > restart

一部のマザーボード (例: Packard Bell 製ノートパソコン) では、管理者パスワードを設定しないとセキュアブートを無効化できません (無効化した後に管理者パスワードは消去できます)。Rod Smith の Secure Boot 無効化に関する記事 も参照。

参照