1.9. セキュアブート用のカーネルモジュールの署名
Red Hat Enterprise Linux 7 には UEFI セキュアブート機能が含まれているので、Red Hat Enterprise Linux 7 は UEFI セキュアブートが有効になっているシステム上でインストールし、実行できます。Red Hat Enterprise Linux 7 では、UEFI システムでセキュアブートを使用する必要がないことにご留意ください。
セキュアブートが有効な場合は、UEFI オペレーティングシステムのブートローダー、Red Hat Enterprise Linux カーネル、およびすべてのカーネルモジュールを秘密鍵で署名し、それに対応する公開鍵で認証する必要があります。それらが署名・認証されてなければ、システムは起動プロセスを終了できません。
Red Hat Enterprise Linux 7 ディストリビューションには、以下が含まれます。
- 署名付きブートローダー
- 署名済みカーネル
- 署名済みカーネルモジュール
また、署名された第 1 ステージのブートローダーと署名されたカーネルには、組み込み Red Hat 公開鍵が含まれています。これらの署名済みバイナリーおよび組み込み鍵により、Red Hat Enterprise Linux 7 は UEFI セキュアブート対応のシステムで、UEFI ファームウェアが提供する Microsoft UEFI セキュアブート認証局キーを使用してインストール、ブート、および実行できます。
セキュアブートのサポートは、すべての UEFI ベースのシステムに含まれるわけではありません。
以下のセクションでは、セキュアブートが有効になっている UEFI ベースのビルドシステム上で Red Hat Enterprise Linux 7 に使用する、プライベートで構築されたカーネルモジュールへの自己署名に必要な手順を説明しています。また、カーネルモジュールのデプロイメントを希望するターゲットシステムに公開鍵をインポートするのに利用可能なオプションについても説明しています。
カーネルモジュールに署名して読み込むには、以下を行う必要があります。
1.9.1. 前提条件
外部でビルドされたカーネルモジュールに署名できるようにするには、次の表にリストされているユーティリティーをビルドシステムにインストールします。
ユーティリティー | 提供するパッケージ | 使用対象 | 目的 |
---|---|---|---|
|
| ビルドシステム | 公開および秘密 X.509 鍵のペアを生成 |
|
| ビルドシステム | カーネルモジュールの署名に使用する Perl スクリプト |
|
| ビルドシステム | 署名スクリプトの実行に使用する Perl インタープリター |
|
| ターゲットシステム | 公開鍵を手動で登録する際に使用するオプションのユーティリティー |
|
| ターゲットシステム | システムキーリングに公開鍵を表示する際に使用するオプションのツール |
カーネルモジュールを構築、署名するビルドシステムは、UEFI セキュアブートを有効にする必要がなく、UEFI ベースのシステムである必要すらありません。
1.9.2. カーネルモジュールの認証
Red Hat Enterprise Linux 7 では、カーネルモジュールの読み込み時に、カーネルのシステムキーリング上の公開 X.509 鍵を使用してモジュールの署名をチェックします。使用される鍵は、カーネルのシステムブラックリストのキーリングにあるものを除きます。次のセクションでは、キー/キーリングのソースの概要、システム内のさまざまなソースからロードされたキーの例を示します。また、ユーザーは、カーネルモジュールの認証に必要なものを確認することができます。
1.9.2.1. カーネルモジュール認証に使用する公開鍵のソース
ブート中にカーネルは、以下の表にある永続的キーストア一式から X.509 鍵をシステムキーリングまたはシステムのブラックリストに読み込みます。
X.509 鍵のソース | キー追加に関するユーザー能力 | UEFI セキュアブートの状態 | ブート中に読み込まれる鍵 |
---|---|---|---|
カーネルに埋め込み | いいえ | - |
|
UEFI セキュアブート "db" | 限定的 | 有効でない | いいえ |
有効 |
| ||
UEFI セキュアブート "dbx" | 限定的 | 有効でない | いいえ |
有効 |
| ||
| いいえ | 有効でない | いいえ |
有効 |
| ||
Machine Owner Key (MOK) リスト | はい | 有効でない | いいえ |
有効 |
|
システムが UEFI ベースでない場合、または UEFI セキュアブートが有効になっていない場合は、カーネルに組み込まれた鍵のみがシステムのキーリングに読み込まれます。この場合、カーネルの再構築なしでキーセットを拡張することはできません。
システムのブラックリストキーリングは、無効にされた X.509 鍵のリストです。ブラックリストにある鍵でモジュールが署名されていると、公開鍵がシステムのキーリングにあったとしても、モジュールは認証に失敗します。
システムのキーリング上にある鍵についての情報は、keyctl
ユーティリティーを使うと表示できます。以下は、UEFI セキュアブートが有効になっていない Red Hat Enterprise Linux 7 システムからの短い出力例です。
# keyctl list %:.system_keyring 3 keys in keyring: ...asymmetric: Red Hat Enterprise Linux Driver Update Program (key 3): bf57f3e87... ...asymmetric: Red Hat Enterprise Linux kernel signing key: 4249689eefc77e95880b... ...asymmetric: Red Hat Enterprise Linux kpatch signing key: 4d38fd864ebe18c5f0b7...
以下は、UEFI セキュアブートが有効になっている Red Hat Enterprise Linux 7 システムからの短い出力例です。
# keyctl list %:.system_keyring 6 keys in keyring: ...asymmetric: Red Hat Enterprise Linux Driver Update Program (key 3): bf57f3e87... ...asymmetric: Red Hat Secure Boot (CA key 1): 4016841644ce3a810408050766e8f8a29... ...asymmetric: Microsoft Corporation UEFI CA 2011: 13adbf4309bd82709c8cd54f316ed... ...asymmetric: Microsoft Windows Production PCA 2011: a92902398e16c49778cd90f99e... ...asymmetric: Red Hat Enterprise Linux kernel signing key: 4249689eefc77e95880b... ...asymmetric: Red Hat Enterprise Linux kpatch signing key: 4d38fd864ebe18c5f0b7...
上記の出力では、UEFI セキュアブート "db" 鍵から加わった 2 つの鍵と、shim.efi
ブートローダーに組み込まれている Red Hat Secure Boot (CA key 1)
が示されています。UEFI セキュアブート関連のソースを使用してキーを識別するカーネルコンソールメッセージを検索することもできます。これには、UEFI セキュアブート db、組み込み shim、および MOK リストが含まれます。
# dmesg | grep 'EFI: Loaded cert' [5.160660] EFI: Loaded cert 'Microsoft Windows Production PCA 2011: a9290239... [5.160674] EFI: Loaded cert 'Microsoft Corporation UEFI CA 2011: 13adbf4309b... [5.165794] EFI: Loaded cert 'Red Hat Secure Boot (CA key 1): 4016841644ce3a8...
1.9.2.2. カーネルモジュール認証の要件
本セクションでは、UEFI セキュアブート機能が有効なシステムでカーネルモジュールを読み込むために必要な条件を説明します。
UEFI セキュアブートが有効な場合、または module.sig_enforce
カーネルパラメーターが指定されている場合は、システムのキーリングの鍵を使用して認証された署名済みカーネルモジュールのみを読み込むことができます。また、公開鍵は、システムのブラックリストキーリング上に存在すべきではありません。
UEFI セキュアブートが無効で module.sig_enforce
カーネルパラメーターが指定されていない場合は、公開鍵なしで、未署名カーネルモジュールと署名済みカーネルモジュールを読み込むことができます。これは、以下の表で説明されています。
モジュールの署名 | 公開鍵ありおよび署名が有効 | UEFI セキュアブートの状態 | sig_enforce | モジュールの読み込み | カーネルのテイント |
---|---|---|---|---|---|
署名なし | - | 有効でない | 有効でない | 成功 | はい |
有効でない | 有効 | 失敗 | - | ||
有効 | - | 失敗 | - | ||
署名あり | いいえ | 有効でない | 有効でない | 成功 | はい |
有効でない | 有効 | 失敗 | - | ||
有効 | - | 失敗 | - | ||
署名あり | はい | 有効でない | 有効でない | 成功 | いいえ |
有効でない | 有効 | 成功 | いいえ | ||
有効 | - | 成功 | いいえ |
1.9.3. 公開および秘密 X.509 鍵のペアの生成
セキュアブートを有効化したシステム上でカーネルモジュールを使用する作業を正常に行うには、公開および秘密 X.509 鍵ペアを生成する必要があります。後で秘密鍵を使用してカーネルモジュールに署名します。セキュアブートで署名済みモジュールを検証するには、適切な公開鍵を Machine Owner Key (MOK) に追加する必要があります。手順は、「システム管理者が手動で公開鍵を MOK リストに追加する」 を参照してください。
このキーペア生成のパラメーターの一部は、設定ファイルで指定するのが最適です。
キーペア生成のパラメーターで設定ファイルを作成します。
# cat << EOF > configuration_file.config [ req ] default_bits = 4096 distinguished_name = req_distinguished_name prompt = no string_mask = utf8only x509_extensions = myexts [ req_distinguished_name ] O = Organization CN = Organization signing key emailAddress = E-mail address [ myexts ] basicConstraints=critical,CA:FALSE keyUsage=digitalSignature subjectKeyIdentifier=hash authorityKeyIdentifier=keyid EOF
X.509 公開鍵と秘密鍵のペアを以下の例のように作成します。
# openssl req -x509 -new -nodes -utf8 -sha256 -days 36500 \ -batch -config configuration_file.config -outform DER \ -out my_signing_key_pub.der \ -keyout my_signing_key.priv
公開鍵は
my_signing_key_pub.der
ファイルに書き込まれます。この秘密鍵はmy_signing_key.priv
ファイルに書き込まれます。カーネルモジュールを認証、読み込むすべてのシステムに公開鍵を登録します。
詳細は、「公開鍵のターゲットシステムでの登録」 を参照してください。
強力なセキュリティー対策とアクセスポリシーを適用して、秘密鍵の内容を保護します。悪用すれば、この鍵は、一致する公開鍵で認証されるシステムのセキュリティーに危害を与えるために使用できます。
1.9.4. 公開鍵のターゲットシステムでの登録
セキュアブートが有効になっている UFEI ベースのマシンで Red Hat Enterprise Linux 7 を起動すると、無効化したキーの dbx データベースにあるものを除いて、セキュアブート db キーデータベースにあるすべてのパブリックキーのシステムキーにカーネルがロードされます。以下のセクションでは、システムキーリングが公開鍵を使用してカーネルモジュールを認証できるように、ターゲットシステムで公開鍵をインポートする方法を説明します。
1.9.4.1. 公開鍵を含むファクトリーファームウェアイメージ
システムでカーネルモジュールの認証を実現するために、ファクトリーファームウェアイメージで公開鍵を UEFI セキュアブート鍵データベースに組み入れるようシステムベンダーに要求することを検討します。
1.9.4.2. システム管理者が手動で公開鍵を MOK リストに追加する
Machine Owner Key (MOK) 機能を使用して、UEFI セキュアブートキーデータベースを拡張することができます。セキュアブートが有効になっている UEFI ベースのシステムで Red Hat Enterprise Linux 7 が起動すると、鍵データベースの鍵に加えて、MOK リストの鍵もシステムキーリングに追加されます。MOK リストの鍵は、セキュアブートデータベースの鍵と同様に永続的かつ安全な方法で保存されますが、これらは別個の機能です。MOK 機能は、shim.efi
、MokManager.efi
、grubx64.efi
および Red Hat Enterprise Linux 7 mokutil
ユーティリティーでサポートされています。
MOK 鍵の登録は、各ターゲットシステムの UEFI システムコンソールでユーザーが物理的に手動で対応する必要があります。それにもかかわらず、MOK 機能は、新規生成された鍵ペアのテストとこれで署名されたカーネルモジュールのテストにおいて便利な方法を提供します。
公開鍵を MOK リストに追加するには、以下に従います。
公開鍵を MOK リストに追加するようリクエストします。
# mokutil --import my_signing_key_pub.der
この MOK 登録リクエストに関するパスワードの入力と確認が求められます。
マシンを再起動します。
この MOK 鍵登録リクエストは
shim.efi
が発見し、MokManager.efi
を起動して UEFI コンソールからの登録が完了できるようになります。このリクエストに関連付けたパスワードを入力し、登録を確認します。
公開鍵が MOK リストに永続的に追加されます。
鍵が MOK リストに追加されると、UEFI セキュアブートが有効になっているシステムの起動時に毎回、この鍵はシステムのキーリングに自動的に追加されます。
1.9.5. 秘密鍵を使用したカーネルモジュールの署名
カーネルモジュールの準備が完了していることを前提とします。
Perl スクリプトを使用して、秘密鍵でカーネルモジュールに署名します。
# perl /usr/src/kernels/$(uname -r)/scripts/sign-file \ sha256 \ my_signing_key.priv\ my_signing_key_pub.der\ my_module.ko
注記Perl スクリプトを使用するには、署名するカーネルモジュールファイルの他に、秘密および公開鍵の両方を含むファイルを提供する必要があります。
カーネルモジュールは ELF イメージ形式で、Perl スクリプトは署名を計算して、カーネルモジュールファイルの ELF イメージに直接追加します。
modinfo
ユーティリティーを使うと、カーネルモジュールの署名がある場合は、それについての情報を表示できます。modinfo
の使用方法は、「モジュール情報の表示」 を参照してください。この追加された署名は ELF イメージセクションには含まれず、また ELF イメージの正式な一部ではありません。このため、
readelf
のようなユーティリティーは、この署名をカーネルモジュールに表示することができません。これでカーネルモジュールの読み込み準備が完了しました。署名済みのカーネルモジュールは、UEFI セキュアブートが無効となっているシステムまたは UEFI 以外のシステムでも読み込み可能であることに注意してください。つまり、署名済みのカーネルモジュールと署名なしのカーネルモジュールの両方を提供する必要はないことになります。
1.9.6. 署名済みカーネルモジュールの読み込み
公開鍵が登録されてシステムキーリングに格納されたら、mokutil
を使用して公開鍵を MOK リストに追加します。次に、modprobe
コマンドを使用して、カーネルモジュールを手動で読み込みます。
オプションで、公開鍵の登録前にカーネルモジュールを読み込まないことを確認します。
現在読み込み済みのカーネルモジュールを一覧表示する方法は、「読み込み済みモジュールのリスト表示」 を参照してください。
現在のブートで、システムキーリングに追加されている鍵を確認します。
# keyctl list %:.system_keyring
公開鍵はまだ登録されていないので、このコマンドの出力には表示されません。
公開鍵の登録をリクエストします。
# mokutil --import my_signing_key_pub.der
再起動して、UEFI コンソールでの登録を完了します。
# reboot
システムキーリングの鍵を再度確認します。
# keyctl list %:.system_keyring
任意のカーネルの
/extra/
ディレクトリーにモジュールをコピーします。# cp my_module.ko /lib/modules/$(uname -r)/extra/
モジュールの依存関係のリストを更新します。
# depmod -a
カーネルモジュールを読み込み、正常にロードされたことを確認します。
# modprobe -v my_module # lsmod | grep my_module
必要に応じて、起動時にモジュールを読み込むには、
/etc/modules-loaded.d/my_module.conf
ファイルに追加します。# echo "my_module" > /etc/modules-load.d/my_module.conf