本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
此程序說明如何使用 UEFI 安全開機和自訂私有金鑰來建立 Linux AMI。Amazon Linux 從 AL2023 2023.1 版起開始支援 UEFI 安全開機。如需詳細資訊,請參閱「AL2023 使用者指南」中的 UEFI 安全開機。
重要
以下程序僅適用於進階使用者。您必須具備充分的 SSL 和 Linux 發行版本開機流程的知識才能使用這些程序。
先決條件
-
將會使用下列工具:
-
OpenSSL - https://www.openssl.org/
-
efivar - https://github.com/rhboot/efivar
-
efitools - https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git/
-
-
您的 Linux 執行個體必須使用支援 UEFI 開機模式的 Linux AMI 啟動,並且有非揮發性資料存在。
沒有 UEFI 安全開機金鑰的新建立執行個體是在 SetupMode
中建立,允許您註冊自己的金鑰。某些 AMI 預先設定為具有 UEFI 安全開機功能,您無法變更現有金鑰。如果您想要變更金鑰,您必須根據原始 AMI 建立新 AMI。
您有兩種在變數存放區傳播金鑰的方法,這些方法在接下來的選項 A 和選項 B 中說明。選項 A 說明如何在執行個體中執行此操作,並模仿真實硬體的流程。選項 B 說明如何建立二進位檔案 Blob,其隨後會在建立 AMI 時作為 base64 編碼的檔案傳遞。對於這兩個選項,您必須先建立用於信任鏈的三對金鑰對。
若要建立支援 UEFI 安全開機的 Linux AMI,請先建立三個金鑰對,然後完成選項 A 或選項 B,但不能同時完成兩者:
步驟 1
UEFI 安全開機基於下列用於信任鏈的三個金鑰資料庫:平台金鑰 (PK)、金鑰交換金鑰 (KEK) 和簽章資料庫 (db)。¹
您需在執行個體上建立每個金鑰。若要以對 UEFI 安全開機標準有效的格式準備公有金鑰,請為每個金鑰建立一個憑證。DER
定義 SSL 格式 (格式的二進位編碼)。然後,您可以將每個憑證轉換為 UEFI 簽章清單,該清單為 UEFI 安全開機中所理解的二進位格式。最後,您需使用相關金鑰簽署每個憑證。
準備建立金鑰對
建立金鑰對之前,請建立一個用於金鑰產生的全域唯一識別符 (GUID)。
-
在 shell 提示中執行下列命令。
uuidgen --random > GUID.txt
金鑰對 1:建立平台金鑰 (PK)
PK 是 UEFI 安全開機執行個體的信任根。私有 PK 用於更新 KEK,其又可接續用於將授權的金鑰新增至簽章資料庫 (db)。
X.509 標準用於建立金鑰對。如需有關標準的資訊,請參閱維基百科上的 X.509
建立 PK
-
建立金鑰。您必須將變數命名為
PK
。openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509 -sha256 -days 3650 -subj "/CN=
Platform key
/" -out PK.crt指定了下列參數:
-
-keyout PK.key
- 私有金鑰檔案。 -
-days 3650
- 憑證有效的天數。 -
-out PK.crt
- 用於建立 UEFI 變數的憑證。 -
CN=
- 金鑰的通用名稱 (CN)。您可以輸入自己的組織名稱,而不是Platform key
平台金鑰
。
-
-
建立憑證。
openssl x509 -outform DER -in PK.crt -out PK.cer
-
將憑證轉換至 UEFI 簽章清單。
cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl
-
使用私有 PK (自我簽署) 簽署 UEFI 簽章清單。
sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth
金鑰對 2:建立金鑰交換金鑰 (KEK)
私有 KEK 用於將金鑰新增至 db,這是要在系統上開機使用的授權簽章清單。
建立 KEK
-
建立金鑰。
openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 -sha256 -days 3650 -subj "/CN=Key Exchange Key/" -out KEK.crt
-
建立憑證。
openssl x509 -outform DER -in KEK.crt -out KEK.cer
-
將憑證轉換至 UEFI 簽章清單。
cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl
-
使用私有 PK 簽署簽章清單。
sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl KEK.auth
金鑰對 3:建立簽章資料庫 (db)
db 清單包含授權在系統上開機的授權金鑰。必須使用私有 KEK 才能修改清單。將使用在此步驟中建立的私有金鑰簽署開機映像。
建立 db
-
建立金鑰。
openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 -sha256 -days 3650 -subj "/CN=Signature Database key/" -out db.crt
-
建立憑證。
openssl x509 -outform DER -in db.crt -out db.cer
-
將憑證轉換至 UEFI 簽章清單。
cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl
-
使用私有 KEK 簽署簽章清單。
sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth
使用私有金鑰簽署開機映像 (核心)
若為 Ubuntu 22.04,下列映像需要簽章。
/boot/efi/EFI/ubuntu/shimx64.efi
/boot/efi/EFI/ubuntu/mmx64.efi
/boot/efi/EFI/ubuntu/grubx64.efi
/boot/vmlinuz
簽署映像
使用下列語法簽署映像。
sbsign --key db.key --cert db.crt --output
/boot/vmlinuz
/boot/vmlinuz
注意
您必須簽署所有新核心。
通常會以符號連結到上次安裝的核心。/boot/vmlinuz
請參閱您的發行版本說明文件,了解您的開機鏈和所需映像。
¹ 感謝 ArchWiki 社群所做的所有工作。用於建立 PK、建立 KEK、建立 DB 和簽署映像的命令來自 Creating keys
步驟 2 (選項 A):從執行個體中將金鑰新增至變數存放區
建立三個金鑰對後,您即可以連接到執行個體,並透過完成以下步驟從執行個體中將金鑰新增至變數存放區。或者,完成 的步驟步驟 2 (選項 B):建立一個包含預填寫變數存放區的二進位 blob。
步驟 1:啟動將支援 UEFI 安全開機的執行個體
當您啟動執行個體 (具有下列先決條件) 時,執行個體將準備好設定為支援 UEFI 安全開機。您只能在啟動時在執行個體上啟用對 UEFI 安全開機的支援;以後無法啟用它。
先決條件
-
AMI - Linux AMI 必須支援 UEFI 開機模式。若要驗證 AMI 是否支援 UEFI 開機模式,AMI 開機模式參數必須為 uefi。如需詳細資訊,請參閱確定 Amazon EC2 AMI 的開機模式參數。
請注意, AWS 僅提供設定為支援 Graviton 型執行個體類型的 UEFI 的 Linux AMIs。 AWS 目前不提供支援 UEFI 開機模式的 x86_64 Linux AMIs。您可以設定自有的 AMI,以支援所有架構的 UEFI 開機模式。若要設定支援 UEFI 開機模式的 AMI,必須在自有的 AMI 上執行多個設定步驟。如需詳細資訊,請參閱設定 Amazon EC2 AMI 的開機模式。
-
執行個體類型 - 所有支援 UEFI 的虛擬化執行個體類型也支援 UEFI 安全開機。裸機執行個體類型不支援 UEFI 安全開機。如需有關支援 UEFI 安全開機的執行個體類型詳細資訊,請參閱UEFI 開機模式需求。
-
在發佈 UEFI 安全開機後啟動您的執行個體。只有在 2022 年 5 月 10 日 (發佈 UEFI 安全開機時) 後啟動的執行個體才能支援 UEFI 安全開機。
啟動執行個體後,您可以透過檢查 UEFI 資料是否存在,驗證執行個體是否已準備好設定為支援 UEFI 安全開機 (換句話說,您可以繼續執行步驟 2)。UEFI 資料的存在表示非揮發性資料是持續的。
驗證執行個體是否準備好執行步驟 2
使用 get-instance-uefi-data
aws ec2 get-instance-uefi-data --instance-id
i-0123456789example
如果輸出中存在 UEFI 資料,則執行個體已準備好執行步驟 2。如果輸出為空白,則無法將執行個體設定為支援 UEFI 安全開機。如果您的執行個體在 UEFI 安全開機支援可用之前啟動,則會發生這種情況。啟動新的執行個體,然後再試一次。
步驟 2:設定執行個體以支援 UEFI 安全開機
在執行個體上的 UEFI 變數存放區中註冊金鑰對
警告
您必須在註冊金鑰之後簽署開機映像,否則您將無法啟動執行個體。
建立已簽署的 UEFI 簽章清單 (PK
、KEK
以及db
) 後,必須將他們註冊至 UEFI 韌體。
只有在以下情況下才能寫入 PK
變數:
-
如果
SetupMode
變數為1
,表示尚未註冊 PK。透過以下命令來檢查這一點:輸出為1
或0
。efivar -d -n 8be4df61-93ca-11d2-aa0d-00e098032b8c-SetupMode
-
新 PK 由現有 PK 的私有金鑰簽署。
在 UEFI 變數存放區中註冊金鑰
必須在執行個體上執行以下命令。
如果啟用了設定模式 (值為 1
),則可以在執行個體上執行下列命令來註冊金鑰:
[ec2-user ~]$
efi-updatevar -f db.auth db
[ec2-user ~]$
efi-updatevar -f KEK.auth KEK
[ec2-user ~]$
efi-updatevar -f PK.auth PK
驗證 UEFI 安全開機是否已啟用
若要驗證 UEFI 安全開機是否已啟用,請依照 驗證 Amazon EC2 執行個體是否已啟用 UEFI 安全開機 中的步驟執行動作。
現在,您可以使用 get-instance-uefi-data
步驟 3:從執行個體建立 AMI
若要從執行個體建立 AMI,您可以使用主控台或 CreateImage
API、CLI 或 SDK。如需主控台的說明,請參閱 建立 Amazon EBS 支援的 AMI。如需 API 的說明,請參閱 CreateImage。
注意
CreateImage
API 會自動將執行個體的 UEFI 變數存放區複製到 AMI。控制台使用 CreateImage
API。使用此 AMI 啟動執行個體後,執行個體將具有相同的 UEFI 變數存放區。
步驟 2 (選項 B):建立一個包含預填寫變數存放區的二進位 blob
建立三個金鑰對之後,您可以建立一個包含預先填寫的變數存放區 (包含 UEFI 安全開機金鑰) 的二進位 blob。或者,完成 的步驟步驟 2 (選項 A):從執行個體中將金鑰新增至變數存放區。
警告
您必須在註冊金鑰之前簽署開機映像,否則您將無法啟動執行個體。
步驟 1:建立新的變數存放區或更新現有變數存放區
您可以使用 python-uefivars 工具,在沒有執行個體執行的情況下離線建立變數存放區。該工具可以從您的金鑰建立一個新的變數存放區。指令碼目前支援 EDK2 格式、 AWS 格式和 JSON 表示法,以更高階的工具進行編輯時更容易。
在沒有執行個體執行的情況下離線建立變數存放區
-
在下列連結下載該工具。
https://github.com/awslabs/python-uefivars
-
通過執行下列命令從您的金鑰建立新的變數存放區。這將在
your_binary_blob
.bin 中建立 base64 編碼二進位 blob。該工具還支援透過-I
參數更新二進位 blob。./uefivars.py -i none -o aws -O
your_binary_blob
.bin -P PK.esl -K KEK.esl --db db.esl --dbx dbx.esl
步驟 2:在建立 AMI 時上傳二進位 blob
使用 register-image--uefi-data
參數,請指定您的二進位 blob,而對於 --boot-mode
參數,則指定 uefi
。
aws ec2 register-image \ --name uefi_sb_tpm_register_image_test \ --uefi-data $(cat
your_binary_blob
.bin) \ --block-device-mappings "DeviceName=/dev/sda1,Ebs= {SnapshotId=snap-0123456789example
,DeleteOnTermination=true}" \ --architecture x86_64 \ --root-device-name /dev/sda1 \ --virtualization-type hvm \ --ena-support \ --boot-mode uefi