備註:
- 此教學課程需要存取 Oracle Cloud。若要註冊免費帳戶,請參閱開始使用 Oracle Cloud Infrastructure Free Tier。
- 此範例使用 Oracle Cloud Infrastructure 證明資料、租用戶及區間的範例值。完成實驗室時,請將這些值替代成雲端環境的特定值。
搭配 UEFI 安全啟動使用的簽署核心模組
本教學課程說明如何簽署要在已安裝 Unbreakable Enterprise Kernel 的 Oracle Linux 上與 UEFI Secure Boot 搭配使用的模組。本教學課程也說明在 UEK R6U3 以前使用 UEK R6 核心時,如何將自己的憑證新增至核心的信任憑證金鑰鍊,以及如何使用 mokutil 公用程式將 UEFI 開機 shim 更新為簽署憑證。
警告
本教學課程的對象是執行軟體測試的開發者。請勿在 Oracle 支援的生產系統上使用此教學課程中的程序。
必要條件
- Oracle Linux 系統 (Oracle Linux 7 或 Oracle Linux 8)
- 系統正在執行最新的 UEKR6 核心
- 伺服器的韌體實作與組態支援 MOK 公用程式 (如需詳細資訊,請參閱 https://docs.oracle.com/en/learn/mokutil-uefi/)
目標
本教學課程結束後,您應該能夠:
- 與 UEFI 安全啟動搭配使用的簽署模組
- 將憑證新增至核心的信任憑證金鑰環
- 使用
mokutil
公用程式,以簽署憑證更新 UEFI 啟動 shim
安裝必要的套裝程式
-
根據您的 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
-
-
重新啟動系統。
建立自訂核心模組範例
本教學課程的目的在於建立及建置範例自訂核心模組。在大多數情況下,模組已由外部廠商提供,因此不需要此步驟。此處所描述的處理是用於說明用途。
-
建立
~/hello
目錄。 -
使用下列項目建立
~/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);
-
使用下列項目建立
~/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
-
建置然後安裝模組。
cd ~/hello make && sudo make install
-
測試模組。
sudo modprobe hello modprobe: ERROR: could not insert 'hello': Operation not permitted
如果系統在安全開機模式中執行,
modprobe
會因為該模組尚未生效而失敗。
建立本機憑證並簽署此模組
-
建立 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
針對 O、CN 和 emailAddress 欄位,輸入更適合的值。
-
根據新組態產生新的私密 / 公開金鑰組。
請注意,憑證有效期限為 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' -----
-
以 PEM 格式匯出憑證。
openssl x509 -inform DER -in pubkey.der -out pubkey.pem
-
建立憑證的 PKCS#12 版本。
指定提示時的匯出密碼。
openssl pkcs12 -export -inkey priv.key -in pubkey.pem -name cert -out cert.p12 Enter Export Password: Verifying - Enter Export Password:
-
使用您剛才產生的金鑰來簽署模組。
cd ~/certs sudo /usr/src/kernels/$(uname -r)/scripts/sign-file sha512 priv.key pubkey.der /lib/modules/$(uname -r)/extra/hello.ko
-
使用
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 發行版本,只有在簽署這些金鑰的金鑰位於核心內建的信任金鑰環中時,才能載入模組。
-
建立搭配
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:
-
新增 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
-
將金鑰插入核心的
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
-
請移除現有的 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":
-
將簽署的核心複製到
/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/。
-
將適當的金鑰新增為機器擁有者金鑰 (MOK) 至 UEFI 開機陰影。
mokutil import
指令會提示您輸入下一步驟必須提供的密碼。sudo mokutil --import pubkey.der input password: input password again:
-
重新啟動您的機器。
在重新開機時,UEFI SHIM 應自動啟動用於將 MOK 金鑰新增至 UEFI 安全開機金鑰資料庫的 MokManager。
- 按一個鍵來執行 MOK Management。
請務必在 10 秒內按下按鍵,以中斷啟動程序以新增 MOK 金鑰。 - 選取「註冊 MOK」。
- 選取檢視鍵 0。
- 確認金鑰符合您要的值。
- 按任意鍵,然後選取繼續。
- 選取「是」以註冊金鑰。
- 提供使用 mokutil 匯入金鑰時使用的密碼。
- 選取重新啟動。
- 按一個鍵來執行 MOK Management。
-
確認憑證已安裝在信任金鑰環中。
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
-
驗證模組可順利載入。
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 版次,再開始此程序。
- 5.4.17-2022.el7uek.x86_64
- 5.4.17-2023.el7uek.x86_64
- 5.4.17-2025.el7uek.x86_64
- 5.4.17-2026.el7uek.x86_64
- 5.4.17-2028.1.el7uek.x86_64
- 5.4.17-2028.el7uek.x86_64
- 5.4.17-2011.3.2.el7uek.x86_64
- 5.4.17-2011.4.0.el7uek.x86_64
- 5.4.17-2013.el7uek.x86_64
- 5.4.17-2016.1.el7uek.x86_64
就等同於 Oracle Linux 8 上的這些核心版本而言,不觀察壓縮問題。
其他相關資訊
- Oracle Linux:使用 UEFI 安全啟動
- Oracle Linux UEFI 安全開機更新注意事項
- Oracle Linux:管理憑證和公用金鑰基礎架構
- Oracle Linux 與不可更換的企業核心 (UEK) 發行版本
- mokutil (1) 手冊
- pesign (1) 手冊
pesign --help
指令
其他學習資源
探索 docs.oracle.com/learn 上的其他實驗室,或是存取更多免費學習內容至 Oracle Learning YouTube 通道。此外,瀏覽 education.oracle.com/learning-explorer 以成為 Oracle Learning Explorer。
如需產品文件,請瀏覽 Oracle Help Center。
Sign Kernel Modules for Use With UEFI Secure Boot
F55223-01
March 2022
Copyright © 2021, Oracle and/or its affiliates.