備註:

搭配 UEFI 安全啟動使用的簽署核心模組

本教學課程說明如何簽署要在已安裝 Unbreakable Enterprise Kernel 的 Oracle Linux 上與 UEFI Secure Boot 搭配使用的模組。本教學課程也說明在 UEK R6U3 以前使用 UEK R6 核心時,如何將自己的憑證新增至核心的信任憑證金鑰鍊,以及如何使用 mokutil 公用程式將 UEFI 開機 shim 更新為簽署憑證。

警告
本教學課程的對象是執行軟體測試的開發者。請勿在 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
    

    針對 OCNemailAddress 欄位,輸入更適合的值。

  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

    注意:核心的開機映像檔壓縮大小無法增加,因此只能在核心新增單一自訂憑證。

    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 Management。
      請務必在 10 秒內按下按鍵,以中斷啟動程序以新增 MOK 金鑰。
    2. 選取「註冊 MOK」。
    3. 選取檢視鍵 0。
    4. 確認金鑰符合您要的值。
    5. 按任意鍵,然後選取繼續。
    6. 選取「是」以註冊金鑰。
    7. 提供使用 mokutil 匯入金鑰時使用的密碼。
    8. 選取重新啟動。
  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 Help Center