虚拟机Secure Boot安全启动

您所在的位置:网站首页 bios安全启动可以关闭吗 虚拟机Secure Boot安全启动

虚拟机Secure Boot安全启动

2024-07-17 16:43| 来源: 网络整理| 查看: 265

概述

Secure Boot 作为 UEFI 的一个选项,它可以被设置为开启或关闭。 Secure Boot 所需要的公钥证书被保存在计算机的主板的 FLASH 里面,FLASH 里面保存着 PK , KEK, db, dbx 的证书链。下面我们在虚拟机中使能Secure Boot功能,可以在虚拟机中实验,这样比较安全。

工具

以下工具是必不可少的:

openssl efitools sbsigntools

在有些系统上 efitools 和 sbsigntools 无法直接获取,请从源码包编译,其中efitools依赖 sbsigntools。

yum install -y perl-File-Slurp.noarch git clone https://gitee.com/mirrors_kernel_googlesource/efitools.git git clone https://git.kernel.org/pub/scm/linux/kernel/git/jejb/sbsigntools.git/

在用源代码编译 efitools 时,需要 Perl 的一个模块,名字为 File Slurp,上面的命令安装该 module。

步骤

这里简要介绍 PK,KEK,db,dbx 和 MOK 的概念。

Platform Key (PK) - PK 是用于在硬件平台层和硬件平台拥有者建立起的信任关系 ,规定一个硬件平台只能被一个拥有者所拥有,即 PK 只能存在一个 ,与拥有者相关的公钥被存储在 FLASH 里面的 PK 变量里面,同时,拥有者的私钥可以来对 PK, KEK, db, dbx 进行签名和管理。

Key Exchange Key (KEK) - KEK 是用于在硬件平台和操作系统之间建立信任关系 ,KEK 的公钥可以在主板的 FLASH 存在多个不同项,即 KEK 可以存在多个 ,每一项对应一种可以被启动的操作系统,同样,KEK 的私钥可以来对 db, dbx 进行签名和管理。

Database (db) - db 是用于对 被许可的 EFI 文件予以加载的数据签名库 ,和 KEK 一样, db 的公钥可以存在很多项 。(在 UEFI 平台里面,操作系统加载文件就是一个 EFI 文件)

Database Excluded (dbx) - dbx 是一个 黑名单数据签名库 ,只要谁的 EFI 签名在这,谁就被屏蔽掉, dbx 的公钥也可以存在很多项 。后面不会使用这个。

下面主要是有两种方式将证书更新到 flash 中,一种通过 efivar 方式,另外一种是通过 BIOS 图形界面,前者需要创建EFI list 文件,之后可以通过命令行自动化操作;而后者需要的证书文件较少,但是需要通过图形界面进行操作。

自动化导入证书

建立 PK,KEK,db 密钥对,同时还需要创建EFI list。

建立密钥对

openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Platform Key/" -keyout PK.key -out PK.crt -days 3650 -nodes -sha256

上面的 -subj 的参数可以自己设置,参数 -days 是密钥的有效期,这里设置为 10 年,也可以设置为其他,生成私钥 PK.key,公钥 PK.crt。

同理,KEK 和 db 亦是如此:

openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Key Exchange Key/" -keyout KEK.key -out KEK.crt -days 3650 -nodes -sha256 openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Database/" -keyout db.key -out db.crt -days 3650 -nodes -sha256

建立 EFI List 文件 EFI List 文件其实就是公钥配以平台拥有者的 GUID 的文件,所以这里我们需要有一个GUID,可以通过uuidgen 生成。

guid=$(uuidgen) cert-to-efi-sig-list -g $(cat guid) PK.crt PK.esl cert-to-efi-sig-list -g $(cat guid) KEK.crt KEK.esl cert-to-efi-sig-list -g $(cat guid) db.crt db.esl

这样三个公钥就全变成 List 文件了。

给 List 文件签名

sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.esl.signed sign-efi-sig-list -k PK.key -c PK.crt KEK realKEK.esl realKEK.esl.signed sign-efi-sig-list -k KEK.key -c KEK.crt db realDB.esl realDB.esl.signed

上述中,平台的 Key 权限最高,可以对 PK 本身,和 KEK 签名,KEK 是建立操作系统和硬件平台之间的信任关系,它只用于对于 db 进行签名。

完整的脚本:

