Ubuntu Linux从加密的根分区中启动的过程分析

Ubuntu Linux从加密的根分区中启动的过程分析

在现代 Linux 系统中,很多用户选择加密根分区以提高数据安全性。本文将详细解释 Ubuntu Linux 如何从加密的根分区启动。

1. 安装 Ubuntu 并启用加密根分区

在安装 Ubuntu 时,可以选择“LVM 与加密”选项。启用此选项后,Ubuntu 安装程序会自动配置加密分区,使根分区通过 LUKS(Linux Unified Key Setup)加密,确保系统文件和用户数据的安全性。
选择加密磁盘

1.1 启用加密的分区结构

选择加密安装选项后,Ubuntu 会自动创建一个 LUKS 加密的物理卷,并在其上配置 LVM。LVM(逻辑卷管理)允许在加密的物理分区上灵活创建逻辑卷,如根卷和交换分区,从而便于分区管理。

1.2 /etc/crypttab 文件

安装完成后,系统生成 /etc/crypttab 文件(类似于 /etc/fstab),该文件定义了需要在启动时解密的加密分区。/etc/crypttab 文件会被打包到 initramfs 中,以便在系统启动过程中读取和执行解密操作,确保根分区的正确挂载。

安装过程相对简便,下面我们深入探讨系统的启动过程。


2. GRUB 加载 Linux 内核

在 Ubuntu 的默认加密方案中,ESP 分区和 /boot 目录未加密,只有根分区被加密。因此,GRUB(GRand Unified Bootloader)可以直接访问 /boot 分区中的内核和 initramfs 文件。

2.1 GRUB 启动流程

在启动过程中,GRUB 首先加载未加密的 /boot 分区上的内核和 initramfs。initramfs 是启动早期阶段使用的一个临时内存文件系统,包含了解密分区所需的工具和脚本。GRUB 将这些文件加载至内存中,并将控制权移交给内核。

:若将 /boot 目录也置于加密分区,GRUB 启动流程会更加复杂,但仍可以实现启动。本文主要讨论 /boot 分区未加密的情况。

2.2 Linux 内核启动

加载内核和 initramfs 后,GRUB 将控制权交给内核。此时,内核开始执行其启动流程,并初始化 initramfs,以准备解密根分区。

关于grub加载内核的详细过程可以参考这篇文章 Linux操作系统开机启动的过程–使用GRUB引导


3. initramfs 挂载加密的根分区

内核启动后,initramfs 接管系统的早期启动阶段,负责解密和挂载根分区。

3.1 解密根分区的主要逻辑

initramfs 主要通过 cryptroot 脚本完成解密根分区的任务。cryptroot 脚本位于 /usr/share/initramfs-tools/scripts/local-top/cryptroot。流程如下:

init  # 这是 initramfs 的初始化脚本
-> mount_top()
   -> local_top()
       -> cryptroot  # 解密加密的根分区
           -> run_keyscript()  # 提示用户输入密码
           -> unlock_mapping() # 调用 cryptsetup 解密
-> mountroot
   -> local_mount_root()  # 挂载解密后的根分区

3.2 识别加密的根分区

update-initramfs 命令会将 /etc/crypttab 文件打包进 initramfs 中。cryptroot 脚本读取 /etc/crypttab 文件以识别加密分区的详细信息。

3.2.1 /etc/crypttab 文件的结构

/etc/crypttab 文件中,每行表示一个加密分区,其格式如下:

<name> <device> <password> <options>

# 示例
sda5_crypt UUID=ba5bfb44-7a96-4973-b1d1-d42f989b3d57 none luks,discard
  • name:加密分区的逻辑名称,如 sda5_crypt,在解密后作为挂载点的标识。
  • device:设备路径或 UUID(唯一标识符),指向加密设备。
  • password:可以是密码文件的路径,也可以设置none以在启动时提示用户输入密码。
  • options:额外选项,如加密类型或解密方式等。
    在启动过程中,initramfscryptroot 脚本负责解密根分区(打开根分区),以便后续挂载操作。这个过程涉及解析 /etc/crypttab 文件,通过其中的参数来调用 cryptsetup 工具打开加密的根分区。以下是详细的过程:

3.3 解密根分区

对于每个加密分区,cryptroot 脚本根据 /etc/crypttab 中的信息使用 cryptsetup 命令解密。具体过程如下:

  1. 检查设备路径cryptroot 检查 device 字段,确保指定的设备路径或 UUID 存在并可访问。若设备路径无效,cryptroot 会记录错误并跳过该分区。
  2. 输入密码
    如果 /etc/crypttabpassword 字段为none,系统会在启动时提示用户手动输入密码。
    若指定了密码文件,cryptroot 会尝试从文件中读取密码,并传递给 cryptsetup 进行解密。
  3. 执行解密命令
    使用 cryptsetup open 命令并传入相应参数,cryptroot 解密分区并将其映射到 /dev/mapper/<name> 下。例如,以下命令用于解密并映射分区:
    cryptsetup open --type luks /dev/sda5 sda5_crypt
    
    这里的 --type luks 指定加密类型为 LUKS/dev/sda5 是物理设备路径,而 sda5_crypt 是解密后的设备名称。在成功解密后,系统会在 /dev/mapper/sda5_crypt 中生成一个映射设备。
  4. 验证解密状态
    cryptsetup 会返回解密的状态码。若解密失败,cryptroot 会显示错误信息并可能中止启动过程,提示用户重新尝试输入密码或检查设备配置。
  5. 应用额外选项
    cryptroot 会根据 options 字段设置其他参数。例如,若指定了 discard 选项,则启用 TRIM 支持,优化对 SSD 的性能。

此时,根分区已经解密,系统可以将其挂载为根文件系统,从而为启动提供访问权限。

3.4 挂载根分区

3.4.1 进入挂载阶段

解密操作完成后,解密后的设备通常位于 /dev/mapper/<name> 路径下(例如 /dev/mapper/sda5_crypt)。接下来,initramfs 将进入挂载阶段。此阶段的主要任务是将解密后的设备挂载为根文件系统,以便系统能够正确加载其他文件和服务。

启动流程中 initramfs 的核心脚本 init 将执行以下步骤:

init  # initramfs 的初始化脚本
-> mount_top()
   -> local_top()  # 处理解密和加载操作
-> mountroot       # 进入根分区的挂载阶段
   -> local_mount_root()  # 实际挂载解密后的根分区
3.4.2 local_mount_root() 函数完成挂载

local_mount_root() 是 initramfs 中负责挂载根文件系统的关键函数,其主要步骤如下:

  • 确定挂载设备
    local_mount_root() 首先确定应挂载的设备,即已成功解密的根分区。例如,根分区的挂载目标通常是 /dev/mapper/sda5_crypt。该设备路径在 cryptroot 解密阶段已被映射,因此可以直接用于挂载操作。
  • 挂载根分区
    local_mount_root() 使用标准的 mount 命令将解密的根分区挂载到根目录 / 上。简化后的逻辑大致如下, 实际过程比这稍微复杂一点:
    mount /dev/mapper/sda5_crypt /
    
    这个操作将解密的分区作为系统的根文件系统挂载,以便系统能够访问并读取该分区上的所有目录和文件。
  • 检查挂载状态
    挂载完成后,local_mount_root() 会验证是否成功挂载。如果挂载失败,系统可能会进入紧急模式(emergency mode),要求用户进行进一步的手动干预。这种检查对于确保根文件系统的可用性和完整性非常重要。

经过这些步骤后,initramfs 的任务已全部完成,解密的根分区已成功挂载为系统的根文件系统,系统将继续加载用户空间环境中的服务和应用,完成引导流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值