mirror of
https://github.com/ItsDrike/nixdots
synced 2024-11-10 07:59:40 +00:00
111 lines
4.6 KiB
Nix
111 lines
4.6 KiB
Nix
|
{ config }: let
|
||
|
cfgSystem = config.myOptions.system;
|
||
|
cfg = config.myOptions.system.impermanence.root;
|
||
|
in
|
||
|
{
|
||
|
config = mkIf cfg.enable {
|
||
|
users = {
|
||
|
# This option makes it that users are not mutable outside of our configuration.
|
||
|
# If you're using root impermanence, this will actually be the case regardless
|
||
|
# of this setting, however, setting this explicitly is a good idea, because nix
|
||
|
# will warn us if our users don't have passwords set, preventing lock outs.
|
||
|
mutableUsers = false;
|
||
|
|
||
|
# Each existing user needs to have a password file defined here, otherwise
|
||
|
# they will not be available to login. These password files can be generated with:
|
||
|
# mkpasswd -m sha-512 > /persist/passwords/myuser
|
||
|
users = {
|
||
|
root = {
|
||
|
hashedPasswordFile = "${cfg.persistentMountPoint}/passwords/root";
|
||
|
};
|
||
|
${cfgSystem.username} = {
|
||
|
hashedPasswordFile = "${cfg.persistentMountPoint}/passwords/${cfgSystem.username}";
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
environment.persistence."${cfg.persistentMountPoint}/system" = {
|
||
|
hideMounts = true;
|
||
|
directories = [
|
||
|
"/etc/nixos" # NixOS configuration source
|
||
|
"/etc/NetworkManager/system-connections" # saved network connections
|
||
|
"/var/db/sudo" # keeps track of who got the sudo lecture already
|
||
|
"/var/lib/systemd/coredump" # captured coredumps
|
||
|
] ++ cfg.extraDirectories;
|
||
|
|
||
|
files = [
|
||
|
"/etc/machine-id"
|
||
|
] ++ cfg.extraFiles;
|
||
|
};
|
||
|
|
||
|
# For some reason, NetworkManager needs this instead of the impermanence mode
|
||
|
# to not get screwed up
|
||
|
systemd.tmpfiles.rules = [
|
||
|
"L /var/lib/NetworkManager/secret_key - - - - ${cfg.persistentMountPoint}/system/var/lib/NetworkManager/secret_key"
|
||
|
"L /var/lib/NetworkManager/seen-bssids - - - - ${cfg.persistentMountPoint}/system/var/lib/NetworkManager/seen-bssids"
|
||
|
"L /var/lib/NetworkManager/timestamps - - - - ${cfg.persistentMountPoint}/system/var/lib/NetworkManager/timestamps"
|
||
|
];
|
||
|
|
||
|
# Define host key paths in the persistent mount point instead of using impermanence for these.
|
||
|
# This works better, because these keys also get auto-created if they don't already exist.
|
||
|
services.openssh.hostKeys = mkForce [
|
||
|
{
|
||
|
bits = 4096;
|
||
|
path = "${cfg.persistentMountPoint}/system/etc/ssh/ssh_host_rsa_key";
|
||
|
type = "rsa";
|
||
|
}
|
||
|
{
|
||
|
bits = 4096;
|
||
|
path = "${cfg.persistentMountPoint}/system/etc/ssh/ssh_host_ed25519_key";
|
||
|
type = "ed25519";
|
||
|
}
|
||
|
];
|
||
|
|
||
|
boot.initrd.systemd = let
|
||
|
cfgWipe = cfg.autoBtrfsWipe;
|
||
|
in {
|
||
|
enable = true; # This enables systemd support in stage 1 - required for below setup
|
||
|
services.rollback-root = {
|
||
|
description = "Rollback BTRFS root subvolume to a pristine state";
|
||
|
enable = cfgWipe.enable;
|
||
|
wantedby = [ "initrd.target" ];
|
||
|
# Make sure it's done after decryption (i.e. LUKS/TPM process)
|
||
|
after = [ "systemd-cryptsetup@cryptfs.service" ];
|
||
|
# mount the root fs before clearing
|
||
|
before = [ "sysroot.mount" ];
|
||
|
unitConfig.DefaultDependencies = "no";
|
||
|
serviceConfig.Type = "oneshot";
|
||
|
script = ''
|
||
|
# Mount the BTRFS root to /mnt, so we can manipulate the subvolumes
|
||
|
mount --mkdir ${cfgWipe.devicePath} /mnt
|
||
|
|
||
|
# To restore the root subvolume, we will first delete it, and then create
|
||
|
# a new snapshot from the blank snapshot, which will become our new root subvolume
|
||
|
|
||
|
# However, at this point, root subvol is already populated and contains a number
|
||
|
# of subvolumes, which would make `btrfs subvolume delete` fail.
|
||
|
#
|
||
|
# These existing subvolumes get created automatically, and we can safely remove
|
||
|
# them. They are: /srv, /var/lib/portables, /var/lib/machines, /var/tmp
|
||
|
sudo btrfs subvolume list -o "/mnt/${cfgWipe.subvolumePath}" | cut -f9 -d' ' |
|
||
|
while read subvolme; do
|
||
|
echo "deleting $subvolume subvolume..." &&
|
||
|
btrfs subvolume delete "/mnt/$subvolume"
|
||
|
done
|
||
|
|
||
|
# Now we can remove the root subvolume, and restore it from a snapshot
|
||
|
echo "deleting ${cfgWipe.subvolumePath} (root) subvolume..."
|
||
|
btrfs subvolume delete "/mnt/${cfg.subvolumePath}"
|
||
|
echo "restoring ${cfgWipe.subvolumePath} (root) subvolume..."
|
||
|
btrfs subvolume snapshot "/mnt/${cfgWipe.cleanSnapshotPath}"
|
||
|
"/mnt/${cfgWipe.subvolumePath}"
|
||
|
|
||
|
# Once we're done rolling back to a blank snapshot,
|
||
|
# we can unmount /mnt and continue on the boot process
|
||
|
umount /mnt
|
||
|
'';
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|