mirror of
https://github.com/ItsDrike/nixdots
synced 2025-06-29 12:40:42 +00:00
Group shared system settings
This commit is contained in:
parent
31221a5d19
commit
fca6296841
35 changed files with 16 additions and 11 deletions
72
system/shared/impermanence/autowipe.nix
Normal file
72
system/shared/impermanence/autowipe.nix
Normal file
|
@ -0,0 +1,72 @@
|
|||
{ config, lib, ... }: let
|
||||
inherit (lib) mkIf concatStringsSep flatten mapAttrsToList;
|
||||
cfg = config.myOptions.system.impermanence.autoWipeBtrfs;
|
||||
in
|
||||
{
|
||||
config = mkIf cfg.enable {
|
||||
boot.initrd.systemd = {
|
||||
enable = true; # This enables systemd support in stage 1 - required for below setup
|
||||
|
||||
services.rollback = {
|
||||
description = "Rollback BTRFS subvolumes to a pristine state";
|
||||
enable = true;
|
||||
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 = let
|
||||
# TODO: Consider adding support for moving the subvolume to something like old-roots
|
||||
# instead of deleting it. This would allow for easier recovery in case of a mistake.
|
||||
# The subvolume can live here for a certain amount of time, before it's deleted, or there
|
||||
# can be a certain amount of total roots kept. See the example configuration here:
|
||||
# <https://github.com/nix-community/impermanence> which demonstrates keepping 30 days
|
||||
# worth of old roots.
|
||||
wipeScript = devicePath: subvolumes: ''
|
||||
# Mount the BTRFS device root to a temporary mount point
|
||||
echo "Mounting BTRFS root from ${devicePath} to /mnt"
|
||||
mount --mkdir "${devicePath}" /mnt
|
||||
|
||||
# Recreate each specified subvolume
|
||||
${concatStringsSep "\n" (map (subvolume: ''
|
||||
delete_subvolume_recursively "/mnt/${subvolume}"
|
||||
btrfs subvolume create "/mnt/${subvolume}"
|
||||
'') subvolumes)}
|
||||
|
||||
# Cleanup: unmount the device
|
||||
echo "Unmounting BTRFS root from ${devicePath}"
|
||||
umount /mnt
|
||||
'';
|
||||
in ''
|
||||
# Simply deleting a subvolume with btrfs subvolume delete will not work,
|
||||
# if that subvolume contains other btrfs subvolumes. Because of that, we
|
||||
# instead use this function to delete subvolumes, whihc will first perform
|
||||
# a recursive deletion of any nested subvolumes.
|
||||
#
|
||||
# This is necessary, because the root subvolume will actually usually contain
|
||||
# other subvolumes, even if the user haven't created those explicitly. It seems
|
||||
# that NixOS creates these automatically. Namely, I observed these in root subvol:
|
||||
# - root/srv
|
||||
# - root/var/lib/portables
|
||||
# - root/var/lib/machines
|
||||
# - root/var/tmp
|
||||
delete_subvolume_recursively() {
|
||||
IFS=$'\n'
|
||||
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
|
||||
delete_subvolume_recursively "/mnt/$i"
|
||||
done
|
||||
|
||||
echo "Deleting subvolume $1"
|
||||
btrfs subvolume delete "$1"
|
||||
}
|
||||
|
||||
${concatStringsSep "\n" (mapAttrsToList (devicePath: deviceOpts:
|
||||
wipeScript devicePath deviceOpts.subvolumes
|
||||
) cfg.devices)}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
7
system/shared/impermanence/default.nix
Normal file
7
system/shared/impermanence/default.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
./root.nix
|
||||
./autowipe.nix
|
||||
];
|
||||
}
|
66
system/shared/impermanence/root.nix
Normal file
66
system/shared/impermanence/root.nix
Normal file
|
@ -0,0 +1,66 @@
|
|||
{ config, lib, ... }: let
|
||||
inherit (lib) mkIf mkForce;
|
||||
|
||||
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";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue