本篇文章是想要安装一个较为安全的 archlinux。本文也会介绍为什么要使用这些技术,做到知其然知其所以然。
必须提前说明,这篇文章针对的是有一定基础的 Linux 用户,这不包含 Windows 用户,Windows 用户最好选择更简便的 archinstall 安装脚本。 同时我建议想要从 Windows 切换到 Linux 的用户先尝试不加密的系统,或者提供更简便安装流程的 Linux 发行版例如:openSUSE,对新手真的挺友好的。, 避免出师未捷身先死。先体验 Linux 生态,之后在考虑这篇文章提到的安装流程。同时这篇文章也不包括如何安装 archlinux 和 Windows 双系统。
理念
全盘加密(LUKS)
在本文中会配置 Full Disk Encryption (FDE)全盘加密根目录。在关机情况下,我们的硬盘将会处在完全加密的状态。 这意味着攻击着无法从硬盘中读取到任何有效信息。这将有效避免包括但不限于:电脑丢失、出二手和恶意取证1。
我们将使用 LUKS 来加密根目录,这种加密对系统来说是透明的也就是说系统并不知道硬盘加密了,它能看到的硬盘是解密的,所以也不需要系统做什么解密操作。。
systemd-boot
而我们将会选择 systemd-boot 作为启动引导方式2。它相较于 grub 更快,更简单,更清爽,维护的也更积极, 虽然会有一些代价在使用 grub 的情况下,我们可以通过使用更方便的 grub-btrfs 来快速选定过去的快照进行回滚。但是这并不像隔壁的 openSUSE 一样方便。arch 的回滚方式比较复杂。
UKI
为了使系统更安全,也为了安装更加简便,我们将使用 Unified Kernel Images (UKI)统一内核映像 来作为引导。
systemd-boot 可以自动的读取 UKI 来引导,而不用做过多的配置。这样可以使用在 archlinux 中被称为 esp 的分区格式我们会将硬盘分区为 /efi 和 root 两个区。。
我们只会挂载 esp 目录,而不用挂载整个 /boot 分区,这免去了我们加密引导的复杂性。整个系统中只有 esp 分区未加密。不过你并不用担心这会泄露什么信息。
esp 引导分区只包含 UKI 引导,这里面不包含任何机密信息,只是格式化的引导。而且我们后续会对 UKI 进行签名。3
Secure Boot
关于安全启动,是一个复杂的概念。我们只需要了解安全启动的关键点即可。2
在开启安全启动的情况下,在按下开机键的那一刻,BIOS 会读取在 BIOS 中的平台密钥你可以简单理解为用于签名 R 和验证的密钥。来验证接下来引导的内核是否经过正确的签名。 如果没有签名或者签名不正确 BIOS 会拒绝引导内核也就是上面说的签名 UKI。这可以有效防范恶意更改引导内核来窃取信息的攻击。 R 因为 archlinux 没有像 openSUSE 或者 Fedora 一样签名内核,安全引导是不使用的。不过我们可以自签名内核来达成引导。甚至某种情况来说这更加安全。 使用出厂自带的平台密钥可能会存在泄露或者与攻击者恶意合作,这令他们可以签名恶意内核,并通过这个经过签名的恶意内核启动系统来窃取信息。
Btrfs
我们使用 Btrfs 作为根分区文件系统,这允许我们使用更加灵活的分区方式,也允许我们不用关注分区大小这件事情,这可以避免出现某个分区空间不足造成的问题btrfs 会将分区视为一整个,通过挂载子卷的方式进行软分区。所有分区共同分享一个空间大小,所以不存在空间不足问题。。 而且,Btrfs 支持快照,这将允许我们使用 sanpper 或者 timeshift 来进行方便的也没有那么方便。快照和回滚。4
tpm2
如果你的硬件中不存在 TPM 那么你将无法使用这个功能现在一般都集成在 CPU 固件中了,一般都会有的。说个题外话,前段时间微软推广 Windows 11 的时候强制要求硬件必须存在 TPM 否则无法安装。当时被很多人解读为微软为了赚黑心钱,变相要求消费正更换硬件。还有很多人解读为为了添加后门,为了窃取计算机信息。我对此的解读是大陆地区很多人都忽视信息安全,但又盲目详细信息安全。认为我的电脑没什么可丢失的信息,甚至觉得没人会偷我的信息,这是大错特错!大陆地区为了所谓的信息安全要掌握在自己手中而造了很多轮子,例如国密等。前段时间微信爆出数据连接漏洞就是因为自己造轮子。说实话,安全协议或者算法最好使用公开的,经过广泛验证的模型,绝对!不要!自己造轮子!。
通过使用 TPM 你可以将开机输入硬盘密码的操作省略掉。密码将会交由 TPM 模块来进行处理。说一个简单的理解方式。当你系统启动后,硬盘需要密码进行解锁, 系统将会去询问 TPM 可否解锁硬盘5。如果 TPM 觉得现在环境安全,内核等配置没有被篡改,就告诉系统可以解锁硬盘这是一个相当简化的流程,实际工作流程并不是这样,甚至完全不是你想象中的那个样子。我对此也没有过多了解,这是一个复杂的话题。。
有些用户会担心 TPM 自动解密后会造成安全隐患,比如别人捡到了你遗失的电脑。直接按下开机键就可以自动解锁硬盘。事实上确实是这样,TPM 只能保护你硬盘遗失,注意是硬盘丢失,不是整机丢失。 毕竟 TPM 不知道按下开机按钮的是谁。开机后硬盘加密自动解锁,之后保护系统的是你的用户密码。我们使用 TPM 的宗旨是为了简化反复输入硬盘密码的流程。也就是硬件解锁的过程,软件层面由其他方式保护。
TPM 的保护是基于对硬件和软件的测量6。比如我们即将使用的 0+7这是一个最简化的测量值,只是为了启动 TPM 自动解锁,并不保证绝对安全!你需要去了解想要测量的值,并测试攻击是否被防御。
测量值,这代表着 TPM 会在开机过程中测量 UEFI 固件是否被更改,安全启动是否被关闭。如果出现问题,TPM 就会拒绝提供密钥自动解锁。
这保护了什么呢?在一个简化的攻击模型中用户可能会遭遇的攻击:
- 恶意用户企图直接取走硬盘读取信息。这将由 LUKS 加密保护,硬盘是加密的窃取者无法获取任何有效信息。
- 恶意用户企图通过注入恶意的内核来读取硬盘信息。这将有 Secure Boot 保护,未经签名的内核无法通过检查。
- 恶意用户企图通过更改引导 cmdline 来恶意窃取硬盘解锁密钥。这样由 TPM 保护,PCR 8 的值将会发生变化,TPM 将会拒绝自动解锁。
- 恶意用户企图通过冷启动7攻击来窃取已经 TPM 自动解锁的硬盘密钥。他成功了。对,它成功了,当前的方案不能防范这种攻击方式。 TPM 提供解密密钥后,密钥会被存放在内存中,而冷启动可以将内存读取下来,并通过分析获取密钥。不过你可以不使用 TPM 自动解锁,通过使用手动输入密码来阻止这种攻击。 代价是每次开机都要输入密码。这就是取舍。或者可以使用完整的内存加密8来防范。
Timeshift
之所以选择 Timeshift 而不是 snapper 主要是考虑到 snapper 配置复杂。而且我们使用 systemd-boot 启动,本身也无法使用在引导页面选择备份的个功能。 还不如直接使用 Timeshift 方便。不过我们的分区方式也符合 snapper 的要求,只需要按照 wiki 简单操作一下即可。
安装前准备
经过上面的解释,详细你也已经了解我们为什么要选用这些技术,以及可能存在的攻击面。其实最重要的是了解你可能会受到什么攻击,并做出针对性的防御。你无法防御所有攻击,那将使你的电脑变得不可用,或者极端复杂。
我的电脑是「华硕天选 4」
| cpu | gpu 0 | gpu 1 | ssd | ram |
|---|---|---|---|---|
| AMD R9 7940H | AMD 780 M | RTX 4060 | 512G | 32G |
接下来会有输入很多的命令。以 root@archiso ~ # sgdisk -n1:0:+512M -t1:ef00 -c1:EFI -N2 -t2:8304 -c2:LINUXROOT /dev/sda 为例,# 后面的 sgdisk -n1:0:+512M -t1:ef00 -c1:EFI -N2 -t2:8304 -c2:LINUXROOT /dev/sda 是命令。不要将 root@archiso ~ # 输入进去。
每个步骤我都会提供要输入的命令和命令的反馈,请做区分,不要重复操作。
下载镜像和验证
去 Arch Download 这个地址下载镜像。可以选择🧲磁力连接下载,或者地区镜像。
验证镜像,这很重要,这可以有效避免安装经过篡改的系统。验证方式在地址中有。
写入镜像
准备一个 U 盘。你可以选择使用命令,或者直接使用软件写入,例如 Impression。
将安全启动设置为设置模式
因为 archlinux 安装器无法运行在安全启动模式下,我们需要禁用安全启动。不过我们后续会自签名内核,所以直接设为设置模式比较好。
备份
danger
在开始之前一定要备份!而且你需要确定你的机器是否可以移除平台密钥,某些机器移除平台密钥后可能会直接变砖,因为机器的某些硬件使用微软的平台密钥签名。
如果你跟我一样用的是「华硕天选 4」,你可以直接进入 BIOS 找到安全启动设置,然后备份密钥。
或者你可以使用 efitools 包来备份9。
efi-readvar -v PK -o old_PK.esl
efi-readvar -v KEK -o old_KEK.esl
efi-readvar -v db -o old_db.esl
efi-readvar -v dbx -o old_dbx.esl进入设置模式
其实我也不知道为啥叫设置模式,也许是因为可以自己设置平台密钥?
如果你是跟我一样的电脑,你可以进入 BIOS 后找到安全启动设置,然后选择移除所有密钥。这样就进入了恢复模式。
如果你是其他电脑你可以自己寻找一下进入设置模式的方法。
启动 LiveOS
你需要连接网络等操作。这里就不做介绍了,使用 Wifi 挺麻烦的,建议直接插网线。
还有你要确定你的电脑是 UEFI 启动,本教程不支持 BIOS 启动。
接下来我们将正式开始安装
检查你的硬盘
lsblkroot@archiso ~ # lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 813.4M 1 loop /run/archiso/airootfs
sda 8:0 0 8G 0 disk
sr0 11:0 1 1.1G 0 rom /run/archiso/bootmnt可以看到系统包含了三个块,loop0,sda,sr0。我们需要关注的只有 sda,这是我们需要安装的硬盘。
设置环境变量
export disk="/dev/sda"格式化根目录
清除之前硬盘中的分区表等信息。
wipefs -af $disk创建 GPT 分区表
sgdisk --zap-all --clear $disk写入分区表
partprobe $diskroot@archiso ~ # export disk="/dev/sda"
root@archiso ~ # wipefs -af $disk
root@archiso ~ # sgdisk --zap-all --clear $disk
Creating new GPT entries in memory.
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities.
The operation has completed successfully.
root@archiso ~ # partprobe $disk(可选) 随机填充数据到硬盘
这是为了清除可能存在的之前数据泄露,我们将会使用一种快速的填充方式10。
开启一个临时加密盘
cryptsetup open --type plain -d /dev/urandom $disk target使用 0 填满加密盘,因为开启了加密盘,所有数据都会被加密,而我们填写 0 来填满数据就会清除之前硬盘中的残留数据。以规避之前数据泄露。
dd if=/dev/zero of=/dev/mapper/target bs=1M status=progress oflag=direct关闭加密盘
cryptsetup close targetroot@archiso ~ # cryptsetup open --type plain -d /dev/urandom $disk target
WARNING: Using default options for cipher (aes-xts-plain64, key size 256 bits) that could be incompatible with older versions.
For plain mode, always use options --cipher, --key-size and if no keyfile is used, then also --hash.
WARNING: Device /dev/sda already contains a 'gpt' partition signature.
WARNING!
========
Detected device signature(s) on /dev/sda. Proceeding further may damage existing data.
Are you sure? (Type 'yes' in capital letters): YES
root@archiso ~ # dd if=/dev/zero of=/dev/mapper/target bs=1M status=progress oflag=direct
8424259584 bytes (8.4 GB, 7.8 GiB) copied, 18 s, 468 MB/s
dd: error writing '/dev/mapper/target': No space left on device
8193+0 records in
8192+0 records out
8589934592 bytes (8.6 GB, 8.0 GiB) copied, 18.3393 s, 468 MB/s
1 root@archiso ~ # cryptsetup close target分区
我们分两个区,一个 ESP,一个 LUKS root 分区11。这里我们不创建 swap 分区。
这是一个 ESP 分区,也就是引导 /efi 分区,512M 大小。注意引导号 ef00。
sgdisk -n 0:0:+512MiB -t 0:ef00 -c 0:esp $disk这是一个 LUKS2 分区,占据剩余所有空间。引导号为 8309,这代表着 Linux LUKS
sgdisk -n 0:0:0 -t 0:8309 -c 0:luks $disk写入分区表
partprobe $diskroot@archiso ~ # sgdisk -n 0:0:+512MiB -t 0:ef00 -c 0:esp $disk
Creating new GPT entries in memory.
The operation has completed successfully.
root@archiso ~ # sgdisk -n 0:0:0 -t 0:8309 -c 0:luks $disk
The operation has completed successfully.
root@archiso ~ # partprobe $disk检查一下分区表是否正确
sgdisk -p $diskroot@archiso ~ # sgdisk -p $disk
Disk /dev/sda: 16777216 sectors, 8.0 GiB
Model: VBOX HARDDISK
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 9F19AB5D-08A8-40F7-9FAE-AE36F939123B
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 16777182
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 1050623 512.0 MiB EF00 esp
2 1050624 16777182 7.5 GiB 8309 luks加密
使用 cryptsetup 加密根目录,需要注意的是确定需要输入大写的「YES」
需要注意的是,如果你的硬件是 Nvme 设备,你需要将 ${disk}2 变为 ${disk}p2,实际上就是 /dev/sda2 或者 /dev/nvme0n1p2,这具体取决于你的设备。可以使用 lsblk 查看。
这里设置的 LUKS 密码为空,之后我们会取消这个密码槽,只是为了方便操作。
cryptsetup luksFormat --type luks2 ${disk}2root@archiso ~ # cryptsetup luksFormat --type luks2 ${disk}2
WARNING!
========
This will overwrite data on /dev/sda2 irrevocably.
Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/sda2:
Verify passphrase:
cryptsetup luksFormat --type luks2 ${disk}2 15.59s user 0.33s system 151% cpu 10.487 total开启加密块
cryptsetup open ${disk}2 linuxrootroot@archiso ~ # cryptsetup open ${disk}2 linuxroot
Enter passphrase for /dev/sda2:
cryptsetup open ${disk}2 linuxroot 6.92s user 0.05s system 229% cpu 3.032 total格式化文件系统
格式化 /EFI 分区
mkfs.vfat -F32 -n EFI /dev/sda1root@archiso ~ # mkfs.vfat -F32 -n EFI /dev/sda1
mkfs.fat 4.2 (2021-01-31)格式化 /dev/mapper/linuxroot 为 btrfs。注意这里使用的是 /dev/mapper/linuxroot 这是上面开启的加密块。
mkfs.btrfs -f -L linuxroot /dev/mapper/linuxrootroot@archiso ~ # mkfs.btrfs -f -L linuxroot /dev/mapper/linuxroot
btrfs-progs v6.11
See https://btrfs.readthedocs.io for more information.
Performing full device TRIM /dev/mapper/linuxroot (7.48GiB) ...
NOTE: several default settings have changed in version 5.15, please make sure
this does not affect your deployments:
- DUP for metadata (-m dup)
- enabled no-holes (-O no-holes)
- enabled free-space-tree (-R free-space-tree)
Label: linuxroot
UUID: d6e9359c-b5e0-471b-9b6d-4d2c9e8f6caa
Node size: 16384
Sector size: 4096 (CPU page size: 4096)
Filesystem size: 7.48GiB
Block group profiles:
Data: single 8.00MiB
Metadata: DUP 256.00MiB
System: DUP 8.00MiB
SSD detected: no
Zoned device: no
Features: extref, skinny-metadata, no-holes, free-space-tree
Checksum: crc32c
Number of devices: 1
Devices:
ID SIZE PATH
1 7.48GiB /dev/mapper/linuxroot创建 Btrfs 子卷
挂载根分区
mount /dev/mapper/linuxroot /mnt创建子卷。这里的分区样式是一个基础的样式,你可能需要更细致地分区。当前分区是根据 archinstall 安装脚本得来。 分区主要是为了后续使用 Timeshift 备份。可以理解为将不需要备份的目录提取出来,避免备份。
| 子卷 | 挂载点 | 说明 |
|---|---|---|
| @ | / | 根目录 |
| @home | /home | 家目录,用户不希望回滚的时候丢失重要文件 |
| @cache | /var/cache | 缓存文件目录,缓存文件也没有必要回滚 |
| @log | /var/log | 日志文件目录,日志文件不希望回归,方便我们寻找问题 |
| @root | /root | root 用户目录,与 home 目录相同 |
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@cache
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@rootroot@archiso ~ # btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@cache
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@root
Create subvolume '/mnt/@'
Create subvolume '/mnt/@home'
Create subvolume '/mnt/@cache'
Create subvolume '/mnt/@log'
Create subvolume '/mnt/@root'可以使用此命令检查子卷是否正确,你的 ID 可能跟我不一样,这没有问题。
root@archiso ~ # btrfs subvolume list /mnt
ID 256 gen 10 top level 5 path @
ID 257 gen 10 top level 5 path @home
ID 258 gen 10 top level 5 path @cache
ID 259 gen 10 top level 5 path @log
ID 260 gen 10 top level 5 path @root卸载根分区
umount /mnt重新挂载所有分区
刚刚是为了创建子卷才挂载的分区,现在需要正式挂载目录。需要注意的是命令中 -t btrfs 只是为了标记挂载格式,方便智能补全,subvol 的选项 @xxx 是子卷名称。
这里开启了 zstd 压缩,可以稍微节省一些空间,主要是为了提供更好的性能,zstd:1 中的 1 指的是强度,可以从 1 - 5 之间选择,默认情况下是 3,
根据 wiki 的描述,启用 1 可以更好的碎片整理,减少文件系统 IO,会有更好的性能我并没有做基准测试等,不确定是否真的是这样。不过还是按照 wiki 上面的来吧。至于还有很多的选项可选,你可以参考 Btrfs wiki。
mount -t btrfs -o subvol=@,compress=zstd:1 -m /dev/mapper/linuxroot /mnt
mount -t btrfs -o subvol=@home,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/home
mount -t btrfs -o subvol=@cache,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/var/cache
mount -t btrfs -o subvol=@log,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/var/log
mount -t btrfs -o subvol=@root,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/root挂载 EFI 分区
mount -m /dev/sda1 /mnt/efi已过时的分区方案(update:2025-08-09)
下面的方案已经过时,可以参考,依照自己的需求进行分区。
对比现在的方案主要变更的位置是不再分区 @var-tmp @tmp @libvirt @docker
@srv usr-local @containers
具体的原因参照下表:
| 子卷 | 挂载点 | 说明 |
|---|---|---|
| @var-tmp | /var/tmp | 这里的临时文件大小也不大,而且也会自动移除,即便备份也不会占用太多空间。 |
| @tmp | /tmp | 在使用 Arch Linux 的情况下,/tmp 目录会被 systemd 挂载为 tmpfs 格式,会由 systemd 管理,所以没有必要画蛇添足。 |
| @libvirt | /var/lib/libvirt | 这主要是因为我并不使用虚拟机 |
| @docker | /var/lib/docker | docker 跟上方的需求一样 |
| @srv | /srv | 我也不在本地电脑上部署网页或者 ftp 服务器,所以没必要分区 |
| @usr-local | /usr/local | 我觉得即便是三方软件也应该「原子化」更新,如果三方软件没有随着系统回滚,可能会造成无法启动等问题。 |
| @containers | /var/lib/containers | pacman 的工作目录,与 docker 相同 |
以下为原始方案
创建子卷。这里的分区样式是一个基础的样式,你可能需要更细致地分区。当前分区是根据 Btrfs Layout 和 SDB:BTRFS 得来。 分区主要是为了后续使用 Timeshift 备份。可以理解为将不需要备份的目录提取出来,避免备份。
| 子卷 | 挂载点 | 说明 |
|---|---|---|
| @ | / | 根目录 |
| @home | /home | 家目录,用户不希望回滚的时候丢失重要文件 |
| @var-tmp | /var/tmp | 临时文件目录,临时文件也没有必要回滚 |
| @tmp | /tmp | 临时文件目录,没必要回滚 |
| @cache | /var/cache | 缓存文件目录,缓存文件也没有必要回滚 |
| @log | /var/log | 日志文件目录,日志文件不希望回归,方便我们寻找问题 |
| @libvirt | /var/lib/libvirt | 虚拟机,虚拟机的数据文件。一般来说我们也不想回滚这个 |
| @docker | /var/lib/docker | docker,我们并不想回滚 docker 中的数据 |
| @srv | /srv | 包括一些 web 或者 ftp 服务文件 |
| @root | /root | root 用户目录,与 home 目录相同 |
| @usr-local | /usr/local | 一些第三方软件的安装目录,回滚后可能会造成软件丢失 |
| @containers | /var/lib/containers | pacman 的工作目录,与 docker 相同 |
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@var-tmp
btrfs subvolume create /mnt/@tmp
btrfs subvolume create /mnt/@cache
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@libvirt
btrfs subvolume create /mnt/@docker
btrfs subvolume create /mnt/@srv
btrfs subvolume create /mnt/@root
btrfs subvolume create /mnt/@usr-local
btrfs subvolume create /mnt/@containersroot@archiso ~ # btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@var-tmp
btrfs subvolume create /mnt/@tmp
btrfs subvolume create /mnt/@cache
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@libvirt
btrfs subvolume create /mnt/@docker
btrfs subvolume create /mnt/@srv
btrfs subvolume create /mnt/@root
btrfs subvolume create /mnt/@usr-local
btrfs subvolume create /mnt/@containers
Create subvolume '/mnt/@'
Create subvolume '/mnt/@home'
Create subvolume '/mnt/@var-tmp'
Create subvolume '/mnt/@tmp'
Create subvolume '/mnt/@cache'
Create subvolume '/mnt/@log'
Create subvolume '/mnt/@libvirt'
Create subvolume '/mnt/@docker'
Create subvolume '/mnt/@srv'
Create subvolume '/mnt/@root'
Create subvolume '/mnt/@usr-local'
Create subvolume '/mnt/@containers'可以使用此命令检查子卷是否正确,你的 ID 可能跟我不一样,这没有问题。
root@archiso ~ # btrfs subvolume list /mnt
ID 256 gen 10 top level 5 path @
ID 257 gen 10 top level 5 path @home
ID 258 gen 10 top level 5 path @var-tmp
ID 259 gen 10 top level 5 path @tmp
ID 260 gen 10 top level 5 path @cache
ID 261 gen 10 top level 5 path @log
ID 262 gen 10 top level 5 path @libvirt
ID 263 gen 10 top level 5 path @docker
ID 264 gen 10 top level 5 path @root
ID 265 gen 10 top level 5 path @usr-local
ID 266 gen 10 top level 5 path @containers
ID 267 gen 11 top level 5 path @srv卸载根分区
umount /mnt重新挂载所有分区
刚刚是为了创建子卷才挂载的分区,现在需要正式挂载目录。需要注意的是命令中 -t btrfs 只是为了标记挂载格式,方便智能补全,subvol 的选项 @xxx 是子卷名称。
这里开启了 zstd 压缩,可以稍微节省一些空间,主要是为了提供更好的性能,zstd:1 中的 1 指的是强度,可以从 1 - 5 之间选择,默认情况下是 3,
根据 wiki 的描述,启用 1 可以更好的碎片整理,减少文件系统 IO,会有
mount -t btrfs -o subvol=@,compress=zstd:1 -m /dev/mapper/linuxroot /mnt
mount -t btrfs -o subvol=@home,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/home
mount -t btrfs -o subvol=@var-tmp,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/var/tmp
mount -t btrfs -o subvol=@tmp,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/tmp
mount -t btrfs -o subvol=@cache,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/var/cache
mount -t btrfs -o subvol=@log,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/var/log
mount -t btrfs -o subvol=@libvirt,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/var/lib/libvirt
mount -t btrfs -o subvol=@docker,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/var/lib/docker
mount -t btrfs -o subvol=@root,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/root
mount -t btrfs -o subvol=@usr-local,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/usr/local
mount -t btrfs -o subvol=@containers,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/var/lib/containers
mount -t btrfs -o subvol=@srv,compress=zstd:1 -m /dev/mapper/linuxroot /mnt/srv关闭写时复制(update: 2025-06-14)
根据读者来信的提示,事情似乎发生了一些变化。随着 Btrfs 的普及,有越来越多设计良好的软件会针对 Btrfs 进行适配, 手动关闭 CoW 的操作似乎有点画蛇添足。所以下方关闭 CoW 的操作可以选择不做。
需要注意的是,关闭 CoW 会同步关闭 Btrfs 的快照、数据校验和压缩功能。这主要是为了避免下方这些目录频繁写入,
像是 log、cache、tmp 和 var/tmp 本身就没有必要快照。而 docker、podman 和 libvirt 有自己的镜像格式,使用 CoW 可能造成性能问题。
chattr +C /mnt/var/log
chattr +C /mnt/var/cache
chattr +C /mnt/var/tmp
chattr +C /mnt/var/lib/docker
chattr +C /mnt/var/lib/libvirt
chattr +C /mnt/var/lib/containers
chattr +C /mnt/tmp目前你的分区状态应该是这样的
root@archiso ~ # lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 813.4M 1 loop /run/archiso/airootfs
sda 8:0 0 8G 0 disk
├─sda1 8:1 0 512M 0 part /mnt/efi
└─sda2 8:2 0 7.5G 0 part
└─linuxroot 254:0 0 7.5G 0 crypt /mnt/srv
/mnt/var/lib/containers
/mnt/usr/local
/mnt/root
/mnt/var/lib/docker
/mnt/var/lib/libvirt
/mnt/var/log
/mnt/var/cache
/mnt/tmp
/mnt/var/tmp
/mnt/home
/mnt
sr0 11:0 1 1.1G 0 rom /run/archiso/bootmnt安装基础包
安装前使用 reflector 命令调整镜像源, --country 位置填写你所在的国家,或者临近国家。
reflector --country China --age 24 --protocol http,https --sort rate --save /etc/pacman.d/mirrorlist这里安装的包主要包括运行必须的基础包,还有一些工具包。你可以根据你的需要自己自行添加或移除。
配置 pacman
安装前配置一下 pacman,提升下载速度等。将 /etc/pacman.conf 中的 Color 和 ParallelDownloads = 5 取消注释,这将开启颜色显示和并行下载。
# Misc options
#UseSyslog
#Color
Color
#NoProgressBar
#ParallelDownloads = 5
ParallelDownloads = 5
DownloadUser = alpm
#DisableSandbox基础包
| 包名 | 是否必须 | 介绍 |
|---|---|---|
| base | ✅ | 基础包 |
| base-devel | ✅ | 基础包 |
| linux | ✅ | linux 内核 |
| linux-firmware | ✅ | linux 固件 |
| btrfs-progs | ✅ | btrfs 支持 |
| util-linux | ✅ | linux 工具,不安装会很痛苦 |
| cryptsetup | ✅ | 加密解密工具,后续会用到 |
| dosfstools | ✅ | 文件工具,类似 mkfs.fat 工具 |
| sbctl | ✅ | 安全启动工具,后续会用到 |
| vim / nano / neovim … | ✅ | 文本编辑器,选择你喜欢的安装,但至少安装一个 |
| amd-ucode / inter-uncode | ✅ | cpu 微码,修复对应 cpu 漏洞的,根据你的 cpu 选择。虚拟机不用安装。 |
| networkmanager | ✅ | 网络管理器,如果你想安装桌面平台,无脑选择这个就行。 |
| sudo | ✅ | 提权,没有这个你可能会重装系统 |
| unzip | ❌ | 解压,根据你的需要自行安装 |
| git | ✅ | git 日常使用中大概率会用到 |
安装
pacstrap -K /mnt base base-devel linux linux-firmware amd-ucode vim nano cryptsetup btrfs-progs dosfstools util-linux git unzip sbctl networkmanager sudo生成 fstab 文件
这是为了保存我们辛辛苦苦挂载的目录,你也不想重启后就没了吧。
genfstab -U /mnt >> /mnt/etc/fstab检查一下是否有问题,跟我这个差不多就行。
root@archiso ~ # cat /mnt/etc/fstab
# Static information about the filesystems.
# See fstab(5) for details.
# <file system> <dir> <type> <options> <dump> <pass>
# /dev/mapper/linuxroot LABEL=linuxroot
UUID=d6e9359c-b5e0-471b-9b6d-4d2c9e8f6caa / btrfs rw,relatime,compress=zstd:1,space_cache=v2,subvol=/@ 0 0
# /dev/mapper/linuxroot LABEL=linuxroot
UUID=d6e9359c-b5e0-471b-9b6d-4d2c9e8f6caa /home btrfs rw,relatime,compress=zstd:1,space_cache=v2,subvol=/@home 0 0
# /dev/mapper/linuxroot LABEL=linuxroot
UUID=d6e9359c-b5e0-471b-9b6d-4d2c9e8f6caa /var/cache btrfs rw,relatime,compress=zstd:1,space_cache=v2,subvol=/@cache 0 0
# /dev/mapper/linuxroot LABEL=linuxroot
UUID=d6e9359c-b5e0-471b-9b6d-4d2c9e8f6caa /var/log btrfs rw,relatime,compress=zstd:1,space_cache=v2,subvol=/@log 0 0
# /dev/mapper/linuxroot LABEL=linuxroot
UUID=d6e9359c-b5e0-471b-9b6d-4d2c9e8f6caa /root btrfs rw,relatime,compress=zstd:1,space_cache=v2,subvol=/@root 0 0
# /dev/sda1 LABEL=EFI
UUID=AB14-F139 /efi vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2本地化
选择本地化语言,这里选择 en_US.UTF-8,最好不要在系统级设置成中文或其他语言。可以在桌面环境设置成中文。
sed -i -e "/^#"en_US.UTF-8"/s/^#//" /mnt/etc/locale.gen除了上面命令直接设置,
你还可以选择使用 vim 或者 nano 去 /mnt/etc/locale.gen 中找到 en_US.UTF-8 UTF-8 取消注释。
使用快捷的命令处理剩余本地化步骤12。
| 需要配置的 | 建议 |
|---|---|
us |
|
如果你在中国大陆,请输入 Asia/Shanghai |
|
| 输入你喜欢的,这里选择 arch-tmp |
systemd-firstboot --root /mnt --promptroot@archiso ~ # systemd-firstboot --root /mnt --prompt
Welcome to your new installation of Arch Linux!
Please configure your system!
-- Press any key to proceed --
‣ Please enter system keymap name or number (empty to skip, "list" to list options): us
/mnt/etc/vconsole.conf written.
‣ Please enter timezone name or number (empty to skip, "list" to list options): Asia/Shanghai
/mnt: /etc/localtime written
‣ Please enter hostname for new system (empty to skip): arch-tmp
/mnt: /etc/hostname written.生成配置
arch-chroot /mnt locale-genroot@archiso ~ # arch-chroot /mnt locale-gen
Generating locales...
en_US.UTF-8... done
Generation complete.你还需要创建一个 /mnt/etc/locale.conf 文件,其中需要添加上语言选项。
LANG=en_US.UTF-8添加账户
添加账户,其中 wheel 是用户组,这里用户名是 admin 你可以选择使用别的名字。
arch-chroot /mnt useradd -G wheel -m admin为账户设置密码,别忘了。
arch-chroot /mnt passwd adminroot@archiso ~ # arch-chroot /mnt useradd -G wheel -m admin
root@archiso ~ # arch-chroot /mnt passwd admin
New password:
Retype new password:
passwd: password updated successfully避免使用 root 用户作为主要用户,可以避免很多问题。
设置管理员,这将为 admin 用户提供管理员权限,可以使用 sudo 提权这里不直接更改 sudoers,使用 sudoers.d 目录来配置。这可以避免错误配置,一人一配置也更好管理。。
echo "admin ALL=(ALL:ALL) ALL" >> /mnt/etc/sudoers.d/admin调整 cmdline
这是为了让 systemd-boot 可以正确的引导加密根文件。配置错误可能导致无法正确进入系统13。
获取 sdd uuid
需要关注的是 /dev/sda2: UUID="3a29447e-599f-42fb-b3d2-6b44e871e8d6" 这是我们的 luks 目录。
root@archiso ~ # blkid
/dev/sr0: BLOCK_SIZE="2048" UUID="2024-12-01-05-48-32-00" LABEL="ARCH_202412" TYPE="iso9660" PTUUID="382d5c21" PTTYPE="dos"
/dev/loop0: BLOCK_SIZE="1048576" TYPE="squashfs"
/dev/mapper/linuxroot: LABEL="linuxroot" UUID="d6e9359c-b5e0-471b-9b6d-4d2c9e8f6caa" UUID_SUB="9bfaca49-5d98-419d-b8aa-b5b93203ff29" BLOCK_SIZE="4096" TYPE="btrfs"
/dev/sda2: UUID="3a29447e-599f-42fb-b3d2-6b44e871e8d6" TYPE="crypto_LUKS" PARTLABEL="luks" PARTUUID="35d5b22d-336f-4ea0-9f2b-ecc19c6fd9f1"
/dev/sda1: LABEL_FATBOOT="EFI" LABEL="EFI" UUID="AB14-F139" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="esp" PARTUUID="3ed9525c-0a0a-48c2-b713-4116badc36e4"设置 cmdline 文件
文件位置 /mnt/etc/kernel/cmdline。loglevel = 3 指的是日志级别。如果你不喜欢看日志,也可以设置成 quiet,这将不显示日志,不过不用担心,日志还是记录的,只不过不再开机页面显示了。
loglevel=3设置 cmdline/root.conf
这个文件是用于引导系统找到根目录的,因为我们使用了 luks 加密,不设置这个会导致系统无法发现目录,最终启动失败。
文件位置/mnt/etc/cmdline.d/root.conf,记得提前创建 cmdline.d 目录,使用 mkdir /mnt/etc/cmdline.d
rd.luks.name=3a29447e-599f-42fb-b3d2-6b44e871e8d6=linuxroot root=/dev/mapper/linuxroot rootfstype=btrfs rootflags=subvol=/@ rw其中 rd.luks.name=<uuid>=<linuxroot> 中的 uuid 是加密的根目录,在这里是 /dev/sda2,linuxroot 是映射的标签,这里选择 linuxroot。
root=/dev/mapper/linuxroot 这里的 linuxroot 就是前面映射的标签。
rootfstype=btrfs 这是告诉引导,文件系统是 btrfs
rootflags=subvol=/@ 这是告诉引导,挂载根目录
rw 告诉引导文件系统可读写
调整 mkinitcpio.conf
这里主要是为了更改 HOOKS,要注意顺序,错误的钩子顺序会导致无法正常启动系统。请确保在使用本方案的情况下 HOOKS 跟我相同。
| 钩子名 | 用途 |
|---|---|
| base | 基础系统 |
| systemd | systemd 启动,只有使用 sytemd-boot 才可以使用 |
| autodetect | 检测硬件模块 |
| microcode | 微码,修复漏洞 |
| modconf | 配置文件 |
| kms | 图形显示 |
| keyboard | 键盘 |
| sd-vconsole | 基于 systemd 的虚拟键盘 |
| sd-encrypt | 基于 systemd 的加解密 |
| block | 设备块 |
| filesystems | 文件系统 |
| fsck | 文件系统检查 |
文件位置 /mnt/etc/mkinitcpio.conf
MODULES=()
BINARIES=()
FILES=()
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole sd-encrypt block filesystems fsck)MODULES=()
BINARIES=()
FILES=()
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems fsck)
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole sd-encrypt block filesystems fsck)配置统一内核映像(UKI)
编辑 /mnt/etc/mkinitcpio.d/linux.preset 文件
# mkinitcpio preset file for the 'linux' package
-#ALL_config="/etc/mkinitcpio.conf"
+ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
PRESETS=('default' 'fallback')
#default_config="/etc/mkinitcpio.conf"
-default_image="/boot/initramfs-linux.img"
+#default_image="/boot/initramfs-linux.img"
-#default_uki="/efi/EFI/Linux/arch-linux.efi"
-#default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"
+default_uki="/efi/EFI/Linux/arch-linux.efi"
+default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"
-fallback_config="/etc/mkinitcpio.conf"
-fallback_image="/boot/initramfs-linux-fallback.img"
+#fallback_config="/etc/mkinitcpio.conf"
+#fallback_image="/boot/initramfs-linux-fallback.img"
-#fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi"
-#fallback_options="-S autodetect"
+fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi"
+fallback_options="-S autodetect"确保最终效果和下方一样
# mkinitcpio preset file for the 'linux' package
ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
PRESETS=('default' 'fallback')
#default_config="/etc/mkinitcpio.conf"
#default_image="/boot/initramfs-linux.img"
default_uki="/efi/EFI/Linux/arch-linux.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"
#fallback_config="/etc/mkinitcpio.conf"
#fallback_image="/boot/initramfs-linux-fallback.img"
fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi"
fallback_options="-S autodetect"生成 UKI
创建 UKI 存放目录
mkdir -p /mnt/efi/EFI/Linux生成
arch-chroot /mnt mkinitcpio -P一定要确认安装过程中是否包含了 cmdline.d/root.conf 和 cmdline 配置。血泪教训,如果没有正确包含,系统是无法正常开机的,会引导错误。
root@archiso ~ # arch-chroot /mnt mkinitcpio -P
==> Building image from preset: /etc/mkinitcpio.d/linux.preset: 'default'
==> Using configuration file: '/etc/mkinitcpio.conf'
-> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -U /efi/EFI/Linux/arch-linux.efi --splash /usr/share/systemd/bootctl/splash-arch.bmp
==> Starting build: '6.12.1-arch1-1'
-> Running build hook: [base]
-> Running build hook: [systemd]
-> Running build hook: [autodetect]
-> Running build hook: [microcode]
-> Running build hook: [modconf]
-> Running build hook: [kms]
-> Running build hook: [keyboard]
-> Running build hook: [sd-vconsole]
-> Running build hook: [sd-encrypt]
==> WARNING: Possibly missing firmware for module: 'qat_420xx'
-> Running build hook: [block]
-> Running build hook: [filesystems]
-> Running build hook: [fsck]
==> Generating module dependencies
==> Creating zstd-compressed initcpio image
-> Early uncompressed CPIO image generation successful
==> Initcpio image generation successful
==> Creating unified kernel image: '/efi/EFI/Linux/arch-linux.efi'
-> Using cmdline file: '/etc/kernel/cmdline'
-> Using cmdline file: '/etc/cmdline.d/root.conf'
==> Unified kernel image generation successful
==> Running post hooks
-> Running post hook: [sbctl]
Secureboot key directory doesn't exist, not signing!
==> Post processing done
==> Building image from preset: /etc/mkinitcpio.d/linux.preset: 'fallback'
==> Using configuration file: '/etc/mkinitcpio.conf'
-> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -U /efi/EFI/Linux/arch-linux-fallback.efi -S autodetect
==> Starting build: '6.12.1-arch1-1'
-> Running build hook: [base]
-> Running build hook: [systemd]
-> Running build hook: [microcode]
-> Running build hook: [modconf]
-> Running build hook: [kms]
==> WARNING: Possibly missing firmware for module: 'ast'
-> Running build hook: [keyboard]
==> WARNING: Possibly missing firmware for module: 'xhci_pci_renesas'
-> Running build hook: [sd-vconsole]
-> Running build hook: [sd-encrypt]
==> WARNING: Possibly missing firmware for module: 'qat_420xx'
-> Running build hook: [block]
==> WARNING: Possibly missing firmware for module: 'aic94xx'
==> WARNING: Possibly missing firmware for module: 'bfa'
==> WARNING: Possibly missing firmware for module: 'qed'
==> WARNING: Possibly missing firmware for module: 'qla1280'
==> WARNING: Possibly missing firmware for module: 'qla2xxx'
==> WARNING: Possibly missing firmware for module: 'wd719x'
-> Running build hook: [filesystems]
-> Running build hook: [fsck]
==> Generating module dependencies
==> Creating zstd-compressed initcpio image
-> Early uncompressed CPIO image generation successful
==> Initcpio image generation successful
==> Creating unified kernel image: '/efi/EFI/Linux/arch-linux-fallback.efi'
-> Using cmdline file: '/etc/kernel/cmdline'
-> Using cmdline file: '/etc/cmdline.d/root.conf'
==> Unified kernel image generation successful
==> Running post hooks
-> Running post hook: [sbctl]
Secureboot key directory doesn't exist, not signing!
==> Post processing done
arch-chroot /mnt mkinitcpio -P 25.02s user 26.74s system 110% cpu 46.944 total检查,可以注意到存在 arch-linux.efi 和 arch-linux-fallback.efi
root@archiso ~ # ls -lR /mnt/efi
/mnt/efi:
total 4
drwxr-xr-x 3 root root 4096 Dec 7 04:51 EFI
/mnt/efi/EFI:
total 4
drwxr-xr-x 2 root root 4096 Dec 7 04:52 Linux
/mnt/efi/EFI/Linux:
total 170064
-rwxr-xr-x 1 root root 30520832 Nov 29 21:43 arch-linux.efi
-rwxr-xr-x 1 root root 143618560 Nov 29 21:43 arch-linux-fallback.efi启动必要服务
必要服务
| 服务 | 介绍 |
|---|---|
| systemd-resolved | 域名解析 |
| systemd-timesyncd | 时间同步 |
| NetworkManager | 网络管理 |
如果不启用这些服务可能造成无法联网不过在重启后应该也能再开启。
systemctl --root /mnt enable systemd-resolved systemd-timesyncd NetworkManagerroot@archiso ~ # systemctl --root /mnt enable systemd-resolved systemd-timesyncd NetworkManager
Created symlink '/mnt/etc/systemd/system/dbus-org.freedesktop.resolve1.service'
→ '/usr/lib/systemd/system/systemd-resolved.service'.
Created symlink '/mnt/etc/systemd/system/sysinit.target.wants/systemd-resolved.service'
→ '/usr/lib/systemd/system/systemd-resolved.service'.
Created symlink '/mnt/etc/systemd/system/dbus-org.freedesktop.timesync1.service'
→ '/usr/lib/systemd/system/systemd-timesyncd.service'.
Created symlink '/mnt/etc/systemd/system/sysinit.target.wants/systemd-timesyncd.service'
→ '/usr/lib/systemd/system/systemd-timesyncd.service'.
Created symlink '/mnt/etc/systemd/system/multi-user.target.wants/NetworkManager.service'
→ '/usr/lib/systemd/system/NetworkManager.service'.
Created symlink '/mnt/etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service'
→ '/usr/lib/systemd/system/NetworkManager-dispatcher.service'.
Created symlink '/mnt/etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service'
→ '/usr/lib/systemd/system/NetworkManager-wait-online.service'.屏蔽 systemd-networkd
我们不使用这个服务,而他会和 NetworkManager 冲突,所以屏蔽掉。
systemctl --root /mnt mask systemd-networkdroot@archiso ~ # systemctl --root /mnt mask systemd-networkd
Created symlink '/mnt/etc/systemd/system/systemd-networkd.service' → '/dev/null'.写入 systemd-boot 引导
将 UKI 写入引导,这样机器才能知道如何启动。
arch-chroot /mnt bootctl install --esp-path=/efiroot@archiso ~ # arch-chroot /mnt bootctl install --esp-path=/efi检查,可以看到多出了 BOOTX64.EFI、systemd-bootx64.efi、entries.srel、loader.conf 和 random-seed 这表示正常。
root@archiso ~ # ls -lR /mnt/efi
/mnt/efi:
total 8
drwxr-xr-x 5 root root 4096 Dec 7 05:00 EFI
drwxr-xr-x 3 root root 4096 Dec 7 05:00 loader
/mnt/efi/EFI:
total 12
drwxr-xr-x 2 root root 4096 Dec 7 05:00 BOOT
drwxr-xr-x 2 root root 4096 Dec 7 04:52 Linux
drwxr-xr-x 2 root root 4096 Dec 7 05:00 systemd
/mnt/efi/EFI/BOOT:
total 104
-rwxr-xr-x 1 root root 105472 Nov 29 21:43 BOOTX64.EFI
/mnt/efi/EFI/Linux:
total 170064
-rwxr-xr-x 1 root root 30520832 Nov 29 21:43 arch-linux.efi
-rwxr-xr-x 1 root root 143618560 Nov 29 21:43 arch-linux-fallback.efi
/mnt/efi/EFI/systemd:
total 104
-rwxr-xr-x 1 root root 105472 Nov 29 21:43 systemd-bootx64.efi
/mnt/efi/loader:
total 16
drwxr-xr-x 2 root root 4096 Dec 7 05:00 entries
-rwxr-xr-x 1 root root 6 Dec 7 05:00 entries.srel
-rwxr-xr-x 1 root root 30 Dec 7 05:00 loader.conf
-rwxr-xr-x 1 root root 32 Dec 7 05:00 random-seed
/mnt/efi/loader/重启
sync
systemctl reboot重启后你就可以看到输入硬盘密钥的提示了,我们现在没有密码,直接回车就行。然后就会进入系统,不过现在我们没有提供桌面平台,后续会提供。
安全启动
登录后,我们来配置安全启动2。
检查状态
sudo sbctl status可以看到我们现在没有启动安全启动,设置模式已经处于启动状态。
admin@arch-tmp ~> sudo sbctl status
Installed: ✗ sbctl is not installed
Setup Mode: ✗ Enabled
Secure Boot: ✗ Disabled
Vendor Keys: none创建密钥
sudo sbctl create-keys这将创建平台密钥,可以看到平台密钥 UUID
admin@arch-tmp ~> sudo sbctl create-keys
Created Owner UUID c5053c9a-3643-436a-ae0c-1bacc689cc6a
Creating secure boot keys...✓
Secure boot keys created!注册微软密钥
这很重要,现在很多的硬件都直接使用微软平台密钥签名,不注册的话很可能会变砖。如果你是用虚拟机安装的话可能会出现错误。不过也不用管。
sudo sbctl enroll-keys -m检查状态
sudo sbctl status可以看到 Vendor Keys 存在 microsoft,这很重要。
admin@arch-tmp ~> sudo sbctl status
Installed: ✓ sbctl is installed
Owner GUID: c5053c9a-3643-436a-ae0c-1bacc689cc6a
Setup Mode: ✗ Enabled
Secure Boot: ✗ Disabled
Vendor Keys: microsoft验证签名
sudo sbctl verify可以看到 uki 和引导文件没有被签名,我们直接签名就可以。
admin@arch-tmp ~> sudo sbctl verify
Verifying file database and EFI images in /efi...
✗ /efi/EFI/BOOT/BOOTX64.EFI is not signed
✗ /efi/EFI/Linux/arch-linux-fallback.efi is not signed
✗ /efi/EFI/Linux/arch-linux.efi is not signed
✗ /efi/EFI/systemd/systemd-bootx64.efi is not signed签名
sudo sbctl sign -s /efi/EFI/BOOT/BOOTX64.EFI
sudo sbctl sign -s /efi/EFI/Linux/arch-linux.efi
sudo sbctl sign -s /efi/EFI/Linux/arch-linux-fallback.efi
sudo sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efiadmin@arch-tmp ~> sudo sbctl sign -s /efi/EFI/BOOT/BOOTX64.EFI
✓ Signed /efi/EFI/BOOT/BOOTX64.EFI
admin@arch-tmp ~> sudo sbctl sign -s /efi/EFI/Linux/arch-linux.efi
✓ Signed /efi/EFI/Linux/arch-linux.efi
admin@arch-tmp ~> sudo sbctl sign -s /efi/EFI/Linux/arch-linux-fallback.efi
✓ Signed /efi/EFI/Linux/arch-linux-fallback.efi
admin@arch-tmp ~> sudo sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi
✓ Signed /efi/EFI/systemd/systemd-bootx64.efi配置 TPM 自动解锁
进行下一步操作前,请重启一下系统,这样才可以正确的配置 TPM 自动解锁。
恢复密钥
我们先注册一个恢复密钥,这很重要。输入密码后当前没有密码就可以获取一个恢复密钥,保存好它。
sudo systemd-cryptenroll --recovery-key /dev/sda2admin@arch-tmp ~> sudo systemd-cryptenroll --recovery-key /dev/sda2
🔐 Please enter current passphrase for disk /dev/sda2:
A secret recovery key has been generated for this volume:
🔐 bgjdrdgt-cilfdtur-lhgcruln-idbglifj-bfuffejf-kherljfl-trdnrlju-gnfutnun
Please save this secret recovery key at a secure location. It may be used to
regain access to the volume if the other configured access credentials have
been lost or forgotten. The recovery key may be entered in place of a password
whenever authentication is requested.
New recovery key enrolled as key slot 1.注册 TMP2 自动解锁
需要注意的是 --tpm2-device 可以自动选择 auto,它会自动选择 tpm 设备,如果你存在多个设备,你需要手动配置。输入密码,就可以注册到槽中。
需要注意的是,你可以配置 --tpm2-pcrs=0+7+11,不配置情况下只会默认为 7。
sudo systemd-cryptenroll --tpm2-device=auto /dev/sda2admin@arch-tmp ~> sudo systemd-cryptenroll --tpm2-device=auto /dev/sda2
🔐 Please enter current passphrase for disk /dev/sda2:
New TPM2 token enrolled as key slot 2.检查 TPM2 槽
sudo systemd-cryptenroll /dev/sda2你可以注意到槽 0,这个槽我们现在默认为空,我们需要移除它。默认情况下 tpm 会自动处理密钥解锁。一旦解锁失败可以使用恢复密钥进入系统。
admin@arch-tmp ~> sudo systemd-cryptenroll /dev/sda2
SLOT TYPE
0 password
1 recovery
2 tpm2移除空密码
sudo systemd-cryptenroll /dev/sda2 --wipe-slot emptyadmin@arch-tmp ~> sudo systemd-cryptenroll /dev/sda2 --wipe-slot empty
Wiped slot 0.再次检查
admin@arch-tmp ~> sudo systemd-cryptenroll /dev/sda2
SLOT TYPE
1 recovery
2 tpm2