前言

在我曾经的文章中,我提到我的 Archlinux 系统已经连续使用两年了,期间一直没有出现过什么大问题。然我事实上我对这个系统安装一直有些不满意:

首先是不满意磁盘分区,我当时只给根目录分了 30G 空间,并且 /var 目录没有单独挂载分区,导致根目录的使用空间一直都挺捉襟见肘的,/home 目录也只分了 100G 空间,后期也不太够用。那可能会有人问,500G 的硬盘剩下的三百多 G 那里去了?其实剩下的空间又被我单独挂载在了 /home/$USER/data 目录下,用来放一些不常用的大文件。现在想一想这个分区方式是真的不太好。

其次是磁盘分区使用的文件系统是「good old」的 ext4 文件系统,虽然 ext4 使用起来很可靠稳定,但在特性上多少有些无聊,我想尝试一下新的文件系统 Btrfs,支持写时复制(CoW)、快照以及压缩等高级特性。

秉承着「没有坏就不要动它」的原则,虽然对系统安装有些不满意,但又不是不能用,也就这么用下来了。然而就在前些日子某次系统更新后,我突然发现鼠标不能用了,直到最后我发现其实是 keyd 的一个 bug,不知是否是奥米克戎后遗症导致我注意力变差,还是因为前一天晚上睡眠不足,我排查了好一会也没有找到故障原因,最后脑袋一热,决定重装系统。


由于 Arch linux 官方有着十分详尽的 wiki,同时 ArchlinuxCN 社区也维护了一版中文 wiki,国内外互联网上也有很多安装与配置教程,只要善用搜索引擎,安装 Archlinux 不是什么难事,所以本文为了篇幅考虑,不会将所有安装步骤列出来,只记录下我个人安装过程中遇到的需要注意的一些特殊配置,权当是个备忘录吧。

重装前的备份

因为我打算使用 btrfs 文件系统,虽然将 ext4 文件系统转换为 btrfs 文件系统是可行的,但是毕竟存在风险,保险起见还是备份数据,然后全盘格式化。

首先运行 pacman -Qe,这个命令可以列出系统中所有手动指定安装的包,运行 pacman -Qe >> list.txt 可以将这个软件包名单保存到 list.txt 文件里面,再将这个文件保存到方便查看的地方,比如自己的手机里什么的,方便重装后参照这个名单将软件装回来。

之后是备份整个家目录,以便重装完后恢复绝大多数的个人数据。我找到一个闲置的空的移动硬盘,不是空的也没关系,只要剩余空间够放下家目录的内容就行,将其挂载在 /mnt 目录下,并新建一个空文件夹 backup。为了在恢复数据时保留所有文件的权限,我使用 rsync 命令:

sudo rsync -avrh --progress /home/ /mnt/backup/

这个命令会将所有家目录中的文件同步至 /mnt/backup/ 路径下。选项 -avrh 可以在复制时保留文件的权限,/home/ 是需要备份的目录,/mnt/backup/ 是备份的目标目录,一定要注意路径最后的斜杠,路径最后是否有斜杠对于 rsync 命令来说是完全不同的两个路径,这里在路径最后加上了斜杠,之后再用 rsync 恢复数据时也需要在路径后面加上斜杠。备份数据可能需要较长时间,取决于硬盘的速度,备份完成后,再次检查一下数据备份是否出错,之后便可以着手重装系统了。

若你在根分区也有想要备份的文件,也可以选择备份。

系统安装

Archlinux 官方的系统镜像如今已经默认集成了一个十分好用的安装脚本,配置好网络后只需运行 archinstall 便可快速安装,不过需要注意的是,运行 archinstall 时会首先刷新镜像列表,如果网络不太好的话可能会花很长时间,所以在这之前可以手动编辑 /etc/pacman.d/mirrorlist 将国内镜像列表移动到最顶部,通过 head 命令查看文件的前 20 行:

$ head -n 20 /etc/pacman.d/mirrorlist
##
## Arch Linux repository mirrorlist
## Generated on 2023-02-26
##
## China
Server = https://mirrors.bfsu.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.aliyun.com/archlinux/$repo/os/$arch
Server = https://mirrors.cqu.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.hit.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.neusoft.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.nju.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.njupt.edu.cn/archlinux/$repo/os/$arch
Server = https://mirror.redrock.team/archlinux/$repo/os/$arch
Server = https://mirrors.shanghaitech.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.sjtug.sjtu.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.wsyu.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.xjtu.edu.cn/archlinux/$repo/os/$arch

