首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

Linux安全启动及Machine Owner Key(UEFI BIOS MBR GPT GRUB)

编程知识
2024年07月21日 18:48

PS:要转载请注明出处,本人版权所有。

PS: 这个只是基于《我自己》的理解,

如果和你的原则及想法相冲突,请谅解,勿喷。

环境说明

  无

前言


  只要装过各种系统的人都或多或少会接触到UEFI或者BIOS这样的概念。本文也不会对这些概念进行详解,本文主要把这些概念串起来,并引入MOK(Machine Owner Key)。

  为什么需要MOK,是因为在使用现代linux系统时(如:PVE),如果我们需要自己安装一些自己构建的驱动(例如想实现gpu sr-iov),会用到此功能。





UEFI/BIOS


  BIOS (Basic Input/Output System) 和UEFI (Unified Extensible Firmware Interface) 这两个名字或者功能我们非常的熟悉了,机器开机自检完成后,一般f2/del等进入的界面,就是这个系统在显示工作。如果我们不按f2/del等键,系统会默默运行BIOS或者UEFI,然后自动加载引导程序,然后加载OS来运行。

  UEFI主要是为了取代BIOS系统的,因为其有:支持更多分区、启动速度快、支持更多硬件、更加安全、维护简单(统一标准)等等优点。其有个大的缺点就是,有些时候会因为安全的问题,需要更多的设置过程。

  对于BIOS来说,机器开机自检完成后,自动读取MBR(Master boot record),一般在磁盘的开始的扇区,然后加载OS或者其他进行启动。注意,这里MBR分区是一种老旧的分区格式了。

  对于UEFI来说,机器开机自检完成后,自动读取GPT分区(GUID Partition Table)中的EFI分区,然后加载OS或者其他进行启动。

  总的来说,随着时间的推进,UEFI是一种标准,已经被各大厂商支持和实现了。BIOS其已经完成了其历史的作用,除了为了兼容老机器,否则我们不应该使用它。





Linux 在UEFI下,自构建驱动安装问题


  这里有一个背景知识,那就是现代的linux内核,在加载内核驱动的时候,一般都会对内核驱动做一系列校验,其中一项就是做签名校验,如果校验失败,内核拒绝加载驱动。对于这部分内容,可以参考《Linux驱动加载源码分析(安全加载 、签名、校验)》 https://www.cnblogs.com/Iflyinsky/p/18301894 一文。

  在《常用加密及其相关的概念、简介(对称、AES、非对称、RSA、散列、HASH、消息认证码、HMAC、签名、CA、数字证书、base64、填充)》 https://www.cnblogs.com/Iflyinsky/p/18076852 中我们介绍了签名的原理,这里简单提一下:首先有非对称加密算法生成公钥、私钥。然后对消息进行摘要,对摘要进行私钥加密得到签名,最后可以用公钥来验证(解密)此签名是否正确。

  那么对应到内核驱动签名验证这里就是:首先对驱动模块使用私钥进行签名,并将签名文件写入驱动模块文件中,当我们加载驱动模块时,内核会使用其带的公钥来对驱动模块进行签名验证。

  注意,这里有一个重要的问题是:内核带的公钥是哪里来的?一般来说,有两个渠道可以增加内核的公钥,一个是编译内核的时候,一个是通过运行时的一些方法动态写入一些公钥到内核。



