🚀

NixOSでSecureBoot+LVM on LUKS

2024/12/03に公開

前がたり

動機

https://zenn.dev/keitti73/articles/d06c0a587695da
これと同じことをNixOSでもしたいよねということです。

Q.グラフィカルインストール出でてくる暗号化じゃだめなの?

A.駄目です。
理由:
グラフィカルインストールでできる暗号化はLUKS1使用されています(要出典
また、LVM on LUKSになってないのでパーティション構成用意に変更できません(変更する必要があるかは議論しないものとする)

課題

  • 筆者がflakeやhome-managerについて理解しておらず使用していない。
    • どころかnixそのものについてもまともに理解していない
  • これがスマートなやり方かどうか検証できていない(n=1なため
  • systemd-homedが使えず、ホームディレクトリの暗号化は行えていない

成果物

https://github.com/keitti73/Nix_home_server_config

構築

パーティションを切る

cgdisk /dev/shX

で編集することをおすすめする
TUIで編集できる
構成はこのようにする

パーティションネーム パーティションタイプ パーティションID 推奨サイズ
boot EFI system ef00 1G
system Linux LVM 8e00 残りすべて

swap領域はLVMの中に作成するためここでは作成不要だ
bootパーティションはセキュアブートのためにいじくり回すので多めに取っておこう!

Systemパーティションの暗号化

前項でsystemと名付けたパーティションを暗号化していく

#パーティションをLUKSをつかってフォーマット
cryptsetup luksFormat /dev/nvme0n1p2
#暗号化コンテナをオープンする
cryptsetup open --type luks /dev/nvme0n1p2 cryptolvm
#復号化されたコンテナが /dev/mapper/cryptolvm から利用できる

これでsystemパーティションがLUKSによって暗号化された
この上にLVMを使ってパーティションを切っていく

#物理ボリュームを作成
pvcreate /dev/mapper/cryptolvm
#MyVol という名前のボリュームグループを作成して、先に作成した物理ボリュームを追加
vgcreate MyVol /dev/mapper/cryptolvm
#ボリュームグループに論理ボリュームを作成
lvcreate -L 32G MyVol -n swap #swap領域
lvcreate -l 100%FREE -n system MyVol #system領域

メモリが16GBあるのでswapは2倍理論を採用しswapは32GBとした
任意の値を入れてほしい

フォーマット

作成するためしたパーティションをフォーマットしていく

#bootパーティション:fat32でフォーマット
mkfs.vfat -F32 /dev/nvme0n1p1
#rootパーティション:ext4でフォーマット
mkfs.ext4 /dev/mapper/MyVol-system
#swap領域
mkswap /dev/mapper/MyVol-swap

今回はext4を使うことにしたがお好みのファイルシステムでフォーマットしていただければ大丈夫だ
xfsなどは最初からarchisoに入っているのでインストール不要だ

マウント

フォーマットしたパーティションをマウントする

#/mntにsystem領域をマウントする
mount /dev/mapper/MyVol-system /mnt
#boot領域作成
mkdir /mnt/boot
#boot領域にbootパーティションをマウント
mount /dev/nvme0n1p1 /mnt/boot
#swap領域を有効化する
swapon /dev/mapper/MyVol-swap

暗号化されたパーティションをboot時解錠できるようにする

コンフィグを生成

nixos-generate-config --root /mnt

まず暗号化したパーティションのuuidを確認する

lsblk -f
NAME               FSTYPE      FSVER    LABEL       UUID                                   FSAVAIL FSUSE% MOUNTPOINTS
sda
└─sda1             vfat        FAT32    NIXOS-MINIM 19EF-375D
nvme0n1
├─nvme0n1p1        vfat        FAT32                3699-EB86                               924.1M    10% /boot
└─nvme0n1p2        crypto_LUKS 2                    9d15756c-f988-446c-ad3e-41af792d5e81
  └─cryptlvm       LVM2_member LVM2 001             sCNyoX-EzJF-UPQG-3XJ3-RMQT-wTFo-LmHBKG
    ├─MyVol-swap   swap        1                    3e35b190-57ae-4844-b6ec-2f22716d4a55                  [SWAP]
    └─MyVol-system ext4        1.0                  fe96fe5c-ffeb-40e4-be64-e093b377b100    410.3G     4% /nix/store

この様になっていると思います
この場合"9d15756c-f988-446c-ad3e-41af792d5e81"をメモしておいてください。
暗号化してストレージをブートローダーが解除できるようにconfigure.nixを編集していきます。

configure.nix
+  boot.initrd.services.lvm.enable = true;
+  boot.initrd.luks.devices = {
+    cryptlvm = {
+      device = "/dev/disk/by-uuid/9d15756c-f988-446c-ad3e-41af792d5e81";
+    };
+  };

これを追加すればOKです。
その他お好みを設定を行ってください。
詳しい部分は説明できません(筆者がNixOSをまともに理解していないため)
設定を行ったらNixOSをビルドして再起動します。

nixos-install

reboot

再起動後TPM2を使ってストレージを復号するために鍵を登録します。

systemd-cryptenroll /dev/nvme0n1p2 --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=7

これで、LVM on LUKSの設定は完了です。

セキュアブートを有効化する

https://github.com/nix-community/lanzaboote
このプロジェクトにしたがって進めていきます
https://github.com/nix-community/lanzaboote/blob/master/docs/QUICK_START.md
クイックスタートはこれです。

鍵を生成する

sudo sbctl create-keys

nivを使ってリポジトリを読み込む

cd /etc/nixos/
niv init
niv add nix-community/lanzaboote -r v0.4.1 -v 0.4.1

その後configure.nixを編集する
以下は公式のサンプルコードです。

# file: configuration.nix
{ pkgs, lib, ... }:
+let
+    sources = import ./nix/sources.nix;
+    lanzaboote = import sources.lanzaboote;
+in
{
+  imports = [ lanzaboote.nixosModules.lanzaboote ];

  environment.systemPackages = [
    # For debugging and troubleshooting Secure Boot.
+   pkgs.sbctl
  ];

  # Lanzaboote currently replaces the systemd-boot module.
  # This setting is usually set to true in configuration.nix
  # generated at installation time. So we force it to false
  # for now.
-  boot.loader.systemd-boot.enable = true;
+  boot.loader.systemd-boot.enable = lib.mkForce false;

+  boot.lanzaboote = {
+    enable = true;
+    pkiBundle = "/etc/secureboot";
+  };
}

configure.nixを編集し終わったら

nixos-rebuild switch

でビルドし直します

UEFIにに入りsetup mode にする

マザボによってやり方が違うので詳しく書きません。
UEFI Passwordを設定しないとCustom setup modeに入れないマザボもあるので気をつけてください(一敗

キーをマザボに登録する

NixOSが起動したら

sudo sbctl enroll-keys --microsoft

でキーをマザボに交換します。
その後、再びUEFIを起動しSecure Bootを有効にします。
これでSecure Bootが有効になるはずです。

あとがき

これでできるはずです。
筆者はまじでNixについてわかってないのでこれがベストなやり方かわかってません。
指摘があれば修正します。

Discussion