或者直接在文件最开头手动添加国内镜像源,以北外镜像站为例,在文件最开头添加这样一行:

Server = https://mirrors.bfsu.edu.cn/archlinux/$repo/os/$arch

这样就可以跳过刷新镜像列表这一步,可以节省不少时间。

官方的安装脚本其实已经挺好用了,如果没什么特殊需求的话完全可以使用这个脚本非常快地安装一个新系统,但是我恰恰是有特殊需求的那种人。我打算配置系统休眠(Hibernation),需要一个 swap 空间,而官方安装脚本默认使用 zram 作为 swap,因为 zram 是将一部分内存空间压缩当作 swap 空间,而内存断电丢失数据的特性决定了它不可以用于系统休眠,想要配置硬盘上的 swap 需要手动分区,而安装脚本的手动分区功能我研究了半天也没搞明白怎么用,所以我最终决定抛弃安装脚本,手动安装。

手动安装系统的话基本上参照官方的安装教程就差不多了,以下是我个人的一些配置。

硬盘分区

我的硬盘分区挂载状态如下,运行 lsblk

$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda      8:0    0 465.8G  0 disk
├─sda1   8:1    0   512M  0 part /boot
├─sda2   8:2    0    16G  0 part [SWAP]
└─sda3   8:3    0 449.3G  0 part /home
                                 /var/log
                                 /var/cache/pacman/pkg
                                 /

你会发现除了常规的 boot 分区 sda1 和 swap 分区 sda2 外,sda3 竟然被挂载到了四个目录下,这对于 btrfs 分区是可行的,btrfs 分区可以创建很多子卷(subvolume),每个子卷又可以像单独的分区一样被挂载,而且每个子卷又像文件夹一样可以共享这个分区所有的容量,挂载子卷而不是挂载分区,就不会出现一个分区用完了,而另一个分区还没用多少的尴尬情况。如果你真的想要限制子卷可使用的空间,也可以使用 Quota,不过这个功能目前并不稳定,请谨慎使用。btrfs 分区也可以像传统分区那样直接挂载整个分区,但这样情况下就不可以用快照功能了,所以并不推荐。

我使用的是 gdisk 来进行硬盘分区,你也可以使用其他的分区工具。对于支持 UEFI 的机器,/boot/boot/EFI 目录必须挂载到单独的 FAT32 分区,一般 boot 分区只需要几百兆大小。swap 可以为单独的分区或者是交换文件,一般而言使用交换文件配置要更为灵活,但是在 btrfs 分区上使用交换文件需要一些额外设置,而且休眠到交换文件也需要额外设置,所以为了方便起见,我直接划分了一个交换分区,至于交换空间的大小,若是想要休眠到硬盘,一般而言需要交换空间不小于机器物理内存的容量,对于小内存的机器,最好是两倍物理内存的容量,若是机器内存比较大,交换空间小于物理内存容量也是可行的,只是需要一些额外设置,我的电脑只有 8G 内存,保险起见我直接分了 16G 交换分区。剩余的空间我全给了主分区,将来格式化成 btrfs 文件系统。

接下来是格式化分区,分区设备名称不同的机器可能会不同,请自行修改:

mkfs.fat -F 32 /dev/sda1    # 格式化 boot 分区
mkswap /dev/sda2    # 格式化 swap 分区
mkfs.btrfs /dev/sda3    # 格式化主分区

然后是挂载分区,btrfs 分区的挂载比较复杂,首先挂载整个 btrfs 分区到 /mnt,这样才可以创建子卷:

mount /dev/sda3 /mnt    # 挂载分区
# 创建子卷
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@pkg
umount /dev/sda3    # 卸载分区

关于子卷的划分,我打算使用 Timeshift 来管理快照,而 Timeshift 只支持 Ubuntu 类型的子卷布局,也就是根目录挂载在 @ 子卷上,/home 目录挂载在 @home 子卷上;另外我还打算使用 grub-btrfs 来为快照自动创建 grub 目录,grub-btrfs 要求 /var/log 挂载在单独的子卷上;还有 @pkg 子卷挂载在 /var/cache/pacman/pkg 目录下,这个目录下保存的是下载的软件包缓存,也没什么保存快照的必要,所以也单独划分了个子卷。

接下来就是挂载子卷了,使用 subvol 挂载选项来指定挂载的子卷:

# 挂载根目录
mount /dev/sda3 /mnt -o subvol=@,noatime,discard=async,compress=zstd
# 挂载家目录
mkdir /mnt/home
mount /dev/sda3 /mnt/home -o subvol=@home,noatime,discard=async,compress=zstd
# 挂载 /var/log 目录
mkdir -p /mnt/var/log
mount /dev/sda3 /mnt/var/log -o subvol=@log,noatime,discard=async,compress=zstd
# 挂载 /var/cache/pacman/pkg 目录
mkdir -p /mnt/var/cache/pacman/pkg
mount /dev/sda3 /mnt/var/cache/pacman/pkg -o subvol=@pkg,noatime,discard=async,compress=zstd

除了 subvol 选项用来指定挂载的子卷,我还添加了其他的挂载选项用于优化 btrfs 文件系统的性能:noatime 选项可以降低数据读取和写入的访问时间;discard=async 选项可以在闲时释放磁盘中未使用的区块,也就是 TRIM,另外也可以不添加这个选项,而是在系统安装完成后启用 fstrim.timer 服务从而定时执行 TRIM,可以根据自己的喜好选择;compress 选项可以在数据写入前进行压缩,减少磁盘的写入量,增加磁盘寿命,在某些场景下还能优化一些性能,支持的压缩算法有 zliblzozstdzstd 算法是最快的。关于更多的挂载选项,可以看这里。在系统安装完成后也可以编辑 /etc/fstab 文件修改挂载选项。

因为 /var/log/var/cache/pacman/pkg 在将来并不会被保存快照,也可以选择为这两个目录禁用写时复制:

chattr +C /mnt/var/log
chattr +C /mnt/var/cache/pacman/pkg

接下来挂载其他分区:

# 挂载 boot 分区
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot
# 启用 swap 分区
swapon /dev/sda2

接下来便可以继续接下来的安装步骤了。

安装过程

管理 btrfs 文件系统,比较推荐安装 btrfs-progs,其包含了很多用于管理 btrfs 文件系统的命令,前文用到的 btrfs subvolume create 命令就是来自这个软件包,Arch 官方的的安装镜像已经集成了这个软件包。可以在 pacstrap 步骤中安装这个包,我一般会在这个步骤装上如下的软件包:

pacstrap -K /mnt base base-devel linux-lts linux-lts-headers linux-firmware neovim btrfs-progs amd-ucode

base 和 base-devel 是系统核心的软件包组,linux-lts 和 linux-lts-headers 是长期支持版本的内核及其头文件,若是不追求较新的内核特性及驱动支持,长期支持版本内核更为稳定,linux-firmware 是各种常用的驱动,neovim 是一个文本编辑器,amd-ucode 是用于 AMD 处理器的微码文件,若是 Intel 处理器,可以安装 intel-ucode。

chroot 进入新系统后,除了官方推荐的配置,对于 btrfs 文件系统,需要编辑 mkinitcpio 文件,通常位于 /etc/mkinitcpio.conf,找到 MODULES=() 一行,在括号中添加 btrfs,这是为了在系统启动时提前加载 btrfs 内核模块,从而正常启动系统。记得每次编辑完 mkinitcpio 文件后都需要手动重新生成 initramfs:

mkinitcpio -P

配置完成后,再进行安装 GRUB

pacman -S grub
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=Arch
grub-mkconfig -o /boot/grub/grub.cfg

添加新用户:

useradd -m -G wheel -s /bin/bash user

这个命令添加了一个用户组为 wheel,shell 为 bash,用户名为 user 的新用户,如果之后打算恢复以前的家目录,建议使用和之前系统一样的用户名。

之后运行 visudo,如果环境变量没有指定默认编辑器,会提示选择,选择一个之后会进入文件编辑界面,找到 # %wheel ALL=(ALL:ALL) 一行,删除最前面的井号注释,这样所有在 wheel 用户组的用户都可以使用 sudo 命令了,或者要是不想每次运行 sudo 都要输入密码,可以取消注释 %wheel ALL=(ALL:ALL) NOPASSWD: ALL 这一行,但这样可能会降低系统的安全性。

另外记得安装网络配置相关的软件包,比如 networkmanager,以免重启后没有网。

推荐阅读一下常用设置,如果没有其他要配置的,就可以重启进新系统了。

安装后的配置

重启进入新系统后,因为还未安装图形界面,会进入 tty,因为之后要恢复家目录文件,所以这里暂时先不用普通用户登录,而是登录进 root 用户,开始着手恢复家目录文件,将之前用于备份家目录的移动硬盘重新挂载到 /mnt 目录,一样使用 rsync 恢复文件,只需将之前备份命令里两个路径互换位置即可:

rsync -avrh --progress /mnt/backup/ /home/