Machine Owner Key


  在实际我们自己测试自己的驱动模块的时候,一般都会自己生成一个私钥,公钥对来对自己的驱动模块进行签名。但是在启用的UEFI+ 支持安全启动的linux系统上,我们的驱动模块是无法正常加载的,因为我们的驱动无法过签名验证。

  从上面的描述来看,如果要成功加载我们的内核模块,那么我们应该把我们的公钥传给内核。

  在解决怎么把公钥传给内核前,我们第一步要简单了解一下linux secure boot的简单流程:

  • 机器开机及硬件自检完成,然后进入uefi固件,uefi固件里面有微软公钥。
  • uefi加载shim固件(独立与linux发行版,被微软私钥预先签名,例如这个包: https://packages.debian.org/sid/amd64/shim-signed )。此外shim有各大发行版公钥。
  • shim固件加载grub固件(grub固件被各大发行版私钥签名)。
  • grub加载linux签名内核。

  其实从上面的流程来看,就是一环环签名校验,保证了信任链的传递。

  回到我们之前的问题,我们怎么把我们私钥、公钥传给内核呢?必定是有一个工具能够将相关信息传进去,这个工具就是mokutil工具。



mokutil

  简而言之,shim除了自带发行版的公钥外,还维护一个用户可以操作的密钥数据库,里面存储的是Machine Owner Key。通过mokutil工具,我们可以增加和删除这些密钥。这样我们就可以将我们自己的模块签名公钥嵌入到了UEFI启动流程中去,然后根据适当的方法即可交给内核使用,并能够加载我们自己密钥签名的驱动程序。

  mokutil工具添加过程:

  1. 导入公钥
mokutil --import /var/lib/dkms/mok.pub 
# 并输入一次性密码
  1. 重启系统,此时新一次的uefi的启动流程会启动mok管理器,让用户按照要求注册新的密钥,并输入之前的一次性密码。(弹个框,自己选择,输入密码即可)

  2. 这样启动系统后,我们的密钥成功加载。

  3. 测试系统是否成功注册密码

mokutil --test-key /var/lib/dkms/mok.pub

  这样我们就可以使用mok.pub对应的私钥对我们的驱动进行签名,然后就可以正常使用公钥验证,然后加载驱动了。

  此外,这里还要多提一下,其实android的安全加载也有类似的过程,也是两个要点:信任链传递、驱动签名。





后记


  了解了越来越多计算机的知识,不得不感叹:知识总是不经意间出现在日常生活工作中。

参考文献




打赏、订阅、收藏、丢香蕉、硬币,请关注公众号(攻城狮的搬砖之路)
qrc_img

PS: 请尊重原创,不喜勿喷。

PS: 要转载请注明出处,本人版权所有。

PS: 有问题请留言,看到后我会第一时间回复。

From:https://www.cnblogs.com/Iflyinsky/p/18314889
本文地址: http://shuzixingkong.net/article/256
0评论
提交 加载更多评论
其他文章 LLM-01 大模型 本地部署运行 ChatGLM2-6B-INT4(6GB) 简单上手 环境配置 单机单卡多卡 2070Super8GBx2 打怪升级!
超详细从0-1部署ChatGLM2-6B-INT4(6GB),双卡 2070 Super 8GB * 2,后续一步一步对大模型进行微调测试!
LLM-01 大模型 本地部署运行 ChatGLM2-6B-INT4(6GB) 简单上手 环境配置 单机单卡多卡 2070Super8GBx2 打怪升级! LLM-01 大模型 本地部署运行 ChatGLM2-6B-INT4(6GB) 简单上手 环境配置 单机单卡多卡 2070Super8GBx2 打怪升级! LLM-01 大模型 本地部署运行 ChatGLM2-6B-INT4(6GB) 简单上手 环境配置 单机单卡多卡 2070Super8GBx2 打怪升级!
NSSCTF———Web(sql注入)
[LitCTF 2023]这是什么?SQL !注一下 ! [SWPUCTF 2022 新生赛]ez_sql [GXYCTF 2019]BabySqli 点击右下角文章可跳转 [LitCTF 2023]这是什么?SQL !注一下 ! 首先我们打开靶场查看信息,提示了闭合方式为id = (((((())
NSSCTF———Web(sql注入) NSSCTF———Web(sql注入) NSSCTF———Web(sql注入)
一文全懂:独立冗余磁盘阵列(RAID)
本文介绍了独立冗余磁盘阵列RAID的四种常见模式:RAID0、RAID1、RAID5、RAID10,并且使用mdadm命令在liux系统上如何创建磁盘阵列的详细步骤。
一文全懂:独立冗余磁盘阵列(RAID) 一文全懂:独立冗余磁盘阵列(RAID) 一文全懂:独立冗余磁盘阵列(RAID)
方法引用
方法引用有什么用? 写更少代码 提高代码复用性和可维护性(尤其是团队项目中) 引用静态方法如果你要引用的是一个静态方法,你可以使用类名::静态方法的形式。例如, 将集合中String类型数据转换成int类型这是匿名内部类的写法:查看parsInt源码可以发现该方法满足静态方法引用的条件.因此可以直接
方法引用 方法引用 方法引用
salesforce零基础学习(一百四十)Record Type在实施过程中的考虑
本篇参考: salesforce 零基础学习(二十九)Record Types简单介绍 https://help.salesforce.com/s/articleView?id=sf.customize_recordtype_considerations.htm&type=5 https:/
Ubuntu16.04升级openssh-9.8p1
7月1日OpenSSH官方发布安全更新,忙着处理的同时记录一下升级过程。 系统环境 root@NServer:~# cat /proc/version Linux version 3.4.113-sun8i (root@test) (gcc version 5.5.0 (Linaro GCC 5.5
Ubuntu16.04升级openssh-9.8p1 Ubuntu16.04升级openssh-9.8p1 Ubuntu16.04升级openssh-9.8p1
自学考试(北邮)计算机专业毕业总结
本文目的 2024年是北京自学考试专业过渡期,恰好赶在过渡期前完成了专业的全部课程,于是2024上半年开始毕业论文与设计并完成了答辩,赶在收到毕业证这天总结一下,给后续北邮自考生一点参考,给自己这5年的努力作个总结。 毕业要求所学专业的所有笔试、实践科目、论文成绩均合格,其中笔试、实践是比较常规的考
自学考试(北邮)计算机专业毕业总结 自学考试(北邮)计算机专业毕业总结 自学考试(北邮)计算机专业毕业总结
Java JVM——13. 垃圾回收算法
1.生存还是死亡? 在堆里存放着几乎所有的 Java 对象实例,在 GC 执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC 才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们称为垃圾标记阶段。 那么在 JVM 中究竟是如何标记
Java JVM——13. 垃圾回收算法 Java JVM——13. 垃圾回收算法 Java JVM——13. 垃圾回收算法