ノート:

UEFIセキュアブートで使用するためのカーネルモジュールの署名

このチュートリアルでは、Unbreakable Enterprise Kernelがインストールされている Oracle LinuxでUEFI Secure Bootで使用する独自のモジュールに署名する方法について説明します。このチュートリアルでは、UEK R6U3より前のUEK R6カーネルを使用している場合、独自の証明書をカーネルの信頼できる証明書キーリングに追加する方法、およびmokutilユーティリティーを使用してUEFIブートシムを署名証明書で更新する方法についても説明します。

警告
このチュートリアルは、ソフトウェア・テストを実行している開発者を対象としています。このチュートリアルの手順は、Oracleでサポートされている本番システムで使用しないでください。

前提条件

目的

このチュートリアルを終了すると、次の操作を実行できるようになります。

必須パッケージのインストール

  1. Oracle Linuxシステムに基づいて次のコマンドを実行します。

    • Oracle Linux 8

      sudo dnf update
      sudo dnf group install "Development Tools"
      sudo dnf install kernel-uek kernel-uek-devel keyutils mokutil pesign
      
    • Oracle Linux 7

      sudo yum-config-manager --enable ol7_optional_latest
      sudo yum update
      sudo yum group install "Development Tools"
      sudo yum-config-manager --enable ol7_UEKR6 && yum-config-manager --disable ol7_UEKR5
      
  2. システムの再起動。

サンプルカスタムカーネルモジュールの作成

