私はカーネルモジュールに取り組んでいますが、これは正常に機能しています。ただし、dmesgを見ると、モジュールの検証に失敗したというモジュールに関するメッセージが表示されます(モジュールの検証に失敗した署名または必要なキーがない)。
この問題を解決するにはどうすればよいですか?検証のためにモジュールに署名するにはどうすればよいですか?
ありがとう。
私はカーネルモジュールに取り組んでいますが、これは正常に機能しています。ただし、dmesgを見ると、モジュールの検証に失敗したというモジュールに関するメッセージが表示されます(モジュールの検証に失敗した署名または必要なキーがない)。
この問題を解決するにはどうすればよいですか?検証のためにモジュールに署名するにはどうすればよいですか?
ありがとう。
回答:
カーネルモジュール署名機能は、インストール時にモジュールに暗号で署名し、モジュールの読み込み時に署名をチェックします。これにより、署名されていないモジュールまたは無効なキーで署名されたモジュールの読み込みを禁止することにより、カーネルのセキュリティを強化できます。モジュール署名は、悪意のあるモジュールをカーネルにロードすることを困難にすることにより、セキュリティを向上させます。モジュールの署名チェックはカーネルによって行われるため、信頼できるユーザースペースビットを用意する必要はありません。
この機能は、X.509 ITU-T標準証明書を使用して、関連する公開鍵をエンコードします。署名自体は、どの業界標準タイプでもエンコードされていません。現在、ファシリティはRSA公開キー暗号化標準のみをサポートしています(ただし、プラグイン可能であり、他のユーザーが使用できるようにします)。使用可能なハッシュアルゴリズムは、SHA-1、SHA-224、SHA-256、SHA-384、SHA-512です(アルゴリズムは署名のデータによって選択されます)。
カーネル構成の「ロード可能なモジュールのサポートを有効にする」セクションに移動してオンにすることにより、モジュール署名機能が有効になります
CONFIG_MODULE_SIG "Module signature verification"
これにはいくつかのオプションがあります。
「モジュールに有効な署名が必要」(CONFIG_MODULE_SIG_FORCE)
これは、キーが不明な署名を持つモジュールまたは署名されていないモジュールをカーネルがどのように処理するかを指定します。
これがオフの場合(つまり、「許容」)、キーが利用できないモジュールと署名されていないモジュールは許可されますが、カーネルは汚染されているとマークされ、関連するモジュールは汚染されているとマークされます(図を参照)。文字「E」を使用します。
これがオンの場合(つまり、「制限付き」)、カーネルが所有する公開鍵によって検証できる有効な署名を持つモジュールのみがロードされます。他のすべてのモジュールはエラーを生成します。
ここでの設定に関係なく、モジュールに解析できない署名ブロックがある場合、そのモジュールはすぐに拒否されます。
「すべてのモジュールに自動的に署名する」(CONFIG_MODULE_SIG_ALL)
これがオンの場合、ビルドのmodules_installフェーズ中にモジュールが自動的に署名されます。これがオフの場合、モジュールは以下を使用して手動で署名する必要があります。
scripts/sign-file
「モジュールに署名する必要があるハッシュアルゴリズムはどれですか?」
これは、インストールフェーズでモジュールに署名するハッシュアルゴリズムの選択肢を示します。
CONFIG_MODULE_SIG_SHA1 "Sign modules with SHA-1"
CONFIG_MODULE_SIG_SHA224 "Sign modules with SHA-224"
CONFIG_MODULE_SIG_SHA256 "Sign modules with SHA-256"
CONFIG_MODULE_SIG_SHA384 "Sign modules with SHA-384"
CONFIG_MODULE_SIG_SHA512 "Sign modules with SHA-512"
ここで選択したアルゴリズムは(モジュールではなく)カーネルにも組み込まれるため、そのアルゴリズムで署名されたモジュールは、依存関係のループを引き起こさずに署名をチェックできます。
「モジュール署名鍵のファイル名またはPKCS#11 URI」(CONFIG_MODULE_SIG_KEY)
このオプションをデフォルトの「certs / signing_key.pem」以外に設定すると、署名鍵の自動生成が無効になり、選択した鍵でカーネルモジュールに署名できるようになります。提供された文字列は、PEM形式の秘密キーとそれに対応するX.509証明書の両方を含むファイルを識別する必要があります。または、OpenSSL ENGINE_pkcs11が機能するシステムでは、RFC7512で定義されているPKCS#11 URI。後者の場合、PKCS#11 URIは証明書と秘密鍵の両方を参照する必要があります。
秘密キーを含むPEMファイルが暗号化されている場合、またはPKCS#11トークンがPINを必要とする場合、これはビルド時にKBUILD_SIGN_PIN変数を使用して提供できます。
「デフォルトのシステムキーリング用の追加のX.509キー」(CONFIG_SYSTEM_TRUSTED_KEYS)
このオプションは、デフォルトでシステムキーリングに含まれる追加の証明書を含むPEMエンコードファイルのファイル名に設定できます。
モジュール署名を有効にすると、署名を行うツールのカーネルビルドプロセスにOpenSSL開発パッケージへの依存関係が追加されることに注意してください。
署名を生成およびチェックするには、暗号鍵ペアが必要です。秘密鍵を使用して署名を生成し、対応する公開鍵を使用してそれを検査します。秘密キーはビルド中にのみ必要で、その後は安全に削除または保存できます。公開鍵はカーネルに組み込まれるため、モジュールのロード時に署名をチェックするために使用できます。
通常の状態では、CONFIG_MODULE_SIG_KEYがデフォルトから変更されていない場合、カーネルビルドは、ファイルにキーペアが存在しない場合、opensslを使用して新しいキーペアを自動的に生成します。
certs/signing_key.pem
vmlinuxのビルド中(キーの公開部分はvmlinuxにビルドする必要があります)は、次のパラメータを使用します。
certs/x509.genkey
ファイル(まだ存在しない場合も生成されます)。
独自のx509.genkeyファイルを提供することを強くお勧めします。
特に、x509.genkeyファイルでは、req_distinguished_nameセクションをデフォルトから変更する必要があります。
[ req_distinguished_name ]
#O = Unspecified company
CN = Build time autogenerated kernel key
#emailAddress = unspecified.user@unspecified.company
生成されたRSA鍵のサイズは、次のものでも設定できます。
[ req ]
default_bits = 4096
Linuxカーネルソースツリーのルートノードにあるx509.genkeyキー生成構成ファイルとopensslコマンドを使用して、キープライベート/パブリックファイルを手動で生成することもできます。以下は、公開鍵/秘密鍵ファイルを生成する例です。
openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \
-config x509.genkey -outform PEM -out kernel_key.pem \
-keyout kernel_key.pem
結果のkernel_key.pemファイルの完全パス名をCONFIG_MODULE_SIG_KEYオプションで指定すると、自動生成されたキーペアの代わりにその中の証明書とキーが使用されます。
カーネルには、ルートが表示できる公開鍵のリングが含まれています。それらは、「。system_keyring」と呼ばれるキーリングにあります。
[root@deneb ~]# cat /proc/keys
...
223c7853 I------ 1 perm 1f030000 0 0 keyring .system_keyring: 1
302d2d52 I------ 1 perm 1f010000 0 0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 []
...
モジュール署名用に特別に生成された公開鍵のほかに、CONFIG_SYSTEM_TRUSTED_KEYS構成オプションで参照されるPEMエンコードファイルで追加の信頼できる証明書を提供できます。
さらに、アーキテクチャー・コードは、ハードウェア・ストアから公開鍵を取得し、それらを(例えば、UEFI鍵データベースから)追加することもできます。
最後に、次のようにして公開鍵を追加することができます。
keyctl padd asymmetric "" [.system_keyring-ID] <[key-file]
例えば:
keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509
ただし、新しいキーのX.509ラッパーが、キーが追加されたときに.system_keyringにすでに存在するキーによって有効に署名されている場合、カーネルは.system_keyringにキーを追加することのみを許可することに注意してください。
モジュールに手動で署名するには、Linuxカーネルソースツリーで利用可能なスクリプト/署名ファイルツールを使用します。スクリプトには4つの引数が必要です。
1. The hash algorithm (e.g., sha256)
2. The private key filename or PKCS#11 URI
3. The public key filename
4. The kernel module to be signed
以下は、カーネルモジュールに署名する例です。
scripts/sign-file sha512 kernel-signkey.priv \
kernel-signkey.x509 module.ko
使用されるハッシュアルゴリズムは、構成されたものと一致する必要はありませんが、一致しない場合は、ハッシュアルゴリズムがカーネルに組み込まれているか、またはそれ自体を必要とせずにロードできることを確認する必要があります。
秘密鍵にパスフレーズまたはPINが必要な場合は、$ KBUILD_SIGN_PIN環境変数で提供できます。
署名されたモジュールには、最後にデジタル署名が追加されています。文字列 "〜Module signature append〜。" モジュールのファイルの最後で、署名が存在することを確認しますが、署名が有効であることは確認しません!
署名は定義されたELFコンテナーの外にあるため、署名付きモジュールはBRITTLEです。したがって、署名が計算されて添付されると、それらは削除されない場合があります。モジュール全体が署名されたペイロードであり、署名時に存在するすべてのデバッグ情報を含むことに注意してください。
モジュールはinsmod、modprobe、init_module()またはfinit_module()でロードされます。ユーザー空間では処理が行われないため、署名されていないモジュールの場合とまったく同じです。署名チェックはすべてカーネル内で行われます。
CONFIG_MODULE_SIG_FORCEが有効になっているか、カーネルコマンドラインでenforcemodulesig = 1が指定されている場合、カーネルは、公開鍵を持つ有効に署名されたモジュールのみをロードします。それ以外の場合は、署名されていないモジュールもロードします。カーネルがキーを持っているが、署名の不一致があることが判明しているモジュールの読み込みは許可されません。
解析できないシグネチャを持つモジュールはすべて拒否されます。
秘密鍵はモジュールの署名に使用されるため、ウイルスやマルウェアは秘密鍵を使用してモジュールに署名し、オペレーティングシステムを危険にさらす可能性があります。秘密鍵は破棄するか、安全な場所に移動し、カーネルソースツリーのルートノードに保持しないでください。