Unified Extensible Firmware Interface/セキュアブート
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.efi
と HashTool.efi
が archiso に追加されたことで Secure Boot を有効にして archiso を起動することが可能になりました。Failed to Start loader... I will now execute HashTool
というメッセージが表示されます。HashTool を使って loader.efi
と vmlinzu.efi
のハッシュを登録するには、以下の手順に従って下さい:
OK
を選択してください- HashTool のメインメニューから
Enroll Hash
を選択し、\loader.efi
を選んでYes
で確定します。また、Enroll Hash
とarchiso
を選択して 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/efivars/SecureBoot-1234abcde-5678-
このコマンドで返ってくるリストの最後が 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 の設定
preloader-signedAUR パッケージをインストールして PreLoader.efi
と HashTool.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
X
は EFI システムパーティションのドライブ文字に、Y
は同じくパーティション番号に置き換えてください。
上記のエントリは起動リストの一番最初に追加する必要があります。efibootmgr
コマンドで確認して、必要であればブートローダーの設定を変更してください。
フォールバック
カスタム NVRAM エントリの起動に問題が発生する場合、HashTool.efi
と loader.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
上と同じように、HashTool.efi
と loader.efi
を esp/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
N
は PreLoader.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
shim と MokManager を 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
を起動します。
MokManager で Enroll 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
を起動します。
MokManager で Enroll key from disk を選択してから MOK.cer
を探して MokList に追加してください。完了したら Continue boot を選択してください。ブートローダーが起動して、Machine Owner Key で署名されたバイナリを起動できるようになります。
shim の削除
shim-signedAUR をアンインストールして、コピーした shim と MokManager のファイルを削除してブートローダーを元の名前に戻してください。
自分で署名した鍵を使う
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 のインストールが必要です。
鍵と複数の形式の証明書を作成する必要があります:
- 鍵を作成して
sbsign
のための PEM 形式の証明書を作成 - ファームウェア用に証明書を DER 形式に変換
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 鍵を新しく置き換えたい場合:
- 新しい鍵を作成
- EFI 署名リストに変換
- EFI 署名リストに署名
- 署名された証明書アップデートファイルを登録
$ 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 をインストールしてください。
# 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
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
よりも優先して使って下さい。
ファームウェアのセットアップユーティリティを使う
ファームウェアには様々なインターフェイスがあります。鍵を登録する例が Replacing Keys Using Your Firmware's Setup Utility に載っています。
KeyTool を使う
KeyTool.efi
は efitools パッケージに含まれているので、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 Windows Production PCA 2011 (Windows 用)
- Microsoft Corporation UEFI CA 2011 (UEFI ドライバーやオプション ROM などサードパーティ製のバイナリ用)
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 無効化に関する記事 も参照。
参照
- Wikipedia:ja:Unified Extensible Firmware Interface#セキュアブート
- Dealing with Secure Boot by Rod Smith
- Controlling Secure Boot by Rod Smith
- UEFI secure booting (part 2) by Matthew Garrett
- UEFI Secure Boot by James Bottomley
- efitools README
- Will your computer's "Secure Boot" turn out to be "Restricted Boot"? — Free Software Foundation
- Free Software Foundation recommendations for free operating system distributions considering Secure Boot