恢复过程同样需要较长时间,请耐心等待,恢复完成后退出 root 登录,使用普通用户登录。参照之前备份的软件包列表将所需的软件包装回来,再启用一些需要的服务,就可以正常使用了,就和重装前一样。

快照

btrfs 文件系统最吸引人的特性之一就是快照,通过快照可以方便地回滚系统,虽然我们也可以在命令行手动创建快照,但多少有些麻烦,为了更好地创建和管理快照,可以借助一些其他工具,我使用的是 LinuxMint 团队开发的 Timeshift,注意 Timeshift 只支持 Ubuntu 类型的子卷布局,这在之前的分区过程中已经搞定了。只需从 AUR 安装,之后打开按照向导一路设置就好了,记得要启用 cronie 服务,sudo systemctl enable cronie.service --now,以保证 Timeshift 能够定时创建快照。此外也可以安装 timeshift-autosnap,这个包添加了一个 pacman hook,可以在每次系统升级前自动创建快照。

接下来安装 grub-btrfs,这个软件可以在每次重新生成 grub 配置文件时添加快照的入口,可以在不恢复快照的情况下直接启动进入快照,方便故障排查。若是觉得每次创建快照后都要手动运行 grub-mkconfig 过于麻烦,这个包还提供了一个 systemd 服务 grub-btrfsd.service,需先安装 grub-btrfs 的可选依赖 inotify-tools,然后启用这个服务 sudo systemctl enable grub-btrfsd.service --now 就可以在每次创建快照后自动生成 grub 配置文件了,不过这个服务默认监视的快照路径在 /.snapshots,而 Timeshift 创建的快照是一个动态变化的路径,想要让它监视 Timeshift 的快照路径需要编辑 service 文件。一般情况下不推荐直接编辑位于 /usr/lib/systemd/system/ 下的 service 文件,因为软件包升级会将编辑后的文件覆盖掉,还好 systemd 提供了解决方案,运行 sudo systemctl edit --full grub-btrfsd ,这个命令会将 /usr/lib/systemd/system/grub-btrfsd.service 文件复制到 /etc/systemd/system/grub-btrfsd.service,再用系统默认的文件编辑器打开,这样编辑后的文件就不会被覆盖掉了,找到下面这一行:

ExecStart=/usr/bin/grub-btrfsd --syslog /.snapshots

修改为:

ExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto

这样 grub-btrfs 就会监视 Timeshift 创建的快照了。

Timeshift 创建的快照默认是可读写的,但若用其他的快照管理程序,创建的快照可能是只读的,这种情况下,直接启动进入快照可能会发生错误,这种情况 grub-btrfs 也提供了解决方案,grub-btrfs 提供了一个 grub-btrfs-overlayfs 钩子,编辑 /etc/mkinitcpio.conf,找到 HOOKS 一行,在括号最后添加 grub-btrfs-overlayfs,比如这样:

HOOKS=(base udev autodetect modconf block filesystems keyboard fsck grub-btrfs-overlayfs)

然后重新生成 initramfs,sudo mkinitcpio -P。在这之后创建的只读快照,将会以 overlayfs 的形式启动进入,所有的改动将会存储在内存里,重启后都会消失,逻辑和大多数系统的 live-cd 安装镜像差不多。

休眠到硬盘

休眠到硬盘(又称 S4 睡眠),是将当前系统的状态存入硬盘的交换空间,然后完全断开电源,相比于常规的挂起到内存(又称 S3 睡眠),休眠时几乎不消耗电量,但是恢复时速度要更慢。

因为在之前的系统安装过程中我已经配置好了一个单独的足够大的 swap 分区,为了休眠到硬盘,需要告诉系统如何休眠到 swap 分区,首先配置 initramfs,编辑 /etc/mkinitcpio.conf,找到 HOOKS 一行,在括号中加入 resume,并且保证 resume 一定要在 udev 之后,比如这样:

HOOKS=(base udev autodetect modconf keyboard keymap consolefont block filesystems resume fsck grub-btrfs-overlayfs)

之后重新生成 initramfs,sudo mkinitcpio -P

再然后需要添加一个内核参数 resume ,指定 swap 分区的设备,参数值支持所有块设备持久化命名方式 ,如分区设备号,如 resume=/dev/sda2,或分区 UUID,如 resume=UUID=5514c3aa-63ee-49ec-920d-859b00c676fe,因为在多硬盘的机器上,硬盘的设备号可能会改变,所以还是更推荐使用分区 UUID,运行 sudo blkid 可以获取分区的 UUID:

$ sudo blkid
/dev/sda3: UUID="0929463f-13fe-457b-965a-8382b07a1d5c" UUID_SUB="175a979b-1fa8-437b-9715-acd48864494f" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="Linux filesystem" PARTUUID="0ca55fc8-f4c8-42d8-8b1c-620595fa134f"
/dev/sda2: UUID="5514c3aa-63ee-49ec-920d-859b00c676fe" TYPE="swap" PARTLABEL="Linux swap" PARTUUID="2e482d5e-2295-4b58-bdc2-6a1aab0e0af4"
/dev/sda1: UUID="4567-9EEB" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI system partition" PARTUUID="24847dd6-c006-46a6-b91e-00466fb19ad4"

我的 swap 分区是 /dev/sda2,那么 UUID 就是 5514c3aa-63ee-49ec-920d-859b00c676fe。编辑 /etc/default/grub,找到 GRUB_CMDLINE_LINUX_DEFAULT 一行,将所需的内核参数填入引号中,如:

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet resume=UUID=5514c3aa-63ee-49ec-920d-859b00c676fe"

然后重新生成 grub 配置文件,sudo grub-mkconfig -o /boot/grub/grub.cfg

重启,运行 systemctl hibernate,系统就可以进入休眠状态了,按下电源键,就可以从休眠状态恢复。但这样有些麻烦,我们可以配置在短按电源键或笔记本合盖时进入休眠状态,编辑 /etc/systemd/logind.conf,我配置的是短按电源键进入休眠,加入或修改 HandlePowerKey=hibernate 一行,若想要配置合盖休眠,加入或修改 HandleLidSwitch=hibernate 一行,要记得删除行首的井号注释。重启后就可以通过短按电源键或合盖休眠了。

不过要注意休眠到硬盘的功能可能会在特定机型上出现问题,有时不同的内核版本也会影响休眠的正常工作,我前些天就遇到过问题,具体可以看我之前的文章。对于不同的机型,请自行测试是否有问题,对于出现的问题,建议阅读 Arch wiki 相关的页面,以及善用搜索引擎。

一些杂项配置

做完以上这些,系统差不多就可以正常使用了,但是你目前仍然无法享受到大多数发行版已经提前配置好的特性,因为这是 The Arch Way,什么东西都要自己配置,以下是我根据我个人的使用情况进行的可选的杂项配置,仅供参考。

机型问题修复

在一些锐龙处理器的机器上会出现 Linux 系统卡死的情况,只要系统负载稍微大一点,处理器核心温度一高就会卡死,搜索了一圈,我目前找到的最简单的解决方法是添加一个内核参数 idle=nomwait,编辑 /etc/default/grub,找到 GRUB_CMDLINE_LINUX_DEFAULT 一行,在引号中添加 idle=nomwait,比如这样:

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet resume=UUID=5514c3aa-63ee-49ec-920d-859b00c676fe idle=nomwait"

然后重新生成 grub 配置文件 sudo grub-mkconfig -o /boot/grub/grub.cfg,重启,再尝试运行一些负载较大的软件或游戏,会发现即使运行较长时间,系统也不会卡死了。不过代价是可能会导致系统在空载状态下功耗增加。

2023-05-13 更新

在最近一段时间的使用中,我又遇到了系统卡死的情况,但貌似和系统高负载没有关系,有时刚开机什么都没干就卡死了,使用主线内核卡死概率较高,切换回 lts 内核后,卡死的次数少了很多,但还是无法避免。最后我参照这篇文章中的内容禁用了锐龙处理器的 C6 状态,到现在为止用了好几天了没有再出现过卡死的问题,在这里记录一下:

首先安装 zenstates-git 包;

编辑 /etc/modules-load.d/modules.conf,是个空文件,添加内容 msr

添加一个服务文件 /etc/systemd/system/disable_c6.service

[Unit]
Description=Ryzen Disable C6
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=basic.target

[Service]
Type=oneshot
ExecStart=/usr/bin/zenstates --c6-disable

[Install]
WantedBy=basic.target

 

最后启用服务:

sudo systemctl daemon-reload
systemctl enable disable_c6.service

BBR 算法

谷歌开发的BBR 拥塞控制算法,可以实现更高的带宽和更低的延迟,想要优化网速,可以尝试开启这个功能,首先加载内核模块 tcp_bbrsudo modprobe tcp_bbr,之后编辑 /etc/sysctl.d/30-bbr.conf

net.core.default_qdisc = cake
net.ipv4.tcp_congestion_control = bbr

之后重启,应该就能生效了。

ipv6 隐私扩展