このチュートリアルでは、サンプル・カスタム・カーネル・モジュールを作成してビルドします。ほとんどの場合、モジュールは外部ベンダーによってすでに提供されており、この手順は必要ありません。ここで説明するプロセスは、説明を目的としています。

  1. ~/helloディレクトリを作成します。

  2. 次のエントリを使用してファイル~/hello/hello.cを作成します。

    #include <linux/module.h>  
    #include <linux/kernel.h>  
    #include <linux/init.h>
    
    MODULE_LICENSE("GPL");  
    MODULE_AUTHOR("A.Developer");  
    MODULE_DESCRIPTION("Hello World Linux Kernel Module");
    
    static int __init hello_init(void)
    {  
      printk(KERN_INFO "Hello world!\n");  
      return 0;
    }
    
    static void __exit hello_exit(void)  
    {  
      printk(KERN_INFO "Unloading Hello world.\n");  
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    
  3. 次のエントリを使用してファイル~/hello/Makefileを作成します。

    obj-m += hello.o
    
    all:  
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
    
    clean:  
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
    
    install:  
      cp hello.ko  /lib/modules/$(shell uname -r)/extra  
      depmod
    
  4. モジュールを構築して取り付けます。

    cd ~/hello
    make && sudo make install
    
  5. モジュールをテストします。

    sudo modprobe hello
    
    modprobe: ERROR: could not insert 'hello': Operation not permitted
    

    システムがセキュア・ブート・モードで実行されている場合、モジュールがまだ有効ではないため、modprobeは失敗します。

ローカル証明書の作成およびモジュールの署名

  1. ローカル署名証明書を作成するためのOpenSSL構成ファイルを作成します。

    タイプ:

    cat >>/tmp/x509.conf <<EOF
    [ req ]
    default_bits = 4096
    distinguished_name = req_distinguished_name
    prompt = no
    string_mask = utf8only
    x509_extensions = extensions
    
    [ req_distinguished_name ]
    O = Module Signing Example
    CN = Module Signing Example Key
    emailAddress = first.last@example.com
    
    [ extensions ]
    basicConstraints=critical,CA:FALSE
    keyUsage=digitalSignature
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid
    EOF
    

    OCN、および emailAddressフィールドには、より適切な値を入力します。

  2. 新しい構成に基づいて新しい秘密キーと公開キー・ペアを生成します。

    証明書は10年(3,650日間)有効です。

    mkdir ~/certs
    cd ~/certs
    openssl req -x509 -new -nodes -utf8 -sha512 -days 3650 -batch -config /tmp/x509.conf -outform DER -out pubkey.der -keyout priv.key
    
    Generating a RSA private key
    ........................................................
    ............................++++
    writing new private key to 'priv.key'
    -----
    
  3. 証明書をPEM形式でエクスポートします。

    openssl x509 -inform DER -in pubkey.der -out pubkey.pem
    
  4. 証明書のPKCS#12バージョンを作成します。

    プロンプトが表示されたら、エクスポート・パスワードを指定します。

    openssl pkcs12 -export -inkey priv.key -in pubkey.pem -name cert -out cert.p12
    
    Enter Export Password:
    Verifying - Enter Export Password:
    
  5. 生成したキーを使用してモジュールに署名します。

    cd ~/certs
    sudo /usr/src/kernels/$(uname -r)/scripts/sign-file sha512 priv.key pubkey.der /lib/modules/$(uname -r)/extra/hello.ko
    
  6. modinfoコマンドを使用して、作成したキーでモジュールが署名されていることを確認します。

    modinfo hello
    
    filename:       /lib/modules/5.4.17-2036.103.3.1.el8uek.x86_64/extra/hello.ko
    description:    Hello World Linux Kernel Module
    author:         A.Developer
    license:        GPL
    srcversion:     D51FB4CF0B86314953EE797
    depends:        
    retpoline:      Y
    name:           hello
    vermagic:       5.4.17-2036.103.3.1.el8uek.x86_64 SMP mod_unload modversions 
    sig_id:         PKCS#7
    signer:         Module Signing Example Key
    sig_key:        AB:2C:E3:AB:87:D9:9C:6A:31:B8:80:20:D4:92:25:F3:9A:26:DC
    sig_hashalgo:   sha512
    signature:      9F:B0:25:CB:14:C1:C7:10:7F:60:1E:E6:66:82:64:58:91:1F:01:A5:
                    D9:03:1B:9C:2D:42:00:45:78:2B:FA:70:F8:C7:3B:1A:A2:42:00:09:
                    33:E0:81:1D:C6:E6:46:A5:FE:8B:9F:8C:3D:4E:A1:3A:05:52:ED:F6:
                    25:F9:88:98:D3:70:78:1D:7E:63:F3:73:C8:C8:14:C2:3A:52:B4:8F: 
                    ...
    

カーネル信頼できる鍵リングへの証明書の追加(UEK R6U2以下)

ノート:
UEK R6U3以降を実行する場合、このステップは必要ありません。UEK R6U3のSecure Boot実装が更新され、MOKデータベース内の鍵で署名されたモジュールのモジュールのロードが可能になります。UEK R6U3より前のUEK R6リリースでは、署名されている鍵がカーネルの組み込みの信頼できる鍵リング内にある場合にのみ、モジュールをロードできます。

  1. pesignで使用するNSSデータベースを作成します。

    cd ~/certs
    certutil -d . -N
    
    Enter a password which will be used to encrypt your keys.
    The password should be at least 8 characters long,
    and should contain at least one non-alphabetic character.
    
    Enter new password:
    Re-enter password:
    
  2. PCKS#12キーをデータベースに追加します。

    cd ~/certs
    pk12util -d . -i cert.p12
    
    Enter Password or Pin for "NSS Certificate DB":
    Enter password for PKCS12 file:
    pk12util: PKCS12 IMPORT SUCCESSFUL
    
  3. キーをカーネルのbzImageに挿入します。

    ノート:カーネルのブートイメージの圧縮サイズを増やすことはできないため、カーネルに追加できるカスタム証明書は1つだけです。

    cd ~/certs
    sudo /usr/src/kernels/$(uname -r)/scripts/insert-sys-cert -s /boot/System.map-$(uname -r) -z /boot/vmlinuz-$(uname -r) -c pubkey.der
    
    INFO:    Executing: gunzip <vmlinux-ceDv0X >vmlinux-rFFumH
    WARNING: Could not find the symbol table.
    INFO:    sym:    system_extra_cert
    INFO:    addr:   0xffffffff828915d6
    INFO:    size:   8194
    INFO:    offset: 0x1c915d6
    INFO:    sym:    system_extra_cert_used
    INFO:    addr:   0xffffffff828935d8
    INFO:    size:   0
    INFO:    offset: 0x1c935d8
    INFO:    sym:    system_certificate_list_size
    INFO:    addr:   0xffffffff828935e0
    INFO:    size:   0
    INFO:    offset: 0x1c935e0
    INFO:    Inserted the contents of pubkey.der into ffffffff828915d6.
    INFO:    Used 1481 bytes out of 8194 bytes reserved.
    INFO:    Executing: gzip -n -f -9 <vmlinux-rFFumH >vmlinux-5wHA2r
    
  4. 既存のPE署名を削除し、以前に作成したNSSデータベースパスワードを使用してカーネルを新しいものと再署名します。

    cd ~/certs
    sudo pesign -u 0 -i /boot/vmlinuz-$(uname -r) --remove-signature -o vmlinuz.unsigned
    sudo pesign -n . -c cert -i vmlinuz.unsigned -o vmlinuz.signed -s
    
    Enter Password or PIN for 'NSS Certificate DB":
    
  5. 署名済カーネルを/bootに戻します。

    cd ~/certs
    sudo cp -bf vmlinuz.signed /boot/vmlinuz-$(uname -r)
    

UEFIセキュアブート鍵データベースへの証明書の登録

UEK R6U3より前のUEK R6カーネルの場合、カーネル・イメージの署名に使用されたキーをMOKデータベースに登録する必要があります。他のすべてのカーネルでは、モジュール自体への署名に使用されるキーがデータベースに登録されます。同じキーを使用してモジュールとカーネルに署名した場合、これらのキーは同じになることがあります。

ノート: mokutilユーティリティの使用方法の詳細は、https://docs.oracle.com/learn/mokutil-uefi/を参照してください。

  1. 適切な鍵をマシン所有者鍵(MOK)としてUEFIブートシムに追加します。mokutil importコマンドでは、次のステップで指定する必要があるパスワードの入力を求められます。

    sudo mokutil --import pubkey.der
    
    input password:
    input password again:
    
  2. マシンを再起動します。

    リブート時に、UEFI SHIMは、MOK鍵をUEFIセキュアブート鍵データベースに追加するために使用される MokManagerを自動的に起動するようにしてください。

    1. キーを押してMOK管理を実行します。
      ブート・プロセスを中断してMOKキーを追加する場合は、必ず10秒以内にキーを押してください。
    2. 「MOKの登録」を選択します。
    3. 「View key 0」を選択します。
    4. キーが目的の値と一致することを確認します。
    5. いずれかのキーを押し、「続行」を選択します。
    6. 「Yes」を選択してキーを登録します。
    7. mokutilを使用してキーをインポートするときに使用するパスワードを指定します。
    8. 「reboot」を選択します。
  3. 信頼できる鍵リングに証明書がインストールされていることを確認します。

    sudo keyctl show %:.builtin_trusted_keys
    
    Keyring
     892034081 ---lswrv      0     0  keyring: .builtin_trusted_keys
     367808024 ---lswrv      0     0   \_ asymmetric: Oracle CA Server: fbcd3d4d950c6b2b0e01f0a146c5a4e3855ae704
     230958440 ---lswrv      0     0   \_ asymmetric: Module Signing Example Key: a43b4e638874b0656db2bc26216f56c0ac39f72b
     408597579 ---lswrv      0     0   \_ asymmetric: Oracle America, Inc.: Ksplice Kernel Module Signing Key: 09010ebef5545fa7c54b626ef518e077b5b1ee4c
     839574974 ---lswrv      0     0   \_ asymmetric: Oracle Linux Kernel Module Signing Key: 2bb352412969a3653f0eb6021763408ebb9bb5ab
    
  4. モジュールが正常にロードできることを確認します。

    sudo modprobe hello
    lsmod | grep hello
    hello                  16384  0
    
    dmesg | tail -2
    [  108.848848] hello: loading out-of-tree module taints kernel.
    [  108.849191] Hello world! 
    

既知の問題

Oracle Linux 7上の次のカーネルバージョンでは、結果の vmlinuzファイルに対して同じ(または小さい)圧縮サイズを維持しながら、新しい証明書の受け入れに問題がある可能性があります。このプロセスを開始する前に、使用可能な最新のUEKR6リリースに更新することをお薦めします。

圧縮問題は、Oracle Linux 8のこれらのカーネルの同等バージョンでは発生しません。

詳細情報

その他の学習リソース

docs.oracle.com/learnの他のラボを調べるか、Oracle Learning YouTubeチャネルでさらに無料の学習コンテンツにアクセスします。さらに、education.oracle.com/learning-explorerにアクセスしてOracle Learning Explorerにします。

製品ドキュメントは、Oracleヘルプ・センターを参照してください。