安全启动目的是只有可以通过UEFI固件加密验证的操作系统才可以赋予执行权限。当您打开计算机时,固件会验证每个启动组件的签名或计算的SHA-256哈希。如果所有启动组件的签名或哈希都有效,计算机将允许完成其启动过程,固件将把控制权移交给操作系统。 在开始配置安全启动之前,您必须首先安装依赖。
dnf install efitools keyutils mokutil openssl pesign uuid-runtime sbsigntools
apt: sbsigntool dnf: sbsigntools efitools need to be compiled and installed manually
yum install gnu-efi-devel perl-File-Slurp help2man
git clone https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git
cd efitools
make
make install
1. 说明安全启动依赖一组公私钥对。
- 私钥用于文件签名,通常是EFI启动文件或kernel文件。签名信息一般附于文件内容后。
- 公钥必须是公开可用的。对于安全启动,公钥一般嵌入在固件或存储在NVRAM中。您可以使用公钥和签名来验证文件是否未被修改,也可以验证文件是否使用与正在使用的公钥匹配的密钥进行签名。
对于安全启动,一般需要四组密钥:
- Platform Key(PK):这是安全启动中使用的顶级密钥。平台密钥(PK)在平台所有者和平台固件之间建立了信任关系。PK持有者能够替换现有的PK以及更新/替换密钥交换密钥(KEK)。PK通常归原始设备制造商所有,原始设备制造商完全控制安全启动密钥链。因此,如果您想完全控制安全启动过程,您必须用自己的PK替换PK。
- Key Exchange Key(KEK):在安全启动密钥层次结构中,接下来是KEK。KEK在平台固件和操作系统之间创建信任关系。KEK用于签署签名数据库(db)和禁止签名数据库(dbx)。在大多数系统上,会有一个或多个KEK。需要更新db或dbx的供应商使用KEK。供应商包括宏碁、戴尔等原始设备制造商,以及微软等操作系统供应商。几乎所有计算机上都预装了Microsoft KEK。
- Signature Database(db):签名数据库(db)本质上是引导二进制文件的白名单。具有可以通过db中的公钥验证的签名的二进制文件将被允许在引导时执行。大多数计算机在db中预装了两个Microsoft密钥。您计算机的OEM也可能安装了自己的密钥。
- Forbidden Signature Databases(dbx):dbx是个黑名单,位于dbx中的文件禁止引导执行。
可以通过以下指令查看密钥:
efi-readvar -v PK
efi-readvar -v KEK
efi-readvar -v db
efi-readvar -v dbx
通过以下指令查看PK/KEK/db/dbx内公钥和哈希值:
mokutil --pk
mokutil --kek
mokutil --db
mokutil --dbx
2. 备份在生成自己的密钥并替换UEFI安全启动设置前,可以先进行备份以便需要时可以恢复。
mkdir -vp /keys/{auth,bak,cfg,esl,ms,oem}
efi-readvar > /keys/bak/all-efi-keys-original.txt
efi-readvar -v PK -o /keys/bak/PK-original.esl
efi-readvar -v KEK -o /keys/bak/KEK-original.esl
efi-readvar -v db -o /keys/bak/db-original.esl
efi-readvar -v dbx -o /keys/bak/dbx-original.esl
3. BIOS设置现在首先要移除已经存在的密钥并修改安全启动模式。
不同OEM厂商的BIOS设置可能会有所不同,请根据自己的平台设置。
删除密钥:
如果可以,需要修改安全启动模式为用户模式(User Mode)。这样才可以直接通过操作系统修改密钥信息。
4. 生成密钥4.1 PK X509证书创建一个配置文件:
vim /keys/cfg/PK.cfg
添加以下内容。可以根据需要对“commonName”和“emailAddress”修改。参数“CA:FALSE”表示该证书是自签名的,并非来自认证机构。
[ req ]
default_bits = 4096
encrypt_key = no
string_mask = utf8only
utf8 = yes
prompt = no
distinguished_name = my_dist_name
x509_extensions = my_x509_exts
[ my_dist_name ]
commonName = Test Platform Key
emailAddress = test@test.com
[ my_x509_exts ]
keyUsage = digitalSignature
extendedKeyUsage = codeSigning
basicConstraints = critical,CA:FALSE
subjectKeyIdentifier = hash
创建基于X509证书的PK密钥对。X509证书必须是PEM格式,这里设置过期时间为15年。
openssl req -x509 -sha256 -days 5490 -outform PEM \
-config /keys/cfg/PK.cfg \
-keyout /keys/PK.key -out /keys/PK.pem
创建完成后可以用以下指令来检查PK公钥:
openssl x509 -text -noout -inform PEM -in /keys/PK.pem
4.2 KEK X509证书cp -v /keys/cfg/{PK,KEK}.cfg
sed -i 's/Platform Key/Key Exchange Key/g' /keys/cfg/KEK.cfg
openssl req -x509 -sha256 -days 5490 -outform PEM \
-config /keys/cfg/KEK.cfg \
-keyout /keys/KEK.key -out /keys/KEK.pem
openssl x509 -text -noout -inform PEM -in /keys/KEK.pem
4.3 db X509证书cp -v /keys/cfg/{PK,db}.cfg
sed -i 's/Platform Key/Signature Database/g' /keys/cfg/db.cfg
openssl req -x509 -sha256 -days 5490 -outform PEM \
-config /keys/cfg/db.cfg \
-keyout /keys/db.key -out /keys/db.pem
openssl x509 -text -noout -inform PEM -in /keys/db.pem
5. 转换证书为AUTH格式要在安全启动中注册密钥,它们必须是AUTH格式。为此,首先将您的公钥(pem)转换为EFI签名列表(esl)格式,然后通过使用您的私钥签名转换为具有身份验证标头(auth)格式的EFI签名列表。 您必须为EFI_CERT_X509_GUID类型签名提供8-4-4-4-12格式的唯一ID。uuidgen命令可用于生成此。
echo "$(uuidgen --random)" > /keys/guid.txt
PK:
cert-to-efi-sig-list -g "$(< /keys/guid.txt)" \
/keys/PK.pem /keys/esl/PK.esl
sign-efi-sig-list -g "$(< /keys/guid.txt)" \
-t "$(date +'%F %T')" \
-c /keys/PK.pem -k /keys/PK.key \
PK \
/keys/esl/PK.esl /keys/auth/PK.auth
KEK:
cert-to-efi-sig-list -g "$(< /keys/guid.txt)" \
/keys/KEK.pem /keys/esl/KEK.esl
sign-efi-sig-list -g "$(< /keys/guid.txt)" \
-t "$(date +'%F %T')" \
-c /keys/PK.pem -k /keys/PK.key \
KEK \
/keys/esl/KEK.esl /keys/auth/KEK.auth
db:
cert-to-efi-sig-list -g "$(< /keys/guid.txt)" \
/keys/db.pem /keys/esl/db.esl
sign-efi-sig-list -g "$(< /keys/guid.txt)" \
-t "$(date +'%F %T')" \
-c /keys/KEK.pem -k /keys/KEK.key \
db \
/keys/esl/db.esl /keys/auth/db.auth
6. 在UEFI安全启动链中注册密钥现在您已经将公钥转换为AUTH格式,您必须将它们注册到UEFI安全启动链中。 如果您将安全启动模式更改为用户模式,则可以使用命令注册密钥。您必须首先注册db.auth,然后注册KEK.auth,最后注册PK.auth。
efi-updatevar -f /keys/auth/db.auth db
efi-updatevar -f /keys/auth/KEK.auth KEK
efi-updatevar -f /keys/auth/PK.auth PK
// check all public kyes
efi-readvar
如果没有用户模式(User Mode),则需要在BIOS菜单中注册。不同OEM厂商的BIOS设置不同。
7. 签名启动文件为了在启动安全启动后可以正常加载系统,需要对bootloader和kernel签名。
在启用shim的机器上,grub和boot都由shim引导,对应的文件是/boot/efi/EFI/fedora/shimx64.efi 在没有shim的机器上,需要对/boot/efi/EFI/BOOT/grubx64.efi和/boot/efi/EFI/BOOT/bootx64.efi签名
可以通过以下指令查看当前签名状态:
# pesign -S -i /boot/efi/EFI/fedora/shimx64.efi
---------------------------------------------
certificate address is 0x7fd480f79cc8
Content was not encrypted.
Content is detached; signature cannot be verified.
The signer's common name is Microsoft Windows UEFI Driver Publisher
No signer email address.
No signing time included.
There were certs or crls included.
---------------------------------------------
移除微软的签名信息:
pesign -r -u0 -i /boot/efi/EFI/fedora/shimx64.efi \
-o /boot/efi/EFI/fedora/shimx64.efi.empty
用db公私钥对启动文件签名:
sbsign /boot/efi/EFI/fedora/shimx64.efi.empty \
--key /keys/db.key --cert /keys/db.pem \
--output /boot/efi/EFI/fedora/shimx64.efi
sbsign /boot/vmlinuz-6.6.35-3.cm2 \
--key /keys/db.key --cert /keys/db.pem \
--output /boot/vmlinuz-6.6.35-3.cm2
签名完成后,可以通过下面指令验证:
# sbverify --cert /keys/db.pem /boot/vmlinuz-6.6.35-3.cm2
Signature verification OK
现在可以重启系统,在BIOS设置中启用安全启动功能。 可以正常进入系统,通过以下命令确认安全启动已经打开。
# mokutil --sb-state
SecureBoot enabled
参考:https://sysguides.com/fedora-uefi-secure-boot-with-custom-keys
|