NixOS 安装与配置(一):硬盘分区

· 3 min

2024-06-29: 更新分区方案,增加备用密钥,不再使用 tmpfs

最近换到 NixOS 了,安装记录写太长干脆多写一点分段发布。

目录

  1. 硬盘分区 (you are here)
  2. 系统配置
  3. 程序配置

准备

上文,我有一个安装了 Ventoy 的移动硬盘。

从 NixOS 网站下载 Minimal ISO image (64-bit Intel/AMD),放入文件夹并进入 LiveCD 环境。

配置

这里从 Disko 提供的 LUKS Btrfs Subvolumes 示例配置 开始。

cd /tmp
curl https://raw.githubusercontent.com/nix-community/disko/master/example/luks-btrfs-subvolumes.nix -o /tmp/disko-config.nix

首先对它(的上半部分)进行一些基础更改:

{
  disko.devices = {
    disk = {
-     vdb = {
+     nvme0n1 = {
        type = "disk";
-       device = "/dev/vdb";
+       device = "/dev/nvme0n1";
        content = {
          type = "gpt";
          partitions = {
            ESP = {
-             size = "512M";
+             size = "1G";
              type = "EF00";
              content = {
                type = "filesystem";
                format = "vfat";
                mountpoint = "/boot";
                mountOptions = [ "defaults" ];
              };
            };
            luks = {
              size = "100%";
              content = {
                type = "luks";
-               name = "crypted";
+               name = "cryptroot";
  • 本次使用 /dev/nvme0n1 作为系统盘。
  • 虽然 512M 的 ESP 很合理,但是 1G 可以给我更多安全感。(2T 的盘不差这点)
  • cryptroot 命名更常见(个人喜好)

LUKS

我使用 U 盘分区中的密钥文件。因为尝试 systemd-cryptenroll FIDO2 翻车了

预先 FAT32 格式化,通过 ls -l /dev/disk/by-id 查看一下分区 ID;

这里假设为 /dev/disk/by-id/usb-primary_key-part1

挂载并写入一个 8192 长度的 os.key 文件:

sudo mkdir -p /key
sudo mount -n -t vfat -o rw /dev/disk/by-id/usb-primary_key-part1 /key
sudo dd if=/dev/random of=/key/os.key bs=8192 count=1

如果你有多余的 U 盘,还可以作为备用密钥(只需要将 os.key 文件拷贝一份即可)。

修改配置:

let
  primary_key = "/dev/disk/by-id/usb-primary_key-part1";
  backup_key = "/dev/disk/by-id/usb-backup_key-part1";
in
{
  luks = {
    size = "100%";
    content = {
      type = "luks";
      name = "cryptroot";
      settings = {
        allowDiscards = true;
+       bypassWorkqueues = true; # 禁用工作队列以提高 SSD 性能
-       keyFile = "/tmp/secret.key";
+       keyFile = "/key/os.key"; # 密钥文件挂载位置
+       keyFileSize = 8192; # 密钥文件大小
+       preOpenCommands = ''
+         mkdir -m 0755 -p /key
+         sleep 5
+         mount -n -t vfat -o ro ${primary_key} /key || mount -n -t vfat -o ro ${backup_key} /key
+       '';
+       postOpenCommands = ''
+         umount /key
+         rm -rf /key
+       '';
      };
      # content = ...
    }
  }
}

preOpenCommands / postOpenCommands 部分我参考了 NixOS Wiki

无状态

我从一开始就准备使用 Impermanence

简单来说只需要两个 Btrfs 子卷——/nix/persist

接上面的 content,替换 subvolumes

{
  content = {
    type = "btrfs";
    extraArgs = [ "-f" ];
    subvolumes = {
      "/root" = {
        mountpoint = "/";
        mountOptions = [ "compress=zstd" "noatime" ];
      };
+     "/persist" = {
+       mountpoint = "/persist";
+       mountOptions = [ "compress=zstd" "noatime" ];
+     };
-     "/home" = {
-       mountpoint = "/home";
-       mountOptions = [ "compress=zstd" "noatime" ];
-     };
      "/nix" = {
        mountpoint = "/nix";
        mountOptions = [ "compress=zstd" "noatime" ];
      };
-     "/swap" = {
-       mountpoint = "/.swapvol";
-       swap.swapfile.size = "20M";
-     };
    };
  };
}

persist 子卷需要设置 neededForBoot,添加在配置末尾。

fileSystems."/persist".neededForBoot = true;

为什么删掉 swap?因为我觉得我用不到。

透明压缩

可以看到上面 Btrfs 子卷的 mountOptions 是 "compress=zstd" "noatime"

我将 compress=zstd 改成 compress-force=zstd:1,强制使用压缩并增加压缩级别。

应用配置

sudo nix --experimental-features "nix-command flakes" \
  run github:nix-community/disko -- \
  --mode disko /tmp/disko-config.nix

运行一下 mount | grep /mnt 会发现已经挂载分区。