使用 SLAAC 获取的 ipv6 地址,不同于 ipv4 时代使用 NAT 和 dhcp 获取到的内网地址,是全球唯一的公网地址,公网地址更容易被攻击,另外获取的 ipv6 地址是由运营商下发的地址前缀和根据本机网卡 MAC 地址计算出来的后缀组成的,攻击者很有可能根据 ipv6 后缀反推出网卡的 MAC 地址,增大了其危险性。为了解决这个问题,ipv6 提供了一个隐私扩展特性,允许在常规的 ipv6 地址之外额外生成一个临时地址,在连接网络时会优先使用临时地址,从而增加了安全性。要启用 ipv6 隐私扩展,需要编辑 /etc/sysctl.d/40-ipv6.conf

net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
net.ipv6.conf.nic0.use_tempaddr = 2
...
net.ipv6.conf.nicN.use_tempaddr = 2

上面的 nic0nicN 要改成机器的网络接口名称,有几个就添加几个,不过若是配合 NetworkManager 使用,只添加前两行应该就够了。

之后重启,应该就能生效了。

加密 DNS

在浏览网页时,有时进入一个正常的网站,会莫名被跳转到钓鱼网站,这很有可能是系统 DNS 被污染了,因为常规的 DNS 协议使用的是 udp 明文传输,很容易被攻击者监听并篡改,而各大运营商默认分配的 DNS 是重点的污染对象,想要避免这个问题,就要使用加密的 DNS 协议。

systemd 自带的 systemd-resolved 其实已经支持了加密 DNS 协议,但是目前只支持 DNS-over-TLS,安全性相对较差一些,为了使用其他的加密 DNS 程序,需要禁用这个服务 sudo systemctl disable systemd-resolved.service --now。我选择的软件是 dnscrypt-proxy,支持一些最新的加密 DNS 特性,比如使用 HTTP3 的 DNS-over-HTTPS 协议,具体配置方法在这里,不再赘述。想要使用其他软件,可以看这里

加密 DNS 配置完成后,会与远程的加密 DNS 服务器连接,转发 DNS 请求到本地的 53 端口,但系统默认使用上级路由器 dhcp 分配的 DNS 服务器。想要修改系统默认使用的 DNS 服务器,最直接的方法是编辑 /etc/resolv.conf,在最顶部添加一行 nameserver 127.0.0.1,这样就能默认使用本地 DNS 服务器了,但问题是很多网络管理程序,包括 NetworkManager 都会修改这个文件,所以在重启后 /etc/resolv.conf 很有可能会变回默认。所以使用 NetworkManager 时,更有效的方法是编辑 NetworkManager 的配置文件,编辑 /etc/NetworkManager/conf.d/dns-servers.conf

[global-dns-domain-*]
servers=127.0.0.1

之后重启服务 sudo systemctl restart NetworkManager.service,这样无论连接什么网络,系统都会默认使用本地的 DNS 服务器了。

另外 Chromium 和 Firefox 浏览器都已经支持了加密 DNS,所以也可以在浏览器对应的配置项开启加密 DNS,这样加密 DNS 将只对浏览器生效。

随机 MAC 地址

NetworkManager 还有一个特性就是随机 MAC 地址,开启之后可以增加安全性,NetworkManager 默认开启了在 wifi 扫描时随机 MAC 地址,想要配置随机 MAC 地址,可以编辑 /etc/NetworkManager/conf.d/rand_mac.conf

[device-mac-randomization]
wifi.scan-rand-mac-address=yes

[connection-mac-randomization]
ethernet.cloned-mac-address=stable
wifi.cloned-mac-address=stable

wifi.scan-rand-mac-address 决定在 wifi 扫描时是否开启随机 MAC 地址,若需要固定的 MAC 地址,可以设为 no。ethernet.cloned-mac-addresswifi.cloned-mac-address 决定了连接有线网络和 wifi 网络时是否开启随机 MAC 地址,可用的值有:

  • 指定的 MAC 地址,连接时使用手动指定的 MAC 地址;
  • permanent,不改变 MAC 地址;
  • preserve,在网卡激活后不改变 MAC 地址;
  • random,在每次连接时都使用随机 MAC 地址;
  • stable,在初次连接一个网络时使用随机 MAC 地址,之后每次连接相同的网络都使用相同的 MAC 地址。

修改完后重启 NetworkManager 服务生效。

缓解关机卡 90 秒的问题

Linux 系统在关机时,偶尔会遇见卡住不动,要等大约 90 秒才可以关机的情况,这似乎是 systemd 的问题,systemd 以为有服务没有终止,但实际上没有,就只能等待直到强行停止,这个等待的时间默认就是 90 秒。