#!/bin/bash echo -n "请输入一个通用名,比如公司名称或个人名字: " read NAME openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME PK/" -keyout PK.key \ -out PK.crt -days 3650 -nodes -sha256 openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME KEK/" -keyout KEK.key \ -out KEK.crt -days 3650 -nodes -sha256 openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME DB/" -keyout DB.key \ -out DB.crt -days 3650 -nodes -sha256 openssl x509 -in PK.crt -out PK.cer -outform DER openssl x509 -in KEK.crt -out KEK.cer -outform DER openssl x509 -in DB.crt -out DB.cer -outform DER echo $(uuidgen) > myGUID.txt cert-to-efi-sig-list -g $GUID PK.crt PK.esl cert-to-efi-sig-list -g $GUID KEK.crt KEK.esl cert-to-efi-sig-list -g $GUID DB.crt DB.esl rm -f noPK.esl touch noPK.esl sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \ -k PK.key -c PK.crt PK PK.esl PK.auth sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \ -k PK.key -c PK.crt PK noPK.esl noPK.auth sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \ -k PK.key -c PK.crt KEK KEK.esl KEK.auth sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \ -k KEK.key -c KEK.crt db DB.esl DB.auth echo "" echo "For use with KeyTool, copy the *.auth and *.esl files to a FAT USB" echo "flash drive or to your EFI System Partition (ESP)." echo "For use with most UEFIs' built-in key managers, copy the *.cer files." echo ""

更新到虚拟机的证书列表中 通过写入 efivars 的方式更新到 flash 中,首先必须保证系统的 efivarfs 被正确挂载,ls 一下 /sys/firmware/efi/efivars/ 是否存在文件,否则需要手动挂载:

# mount -t efivarfs efivarfs /sys/firmware/efi/efivars/

再把那三个签过名的 List 文件写入主板:

# efi-updatevar -f PK.esl.signed PK # efi-updatevar -f realKEK.esl.signed KEK # efi-updatevar -f realDB.esl.signed db 图形界面导入证书

图形化导入证书只识别后缀名为 .crt, .der , .cer的证书,但是编码方式需要是 DER,所以需要对证书进行一次转换。

openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME PK/" -keyout PK.key \ -out PK.crt -days 3650 -nodes -sha256 openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME KEK/" -keyout KEK.key \ -out KEK.crt -days 3650 -nodes -sha256 openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME DB/" -keyout DB.key \ -out DB.crt -days 3650 -nodes -sha256 openssl x509 -in PK.crt -out PK.cer -outform DER openssl x509 -in KEK.crt -out KEK.cer -outform DER openssl x509 -in DB.crt -out DB.cer -outform DER

之后将证书拷贝到磁盘中,在虚拟化中可以将宿主机文件镜像以磁盘的形式呈现给虚拟机,我们这里使用单独的一个文件镜像来存储证书。

dd of=data.img if='/dev/zero' bs=1M count=16 mkfs.vfat -I data.img mkdir mnt mount data.img mnt cp -a /path/to/certificates/* mnt umount mnt/ rm -rf mnt

将文件镜像添加到虚拟机磁盘列表,可以通过virt-manager或者配置文件。

图形化导入证书

在启动过程中进入启动菜单,选择Security, 这个菜单可能出现的位置稍有不同。 在这里插入图片描述进入Secure Boot Configuration 之后,选择Secure Boot Mode中的Custom Mode, 会多出来一个菜单 在这里插入图片描述进入Custom Secure Boot Options 中进行证书导入 在这里插入图片描述选择导入PK 在这里插入图片描述选择证书文件 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述导入证书,将证书存储到flash中 在这里插入图片描述 其他两个KEK 和 DB 可以导入也可以选择不导入,但是PK 是必须的。 在之后会提示你需要重启来使刚才的证书和配置生效,此时如果没有对grub 进行签名,需要暂时禁掉 Secure Boot功能。 给二进制的 EFI 文件签名

这是密钥管理和签名的最后一步,给 grub 的 EFI 文件签名:

sbsign --key db.key --cert db.crt --output grubx64.efi.signed /boot/efi/EFI/BOOT/grub64.efi

可以不用给内核 vmlinuz 签名,毕竟 vmlinuz 不是硬件平台的启动 EFI 文件,不过给内核签名也没什么影响,如果想给内核签名类似于给 grub 签名,用 私钥 db.key 及对应的公钥 db.crt 对其签名,这里用的 db 是那个自己创建的 db ,即没有合并微软 db 的那个,合并了微软 db 的是 realDB 。 现在vmlinuz基本都需要支持 EFI 启动,即生成vmlinuz.efi 作为一个EFI应用直接启动,绕过了grub,这种方式下需要使用同样的方式对其进行签名。

sbsign --key db.key --cert db.crt --output vmlinuz.efi.signed vmlinuz.efi 重启系统

重启之后在BIOS中开启Secure Boot 选项,然后一切应该正常了。。。



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3