diff --git a/flake.lock b/flake.lock index 2aa7600..c73796c 100644 --- a/flake.lock +++ b/flake.lock @@ -224,11 +224,11 @@ ] }, "locked": { - "lastModified": 1767048910, - "narHash": "sha256-KLFTeA/xquN+F3XHLAXcserk0L0nijbhzuldxNDF1eE=", + "lastModified": 1767104570, + "narHash": "sha256-GKgwu5//R+cLdKysZjGqvUEEOGXXLdt93sNXeb2M/Lk=", "owner": "nix-community", "repo": "home-manager", - "rev": "d99b4ca5debaa082c7d76015aa2b7f3fc7e8b5f7", + "rev": "e4e78a2cbeaddd07ab7238971b16468cc1d14daf", "type": "github" }, "original": { @@ -304,11 +304,11 @@ ] }, "locked": { - "lastModified": 1767053113, - "narHash": "sha256-WTKK/mqdUQWEhC00A6SLWCo2pIxDwZFntN8XlRWRM6Q=", + "lastModified": 1767139482, + "narHash": "sha256-9XSkEzbNJgx5QFaCZ9e+M3zvfHlcy6mC3dHWOf6sWdo=", "owner": "nix-community", "repo": "neovim-nightly-overlay", - "rev": "beac40644794d7caac0ba673ee6c6b6fbb7dadd4", + "rev": "4f1d5c13b233eed1dc607557503740d0cb4d3c27", "type": "github" }, "original": { @@ -320,11 +320,11 @@ "neovim-src": { "flake": false, "locked": { - "lastModified": 1767047423, - "narHash": "sha256-gjHEPV0agQqaxWrBsfQNVweLnlatR1Fin8xfdAYCWOQ=", + "lastModified": 1767115711, + "narHash": "sha256-OlWYT3jSndNvhT2LtNHLhpsheDSoAKFSKw+kgY6XiHc=", "owner": "neovim", "repo": "neovim", - "rev": "03377b95523324a2a1657435f12c13a493ee5360", + "rev": "f4f60f6a193f9c715fe5ff7574c8c42d17ad04f5", "type": "github" }, "original": { @@ -335,11 +335,11 @@ }, "nix-secrets": { "locked": { - "lastModified": 1767035320, - "narHash": "sha256-vcIKF8fLOinWI35OVZzFP6jyXLEvfCcibgEGDqcVDcA=", + "lastModified": 1767211544, + "narHash": "sha256-AY7BVcQ0tQ6cXz1nQX6Q+ieKhKOYAt+wPO9d4Ar8zhI=", "ref": "refs/heads/main", - "rev": "458133e3b9d33f64d0e79102c09d20bb8568f089", - "revCount": 9, + "rev": "d360b6d4035527e98205820e4084074c29f45e77", + "revCount": 11, "type": "git", "url": "https://git.ts.endless.li/ed209/nix-secrets.git" }, @@ -521,11 +521,11 @@ ] }, "locked": { - "lastModified": 1767062690, - "narHash": "sha256-hfKAOJQYbR0mlwabV56tOlEMUgESRroHqlDpX0hwOpU=", + "lastModified": 1767149068, + "narHash": "sha256-TjfAb58Ybz/93e2jP0qD846dj+VqiY7wk+EqsxcZ708=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "943d2d0bf1b86267287aff826ebd1138d83113b7", + "rev": "6d14586a5917a1ec7f045ac97e6d00c68ea5d9f3", "type": "github" }, "original": { diff --git a/hosts/sachiel/configuration.nix b/hosts/sachiel/configuration.nix index 7ad7c49..4fa4b74 100644 --- a/hosts/sachiel/configuration.nix +++ b/hosts/sachiel/configuration.nix @@ -36,7 +36,7 @@ ]; age = with inputs; { - identityPaths = ["${nix-secrets}/identities/age-tpm-identity-vm.txt"]; + identityPaths = ["/persistent/age-tpm.txt"]; # TODO: Modulerize config by declare pkgs in a list as a module option, and # have module implementation mkMerge into the binpath ageBin = "PATH=$PATH:${lib.makeBinPath [pkgs.age-plugin-yubikey pkgs.age-plugin-tpm]} ${pkgs.age}/bin/age"; @@ -49,11 +49,14 @@ hideMounts = true; directories = [ "/var/log" - "/var/lib/bluetooth" "/var/lib/nixos" "/var/lib/sbctl" "/var/lib/systemd/coredump" - "/etc/NetworkManager/system-connections" + "/var/lib/systemd/timers" + "/var/lib/systemd/timesync" + "/var/lib/bluetooth" + "/var/lib/dbus" + "/etc/NetworkManager" ]; files = [ "/etc/machine-id" @@ -63,6 +66,18 @@ "/etc/ssh/ssh_host_rsa_key.pub" ]; }; + swapDevices = [ + { + device = "/swapfile"; + size = 2048; + randomEncryption = { + enable = true; + source = "/dev/random"; + #sectorSize = 4096; + }; + options = ["nofail"]; + } + ]; nixpkgs = { # You can add overlays here @@ -126,6 +141,166 @@ # Load the TPM drivers in the initram to allow for decryption of agenix # secrets. boot.initrd.availableKernelModules = ["tpm_crb" "tpm_tis"]; + boot.initrd.systemd.services.rollback = { + description = "Rollback BTRFS root subvolume to a pristine state"; + wantedBy = ["initrd.target"]; + after = [ + "systemd-cryptsetup@enc.service" + "systemd-cryptsetup@cryptroot.service" + ]; + before = ["sysroot.mount"]; + unitConfig.DefaultDependencies = "no"; + serviceConfig = { + Type = "oneshot"; + UMask = "0077"; + }; + script = '' + set -euo pipefail + + echo "Starting impermanence rollback..." + + LUKS_DEVICE="" + for device in /dev/mapper/enc /dev/mapper/cryptroot; do + if [[ -b "$device" ]]; then + LUKS_DEVICE="$device" + break + fi + done + + if [[ -z "$LUKS_DEVICE" ]]; then + echo "Error: No LUKS device found (tried enc, cryptroot), skipping rollback" + exit 0 + fi + + echo "Found LUKS device: $LUKS_DEVICE" + + mkdir -p /mnt + + if ! mount -o subvol=/ "$LUKS_DEVICE" /mnt; then + echo "Error: Failed to mount root filesystem" + exit 1 + fi + + if [[ ! -d "/mnt/root-blank" ]]; then + echo "Error: /mnt/root-blank snapshot not found, skipping rollback" + umount /mnt || true + exit 0 + fi + + echo "Found root-blank snapshot, proceeding with rollback" + + if [[ -d "/mnt/root" ]]; then + echo "Removing nested subvolumes..." + btrfs subvolume list -o /mnt/root | cut -f9 -d' ' | while read -r subvolume; do + if [[ -n "$subvolume" ]]; then + echo "Deleting /$subvolume subvolume..." + btrfs subvolume delete "/mnt/$subvolume" || echo "Warning: Failed to delete $subvolume" + fi + done + + echo "Deleting /root subvolume..." + if ! btrfs subvolume delete /mnt/root; then + echo "Error: Failed to delete /root subvolume" + umount /mnt || true + exit 1 + fi + fi + + echo "Restoring blank /root subvolume..." + if ! btrfs subvolume snapshot /mnt/root-blank /mnt/root; then + echo "Error: Failed to create snapshot" + umount /mnt || true + exit 1 + fi + + echo "Rollback completed successfully" + umount /mnt || echo "Warning: Failed to unmount /mnt" + ''; + }; + # boot.initrd.postDeviceCommands = lib.mkAfter '' + # set -euo pipefail + # mkdir -p /mnt + # { + # echo "Starting impermanence rollback..." + # + # LUKS_DEVICE="" + # for device in /dev/mapper/enc /dev/mapper/cryptroot; do + # if [[ -b "$device" ]]; then + # LUKS_DEVICE="$device" + # break + # fi + # done + # + # if [[ -z "$LUKS_DEVICE" ]]; then + # echo "Error: No LUKS device found (tried enc, cryptroot), skipping rollback" + # exit 0 + # fi + # + # echo "Found LUKS device: $LUKS_DEVICE" + # if ! mount -o subvol=/ "$LUKS_DEVICE" /mnt; then + # echo "Error: Failed to mount root filesystem" + # exit 1 + # fi + # + # if [[ ! -d "/mnt/root-blank" ]]; then + # echo "Error: /mnt/root-blank snapshot not found, skipping rollback" + # umount /mnt || true + # exit 0 + # fi + # + # echo "Found root-blank snapshot, proceeding with rollback" + # + # if [[ -d "/mnt/root" ]]; then + # echo "Removing nested subvolumes..." + # btrfs subvolume list -o /mnt/root | cut -f9 -d' ' | while read -r subvolume; do + # if [[ -n "$subvolume" ]]; then + # echo "Deleting /$subvolume subvolume..." + # btrfs subvolume delete "/mnt/$subvolume" || echo "Warning: Failed to delete $subvolume" + # fi + # done + # + # echo "Deleting /root subvolume..." + # if ! btrfs subvolume delete /mnt/root; then + # echo "Error: Failed to delete /root subvolume" + # umount /mnt || true + # exit 1 + # fi + # fi + # + # echo "Restoring blank /root subvolume..." + # if ! btrfs subvolume snapshot /mnt/root-blank /mnt/root; then + # echo "Error: Failed to create snapshot" + # umount /mnt || true + # exit 1 + # fi + # + # echo "Rollback completed successfully" + # umount /mnt || echo "Warning: Failed to unmount /mnt" + # } > /mnt/rollback.log + # ''; + # mkdir /btrfs_tmp + # mount /dev/mapper/cryptroot /btrfs_tmp + # if [[ -e /btrfs_tmp/root ]]; then + # mkdir -p /btrfs_tmp/old_roots + # timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S") + # mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp" + # fi + # + # delete_subvolume_recursively() { + # IFS=$'\n' + # for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do + # delete_subvolume_recursively "/btrfs_tmp/$i" + # done + # btrfs subvolume delete "$1" + # } + # + # for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do + # delete_subvolume_recursively "$i" + # done + # + # btrfs subvolume create /btrfs_tmp/root + # umount /btrfs_tmp + # ''; networking.hostName = "sachiel-vm"; # Define your hostname. # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. @@ -197,7 +372,7 @@ extraGroups = ["networkmanager" "wheel"]; openssh.authorizedKeys.keys = inputs.nix-secrets.ssh-keys; shell = pkgs.fish; - hashedPasswordFile = config.age.secrets.password.path; + hashedPassword = inputs.nix-secrets.hashedPassword; }; # Disable root user # users.users.root.hashedPassword = "!"; diff --git a/hosts/sachiel/disko-config.nix b/hosts/sachiel/disko-config.nix index a7fd484..2b34cc8 100644 --- a/hosts/sachiel/disko-config.nix +++ b/hosts/sachiel/disko-config.nix @@ -9,7 +9,7 @@ partitions = { ESP = { type = "EF00"; - size = "512M"; + size = "1G"; content = { type = "filesystem"; format = "vfat"; @@ -30,6 +30,20 @@ type = "btrfs"; extraArgs = ["-L" "nixos" "-f"]; subvolumes = { + "/root" = { + mountOptions = [ + "compress=zstd" + "noatime" + ]; + mountpoint = "/"; + }; + "/home" = { + mountOptions = [ + "compress=zstd" + "noatime" + ]; + mountpoint = "/home"; + }; "/nix" = { mountOptions = [ "compress=zstd" @@ -38,10 +52,19 @@ mountpoint = "/nix"; }; "/persistent" = { - mountOptions = ["compress=zstd"]; + mountOptions = [ + "compress=zstd" + "noatime" + ]; mountpoint = "/persistent"; }; }; + postCreateHook = '' + mount -t btrfs /dev/disk/by-label/nixos /mnt + btrfs subvolume snapshot -r /mnt/ /mnt/root-blank + cp /home/nixos/age-tpm.txt /mnt/persistent/age-tpm.txt + umount /mnt + ''; }; }; }; @@ -50,10 +73,7 @@ }; }; }; - fileSystems."/" = { - device = "none"; - fsType = "tmpfs"; - options = ["defaults" "size=2G" "mode=755"]; - }; + fileSystems."/persistent".neededForBoot = true; + fileSystems."/var/log".neededForBoot = true; }