UEFI Secure Boot とは?
UEFI Secure Boot は、ファームウェアによって起動されたコードが確実に信頼できるという検証機構である。
UEFI Secure Boot を適切に、安全に使用するには、起動時にロードされる各バイナリが、ファームウェア内にある、信頼できるベンダーやバイナリのソース、または暗号ハッシュを介して識別できる信頼できる特定のバイナリを示す既知のキーに対して検証されることが必要です。
ほとんどの x86 ハードウェアは、Microsoft の鍵があらかじめロードされた状態で工場から出荷されます。 これは、一般に、これらのシステムのファームウェアが Microsoft によって署名されたバイナリを信頼することに依存しており、Linux コミュニティは Secure Boot が動作するためにこの仮定に大きく依存していることを意味します。 これは、例えば Red Hat や SUSE で使用されているのと同じプロセスです。
多くの ARM やその他のアーキテクチャも UEFI Secure Boot をサポートしていますが、ファームウェアにキーをプリロードしていないかもしれません。 これらのアーキテクチャでは、ハードウェアの所有者によってファームウェアに読み込まれた証明書でブートイメージに再署名することが必要かもしれません。
初期の実装計画。 実装計画です。
サポートされるアーキテクチャ
-
amd64: Microsoft の署名入り shim バイナリと Canonical の署名入り grub バイナリが shim-signed または grub-efi-amd64-signed として Ubuntu main archive で提供されています。
-
arm64: 20.04 (‘focal’) では、Ubuntu main archive で Microsoft 署名の shim バイナリと Canonical 署名の grub バイナリが shim-signed または grub-efi-arm64-signed で提供されます。 GRUBのバグが調査中であり、これを解決しないとエンドツーエンドで動作しません。
Testing UEFI Secure Boot
If you’re interested to test Secure Boot on your system, refer the how-to here.を参照してください。 UEFI/SecureBoot/Testing を参照してください。
How UEFI Secure Boot works on Ubuntu
Ubuntu では、initrd イメージを除き、ブートプロセスの一部としてロードされる予定のすべてのプリビルドバイナリは Canonical の UEFI 証明書で署名されており、Microsoft によって署名されている shim ローダーに組み込まれているので暗黙的に信頼されているのです。
Microsoft からのプリロードされた署名証明書が利用できない、またはファームウェアにロードされないアーキテクチャまたはシステムでは、ユーザーは shim または grub の既存の署名を置き換え、システムのファームウェアにインポートした独自の証明書と検証しながら、希望に応じてロードすることが可能です。
システムが起動すると、ファームウェアはファームウェアの BootEntry 変数で指定されたように shim バイナリをロードします。 Ubuntu は、インストール時に独自の BootEntry をインストールし、GRUB ブートローダーが更新されるたびにそれを更新することができます。 shimバイナリはMicrosoftによって署名されているため、ファームウェアにすでに存在する証明書と照合する際に、ファームウェアによって検証され、受け入れられます。 shim バイナリは、それ自身の信頼データベースと同様に Canonical 証明書を埋め込むので、ブート環境のさらなる要素は、ファームウェアにあらかじめロードされた許容可能な証明書のいずれかによって署名されることに加えて、Canonical の UEFI キーによって署名されることが可能です。
shim によって次にロードされるのは、セカンドステージのイメージです。 これは、システムが正常に起動している場合は GRUB、またはファームウェア変数 (通常、システムが以前に起動していたときに変更された) によって設定された鍵管理が必要な場合は MokManager のどちらかになります。
正常に起動している場合、GRUB バイナリ (grub*.efi) がロードされ、その検証は以前に知られていたすべての信頼できるソースに対して試行されます。 Ubuntu用のGRUBバイナリはCanonical UEFIキーによって署名されているため、正常に検証され、ブートプロセスが継続されます。
鍵管理タスクを続行するためにブートする場合、MokManager バイナリ (mm*.efi) がロードされます。 このバイナリは、shim バイナリが構築されている間のみ存在するエフェメラル キーによって署名されることにより、shim によって明示的に信頼されます。 つまり、特定のshimバイナリでビルドされたMokManagerバイナリのみが実行を許可され、妥協したツールの使用による侵害の可能性を制限しています。 MokManagerでは、システムコンソールにいるすべてのユーザが、キーの登録、信頼できるキーの削除、バイナリハッシュの登録、およびシムレベルでのセキュアブート検証の切り替えができますが、ほとんどのタスクでは、コンソールにいるユーザが本当に変更要求者であることを確認するために事前に設定したパスワードの入力が必要です。 このようなパスワードは、shim/MokManagerを1回実行する間だけ有効で、プロセスが完了するかキャンセルされるとすぐにクリアされます。 キーマネージメントが完了すると、システムはリブートされ、キーマネージメントの変更がブートを正常に完了するために必要となる場合があるため、単純にブートを続行することはできません。
一旦システムが GRUB へのブートを継続すると、GRUB プロセスは必要な設定を読み込み (通常は ESP (EFI System Partition) から設定を読み込み、ルートまたは起動パーティション上の別の設定ファイルを指す)、それをロードするカーネルイメージに指し示すことになる。
EFI アプリケーションは、信頼されたファームウェア変数の変更へのアクセスを含め、システム ファームウェアへのフル アクセスを持つこの時点まで、ロードするカーネルも信頼データベースに対して検証される必要があります。 公式 Ubuntu カーネルは Canonical UEFI キーによって署名され、正常に検証され、制御がカーネルに引き渡されます。 Initrdイメージは検証されません。
非公式カーネル、またはユーザーが構築したカーネルの場合、ユーザーが UEFI Secure Boot の全機能を保持しながらそのようなカーネルをロードしたい場合、追加のステップを踏む必要があります。 UEFI Secure Boot が有効になっているときに GRUB によってロードすることを許可されるためには、全てのカーネルは署名されていなければなりませんので、ユーザーは自分自身で署名を進める必要があります。 代わりに、ユーザーは公式カーネルでセキュアブートを有効にして起動している間、shim で ‘sudo mokutil –disable-validation’ を使って検証を無効にし、プロンプトが出たらパスワードを入力して再起動するか、ファームウェアのセキュアブートを完全に無効にしたい場合があります。
この時点まで、ロードするイメージの検証に失敗すると、重大なエラーが発生し、ブートプロセスが停止します。 システムはブートを続行せず、他の BootEntry 変数が有効で信頼できるブートパスを含む可能性があるため、一定時間後に自動的に再起動することがあります。
いったんロードされると、検証済みのカーネルはファームウェアのブート サービスを無効にするため、特権を停止し、事実上ユーザー モードに切り替わり、信頼できる変数へのアクセスは読み取り専用に制限されます。 カーネル モジュールに与えられた幅広い権限を考えると、カーネルに組み込まれていないすべてのモジュールは、ロード時に検証される必要があります。 Canonicalがビルドして公式カーネルと一緒に出荷したモジュールは、Canonical UEFIキーで署名されており、そのため、信頼されています。 カスタムビルドモジュールは、カーネルによってロードが許可される前に、ユーザーがモジュールに署名するために必要なステップを踏む必要があります。 これは ‘kmodsign’ コマンドを使用することで達成できます。
署名されていないモジュールは、カーネルによって単に拒否されます。 insmod や modprobe を使ってそれらを挿入しようとすると、 エラーメッセージとともに失敗します。
多くのユーザーが、システムを正しく動作させるため、または一部のデバイスを機能させるためにサードパーティ製モジュールを必要とし、これらのサードパーティ製モジュールは実行中のカーネルに適合させるためにシステム上でローカルに構築しなければならないことを考慮して、Ubuntu は署名プロセスを自動化して単純化するツールを提供しています。
ドライバーの自動化されていない署名を行うにはどうしたらよいでしょうか。
プロジェクトによっては、DKMS で動作するように設定されていないカスタムカーネルドライバーを使用する必要があるかもしれません。 update-secureboot-policy スクリプトは、新しい MOK を生成するために利用可能です (どの DKMS 構築モジュールもすでに生成するきっかけを与えていない場合)。
既存のキーを shim に登録するには、次のコマンドを使用します。
sudo update-secureboot-policy --enroll-key
MOKが存在しない場合、スクリプトはその旨のメッセージを表示して終了します。 鍵がすでに登録されている場合、スクリプトは何もせずに終了します。 キーは存在するが登録されていない場合、キーが登録されるように、再起動後に使用するパスワードの入力をユーザーに要求します。
次のコマンドを使用して、新しいMOKを生成することができます。
sudo update-secureboot-policy --new-key
そして、新しく生成されたキーを、そのタスクのための前述のコマンドでshimに登録します。
そして、カーネルモジュールは、ビルドプロセスの一部として kmodsign コマンド (UEFI/SecureBoot/Signing 参照) で署名することが可能です。
Security implications in Machine-Owner Key management
MOK の制限を示す特定の KeyUsage OID (1.3.6.1.4.1.2312.16.1.2) によって、インストール時またはアップグレード時に生成される MOK はマシン固有で、カーネルまたはシムによってのみカーネル モジュールへの署名が許可されます。
最近のシムバージョンには、モジュール署名のみのキーの制限に従うためのロジックが含まれています。 これらのキーは、shim の信頼データベースにあるファームウェアに登録することは許可されますが、shim または GRUB がファームウェアにロードするイメージを検証するときは、無視されます。 Shim の verify() 関数は、Module-signing only (1.3.6.1.4.1.2312.16.1.2) という OID を持たない鍵で署名されたイメージのみを正常に検証します。 Ubuntuカーネルは、グローバルトラストデータベース(shimとファームウェアの両方を含む)を使用し、カーネルモジュールをロードするときに署名キーとして含まれている鍵のいずれかを受け入れます。
自動的に生成される MOK に課せられた制限と、システムへのスーパーユーザー アクセスおよび鍵の登録時に必要なパスワードを入力するシステム コンソールへのアクセスを持つユーザーがすでにシステムへのハイレベルなアクセスを持っているという事実を考慮して、生成された MOK 鍵はファイルシステム上に root が所有し読み取り専用パーミッションを持つ通常ファイルとして保持されます。 これは、悪意のあるユーザーやスクリプトによる署名用MOKへのアクセスを制限するのに十分であると考えられる。特に、サードパーティのドライバを必要としない限り、システム上にMOKが存在しないことを考えると、このような仕組みが必要である。 これは、生成されたMOK鍵の悪用から、悪意のあるカーネルモジュールへの署名への侵害の可能性を制限するものです。 これは、スーパーユーザーがシステムにアクセスすることで既に可能となるユーザーランドアプリケーションの侵害と同等であり、これを確保することは UEFI セキュアブートの範囲外です。
以前のシステムでは、shim で Secure Boot 検証が無効になっていたかもしれません。 アップグレードプロセスの一部として、これらのシステムはshimでセキュアブート検証を再度有効にし、該当する場合は新しいMOKキーを登録するように移行されます。
MOK 生成および署名プロセス
キー生成および署名プロセスは、新規インストールを扱うか、以前 Ubuntu を実行していたシステムのアップグレードを扱うかによって若干異なっています。
すべての場合において、システムが UEFI モードで起動していない場合、特別なカーネルモジュール署名ステップや鍵生成は行われません。
Secure Boot が無効な場合、ユーザーが後で Secure Boot を有効にできるため、MOK 生成および登録はまだ行われます。 この場合、システムは正常に動作するはずです。
ユーザーが新しいシステムに Ubuntu をインストールする
ユーザーはインストーラーをステップ実行します。 インストールの準備の初期段階で、システムが動作するためにサードパーティ製モジュールを必要とする場合にのみ、インストール完了後に必要であることが明確に示されているシステム パスワードの入力を求められ、システムのインストール中は、それ以上ユーザーが操作しなくても、新しい MOK が自動的に生成されます。
システムが必要とするサードパーティ製ドライバーまたはカーネル モジュールは、パッケージがインストールされると自動的にビルドされ、ビルド プロセスには署名ステップが含まれます。 署名ステップでは、システムが再起動され、MOK がシステムの信頼データベースに含まれると、すぐにロードできるように、以前に生成された MOK を使用して自動的にモジュールに署名します。
インストールが完了し、システムが再起動すると、最初の起動時に、ユーザーには MokManager プログラム (インストールされたシム ローダーの一部) が、生成された MOK を登録するためのテキスト モード パネルのセットとして表示されます。 ユーザーは「Enroll MOK」を選択し、登録する証明書のフィンガープリントを表示し、登録を確認するよう促されます。 確認後、新しいMOKがファームウェアに入力され、ユーザーはシステムの再起動を要求されます。
システムが再起動すると、登録されたばかりのMOKによって署名されたサードパーティードライバーが必要に応じてロードされます。
ユーザーが UEFI 対応の Ubuntu システムを、システムがサードパーティ製ドライバーを必要とする新しいリリースにアップグレードする場合
アップグレード時に、shim および shim-signed パッケージがアップグレードされます。 shim-signed パッケージのインストール後のタスクは、新しい MOK を生成し、アップグレード処理が完了し、システムが再起動すると、必要であることが明確に言及されているパスワードのためにユーザーにプロンプトを表示します。
アップグレードの間、カーネルパッケージとサードパーティモジュールがアップグレードされます。 サードパーティモジュールは新しいカーネル用に再構築され、その構築後のプロセスは自動的に MOK で署名するよう進行します。
アップグレード後、ユーザはシステムの再起動を推奨されます。
再起動すると、ユーザーは MokManager プログラム (インストールされた shim ローダーの一部) をテキストモードのパネルとして表示され、生成された MOK を登録するように指示されます。 ユーザーは「MOKを登録する」を選択し、登録する証明書のフィンガープリントを表示し、登録を確認するよう促される。 また、セキュアブート検証を再度有効にするプロンプトが表示され(無効になっている場合)、MokManagerは再びユーザーの確認を要求します。 すべての手順が確認されると、シム検証が再度有効になり、新しいMOKがファームウェアに入力され、ユーザーはシステムを再起動するように要求されます。
システムが再起動すると、登録されたばかりの MOK によって署名されたサード パーティ製ドライバーが必要に応じてロードされます。
すべての場合において、システムが UEFI Secure Boot を有効にし、shim の最新バージョンで実行されると、新しい DKMS モジュール (サード パーティ製ドライバー) のインストールは、ビルドしたモジュールに MOK で署名するために進行します。 有効な MOK キーがシステム上に存在し、すでに登録されているようであれば、ユーザーの操作なしでこれは行われます。
MOK が存在しないか、既存の MOK が登録されていない場合、署名の直前に新しい鍵が自動的に作成され、再起動時に要求されるパスワードを入力して鍵を登録するようにユーザーに要求されます。