虽然不能完全解决这个问题,但至少可以修改它等待的时间,编辑 /etc/systemd/system.conf,添加或修改 DefaultTimeoutStopSec=90s 一行,记得删除行首井号注释,把时间改成一个较短的时间,比如 5 秒,这样等待的时间就会大大缩短了。

grub 美化

grub 是很多发行版使用的默认 bootloader,同时大部分 Linux 发行版都会默认对 grub 启动界面做一些美化,然而根据 The Arch Way,Arch Linux 默认同样不会对 grub 做多余的配置,默认就只是一个黑乎乎的菜单界面。

想要美化 grub 启动页面,最简单的方法是使用现成的 grub 主题,grub 软件包默认已经自带了一个主题,位于 /usr/share/grub/themes/starfield/,官方源中有 grub 主题 grub-theme-vimixbreeze-grub,AUR 中也有很多 grub 主题,另外也可以在这里手动下载主题。

用包管理器安装的主题也好,手动下载的主题也好,主题文件夹里面都会有一个 theme.txt 文件,运行 pacman -Ql package 可以列出指定软件包安装的所有文件,找到想要使用的主题对应的 theme.txt 文件,以 grub 自带的 starfield 主题为例,路径在 /usr/share/grub/themes/starfield/theme.txt,编辑 /etc/default/grub,找到 GRUB_THEME 一行,删除行首的井号注释,并将引号内的内容改成对应的 theme.txt 路径,比如:

GRUB_THEME="/usr/share/grub/themes/starfield/theme.txt"

之后重新生成 grub 配置文件,sudo grub-mkconfig -o /boot/grub/grub.cfg,这样下次开机时就可以看到美化后的 grub 菜单了。

pacman 配置

Arch linux 的包管理器 pacman 也有一些有用的配置项默认没有开启,编辑 /etc/pacman.conf,首先启用 32 位软件源 multilib,以便安装一些 32 位软件,比如 steam,取消注释以下两行:

[multilib]
Include = /etc/pacman.d/mirrorlist

之后在 [options] 下找到并取消注释:Color,启用彩色高亮;VerbosePkgLists,在安装或升级软件时显示详细变化;ParallelDownloads = 5,启用并行下载,提高下载速度。另外添加一行 IloveCandy,这是 pacman 的一个有趣的小彩蛋,可以让进度条变成吃豆人的样子。

添加第三方软件源

ArchlinuxCN

这是 ArchlinuxCN 社区维护的软件仓库,包含了很多中文用户常用软件包。以北外镜像站为例,在 /etc/pacman.conf 末尾添加如下两行:

[archlinuxcn]
Server = https://mirrors.bfsu.edu.cn/archlinuxcn/$arch

之后运行 sudo pacman -Sy archlinuxcn-keyring 以刷新密钥,另外可选的也可以安装 archlinuxcn-mirrorlist 包,会安装一个 /etc/pacman.d/archlinuxcn-mirrorlist 镜像列表,编辑这个文件,将最快的镜像源(一般可选北外、清华、华科的镜像等)移动到最顶部并删除注释,再次编辑 /etc/pacman.conf,将软件源修改为:

[archlinuxcn]
Include = /etc/pacman.d/archlinuxcn-mirrorlist

Chaotic-AUR

Chaotic-AUR 包含了很多构建好的 AUR 软件包,若想在安装 AUR 软件包时节省一些时间,可以添加这个软件源:

 sudo pacman-key --recv-key FBA220DFC880C036 --keyserver keyserver.ubuntu.com
 sudo pacman-key --lsign-key FBA220DFC880C036
 sudo pacman -U 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-keyring.pkg.tar.zst' 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-mirrorlist.pkg.tar.zst'

/etc/pacman.conf 末尾添加如下两行:

[chaotic-aur]
Include = /etc/pacman.d/chaotic-mirrorlist

之后编辑 /etc/pacman.d/chaotic-mirrorlist 镜像列表,Chaotic-AUR 之前有一个托管在阿里云的国内镜像,相对速度快一些,但前段时间不知为何这个镜像没有了,目前国内最近的镜像是在韩国和印度,可以将这两个镜像放在最开头,虽然也不太快,但至少能用。

ALHP

ALHP 软件源将 Arch Linux 官方源中的软件包进行了重新编译,使用了 x86-64-v2x86-64-v3 优化,可以提升一部分性能。

添加这个软件源之前,需要先确认当前机器是否支持 x86-64-v2x86-64-v3,运行 /lib/ld-linux-x86-64.so.2 --help,若输出中有:

Subdirectories of glibc-hwcaps directories, in priority order:
  x86-64-v4
  x86-64-v3 (supported, searched)
  x86-64-v2 (supported, searched)

说明机器支持 x86-64-v2x86-64-v3

之后从 AUR 安装 alhp-keyringalhp-mirrorlist,之后编辑 /etc/pacman.d/alhp-mirrorlist 镜像列表,alhp 在国内有上海科技大学镜像站一个镜像源,这个镜像源速度不太稳定,不过也比其他国外镜像快许多,推荐将这个镜像源放在首位。之后编辑 /etc/pacman.conf,添加:

[core-x86-64-v3]
Include = /etc/pacman.d/alhp-mirrorlist

[extra-x86-64-v3]
Include = /etc/pacman.d/alhp-mirrorlist

[community-x86-64-v3]
Include = /etc/pacman.d/alhp-mirrorlist

若系统只支持 x86-64-v2,需要将 x86-64-v3 改成 x86-64-v2,另外一定要添加在官方的 [core][extra][community] 之前,保证软件包优先于官方包安装。

之后运行 sudo pacman -Suy,这会安装很多软件包,需要较长时间,完成后重启。添加了这个软件源后,跑了下分没有明显变化,但是在游戏中帧率好像高了些,还稳定了些,有点玄学,提升聊胜于无吧。

若遇到了问题,想要禁用这个软件源,只需删除 /etc/pacman.conf 中对应的内容,卸载 alhp-keyringalhp-mirrorlist,之后运行 sudo pacman -Suuy,就可以将所有软件包恢复到官方了。

时间同步

systemd 自带了一个 systemd-timesyncd 服务,提供了简单的时间同步服务,若是没有特别需求,这个服务已经够用了。不过这个服务默认使用的是 Arch Linux 自己的 NTP 服务器,在国内访问较慢,有时会导致时间同步失败,为了更快地同步时间,可以选用其他的 NTP 服务器,我选用了中国 NTP 快速授时服务和中国计量科学研究院 NIM 授时服务的 NTP 服务器,编辑 /etc/systemd/timesyncd.conf,添加或编辑如下一行:

NTP=cn.ntp.org.cn ntp1.nim.ac.cn

然后重启 systemd-timesyncd.service,之后运行 timedatectl timesync-status 便可查看时间同步状态:

$ timedatectl timesync-status
       Server: 2001:da8:9000::130 (cn.ntp.org.cn)
Poll interval: 34min 8s (min: 32s; max 34min 8s)
         Leap: normal
      Version: 4
      Stratum: 1
    Reference: PTP
    Precision: 1us (-26)
Root distance: 45us (max: 5s)
       Offset: -2.957ms
        Delay: 31.415ms
       Jitter: 4.354ms
 Packet count: 18
    Frequency: -4.740ppm

可以看到这里 offset 只有不到 3 毫秒,还是很精准的。

笔记本续航优化

Arch Linux 在笔记本平台相比于 Windows 和其他功能齐全的 Linux 发行版一个比较大的劣势就是续航较差,因为其默认并没有为笔记本续航做优化。

而 Linux 平台笔记本续航优化的软件,最为人熟知且被最多人推荐的是 TLP,并且已经被很多发行版预装,这个软件支持很多设备的省电模式优化,如 CPU、无线网络、蓝牙、硬盘等等,配置好了的话可以大大延长笔记本的续航时间。但是这个软件在我的笔记本上运行似乎有些问题,在断开电源后一段时间后外接键盘会不能用,这大概是 USB 自动休眠的问题,但就算我在配置文件中禁用了 USB 自动休眠,问题也没解决。并且 TLP 默认对省电模式的性能限制有点狠,CPU 无法睿频,导致在电池模式下干什么事情都挺卡的。因为我的使用情况大部分时间笔记本都连着电源,所以续航不太敏感,所以我就一直没有装 TLP。

就在最近我发现了另外一个程序,叫 auto-cpufreq,顾名思义,这个程序负责自动调节 CPU 频率,连接电源时使用性能模式,断开电源后使用省电模式,并且不限制睿频,对于省电的效果可能没有 TLP 那么好,但因为它只负责调节 CPU,不会出现 TLP 上面好多设备不能用的玄学问题,并且这些设备的功耗也不是占大头。安装的话只需从 AUR 安装,无需进行过多设置,直接启用相关服务即可,sudo systemctl enable auto-cpufreq.service --now