From 19d322f4064103d1a2bbe818c11ae235b4a41914 Mon Sep 17 00:00:00 2001 From: Jordan Holt Date: Sun, 11 Jan 2026 21:42:55 +0000 Subject: [PATCH] hosts/hypnos: rebuild --- ...01-Add-apple_set_os-EFI-boot-service.patch | 101 ---------------- hosts/hypnos/README.md | 18 ++- hosts/hypnos/default.nix | 99 ++++++++++++--- hosts/hypnos/disko-config.nix | 114 ++++++++---------- hosts/hypnos/hardware-configuration.nix | 6 - modules/nixos/deterministic-ids.nix | 100 +++++++++++++++ .../common/optional/graphical/awesome.nix | 10 ++ users/jordan/default.nix | 4 +- users/jordan/hypnos.nix | 2 +- 9 files changed, 257 insertions(+), 197 deletions(-) delete mode 100644 hosts/hypnos/0001-Add-apple_set_os-EFI-boot-service.patch create mode 100644 modules/nixos/deterministic-ids.nix create mode 100644 users/jordan/common/optional/graphical/awesome.nix diff --git a/hosts/hypnos/0001-Add-apple_set_os-EFI-boot-service.patch b/hosts/hypnos/0001-Add-apple_set_os-EFI-boot-service.patch deleted file mode 100644 index 4ae069d..0000000 --- a/hosts/hypnos/0001-Add-apple_set_os-EFI-boot-service.patch +++ /dev/null @@ -1,101 +0,0 @@ -From d310ddee0fb8e7a5a8b89668c6cb8f9dc863ce94 Mon Sep 17 00:00:00 2001 -From: Jordan Holt -Date: Sun, 28 Apr 2024 15:59:52 +0100 -Subject: [PATCH] Add apple_set_os EFI boot service - ---- - drivers/firmware/efi/libstub/x86-stub.c | 59 +++++++++++++++++++++++++ - include/linux/efi.h | 1 + - 2 files changed, 60 insertions(+) - -diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c -index d5a8182cf..be722c43a 100644 ---- a/drivers/firmware/efi/libstub/x86-stub.c -+++ b/drivers/firmware/efi/libstub/x86-stub.c -@@ -449,6 +449,63 @@ static void setup_graphics(struct boot_params *boot_params) - } - } - -+typedef struct { -+ u64 version; -+ void (*set_os_version) (const char *os_version); -+ void (*set_os_vendor) (const char *os_vendor); -+} apple_set_os_interface_t; -+ -+static efi_status_t apple_set_os() -+{ -+ apple_set_os_interface_t *set_os; -+ efi_guid_t set_os_guid = APPLE_SET_OS_PROTOCOL_GUID; -+ efi_status_t status; -+ void **handles; -+ unsigned long i, nr_handles, size = 0; -+ -+ status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL, -+ &set_os_guid, NULL, &size, handles); -+ -+ if (status == EFI_BUFFER_TOO_SMALL) { -+ status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, -+ size, &handles); -+ -+ if (status != EFI_SUCCESS) -+ return status; -+ -+ status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL, -+ &set_os_guid, NULL, &size, handles); -+ } -+ -+ if (status != EFI_SUCCESS) -+ goto free_handle; -+ -+ nr_handles = size / sizeof(void *); -+ for (i = 0; i < nr_handles; i++) { -+ void *h = handles[i]; -+ -+ status = efi_bs_call(handle_protocol, h, -+ &set_os_guid, &set_os); -+ -+ if (status != EFI_SUCCESS || !set_os) -+ continue; -+ -+ if (set_os->version > 0) { -+ efi_bs_call((unsigned long)set_os->set_os_version, -+ "Mac OS X 10.9"); -+ } -+ -+ if (set_os->version >= 2) { -+ efi_bs_call((unsigned long)set_os->set_os_vendor, -+ "Apple Inc."); -+ } -+ } -+ -+free_handle: -+ efi_bs_call(free_pool, uga_handle); -+ -+ return status; -+} - - static void __noreturn efi_exit(efi_handle_t handle, efi_status_t status) - { -@@ -951,6 +1008,8 @@ void __noreturn efi_stub_entry(efi_handle_t handle, - - setup_unaccepted_memory(); - -+ apple_set_os(); -+ - status = exit_boot(boot_params, handle); - if (status != EFI_SUCCESS) { - efi_err("exit_boot() failed!\n"); -diff --git a/include/linux/efi.h b/include/linux/efi.h -index d59b0947f..81158014f 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -385,6 +385,7 @@ void efi_native_runtime_setup(void); - #define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20) - #define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) - #define APPLE_PROPERTIES_PROTOCOL_GUID EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb, 0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0) -+#define APPLE_SET_OS_PROTOCOL_GUID EFI_GUID(0xc5c5da95, 0x7d5c, 0x45e6, 0xb2, 0xf1, 0x3f, 0xd5, 0x2b, 0xb1, 0x00, 0x77) - #define EFI_TCG2_PROTOCOL_GUID EFI_GUID(0x607f766c, 0x7455, 0x42be, 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f) - #define EFI_TCG2_FINAL_EVENTS_TABLE_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25) - #define EFI_LOAD_FILE_PROTOCOL_GUID EFI_GUID(0x56ec3091, 0x954c, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b) --- -2.42.0 diff --git a/hosts/hypnos/README.md b/hosts/hypnos/README.md index fa210d0..04b5f35 100644 --- a/hosts/hypnos/README.md +++ b/hosts/hypnos/README.md @@ -24,16 +24,24 @@ Apple SSD SM0512F | `/dev/sda1` (EFI, 256 MiB, NixOS Boot)
`/dev/sda2` (ZFS rpool/ ├── local │ ├── nix -│ └── tmp -├── system │ ├── root -│ └── var -└── user - └── home +│ └── state +└── safe + └── persist ``` See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets. +#### Impermanence + +This machine uses [impermanence](https://github.com/nix-community/impermanence) and is rolled back to a clean state on each reboot. + +Mountpoint | Persists across reboots? | Backed up? +--- | --- | --- +`/` | No | Yes +`/state` | Yes | No +`/persist` | Yes | Yes + ### Networks - DHCP on `10.0.1.0/24` subnet. diff --git a/hosts/hypnos/default.nix b/hosts/hypnos/default.nix index cbb7778..ca30000 100644 --- a/hosts/hypnos/default.nix +++ b/hosts/hypnos/default.nix @@ -4,50 +4,113 @@ pkgs, ... }: - +let + inherit (lib) + mkForce + ; +in { imports = [ inputs.disko.nixosModules.disko ./hardware-configuration.nix ./disko-config.nix ../desktop.nix + ../../modules/nixos/deterministic-ids.nix ../../users/jordan ]; nixpkgs = { hostPlatform = "x86_64-linux"; config = { - nvidia.acceptLicense = true; - permittedInsecurePackages = [ "broadcom-sta-6.30.223.271-57-6.12.41" ]; + permittedInsecurePackages = [ "broadcom-sta-6.30.223.271-59-6.12.63" ]; }; }; age.rekey.hostPubkey = ./ssh_host_ed25519_key.pub; - boot.loader = { - systemd-boot.enable = true; - efi.canTouchEfiVariables = true; + boot = { + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + initrd.systemd = { + enable = true; + extraBin.cryptsetup = "${pkgs.cryptsetup}/bin/cryptsetup"; + services."zfs-import-rpool".after = [ "cryptsetup.target" ]; + }; + tmp.useTmpfs = true; }; - networking.hostId = "cf791898"; + console.earlySetup = true; - # nvidia 470 driver doesn't work with Wayland - services = { - xserver = { - displayManager.gdm.wayland = lib.mkForce false; - videoDrivers = [ "nvidia" ]; - }; - displayManager = { - defaultSession = "gnome-xorg"; + systemd.network.enable = true; + systemd.network.wait-online.enable = false; + + networking = { + hostId = "cf791898"; + useNetworkd = true; + dhcpcd.enable = false; + firewall = { + enable = true; + allowedTCPPorts = [ + 22 # SSH + ]; }; }; + services.resolved = { + enable = true; + dnssec = "false"; + fallbackDns = [ + "9.9.9.9" + "2620:fe::fe" + "1.1.1.1" + "2606:4700:4700::1111" + ]; + llmnr = "false"; + extraConfig = '' + MulticastDNS=false + ''; + }; + # Workaround for label rendering bug in GTK4 with nvidia 470 driver environment.sessionVariables.GSK_RENDERER = "gl"; - environment.systemPackages = [ - pkgs.moonlight-qt - ]; + environment.persistence."/persist".enable = mkForce true; + environment.persistence."/state".enable = mkForce true; + + modules = { + system.desktop.gnome.enable = mkForce false; + }; + + services.openssh.settings.PermitRootLogin = mkForce "prohibit-password"; + + users = { + users = { + root = { + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com" + ]; + }; + }; + }; + + users.deterministicIds = + let + uidGid = id: { + uid = id; + gid = id; + }; + in + { + systemd-oom = uidGid 999; + systemd-coredump = uidGid 998; + sshd = uidGid 997; + nscd = uidGid 996; + polkituser = uidGid 995; + rtkit = uidGid 994; + lpadmin = uidGid 993; + }; system.stateVersion = "22.11"; } diff --git a/hosts/hypnos/disko-config.nix b/hosts/hypnos/disko-config.nix index a592901..a84e899 100644 --- a/hosts/hypnos/disko-config.nix +++ b/hosts/hypnos/disko-config.nix @@ -8,20 +8,32 @@ content = { type = "gpt"; partitions = { - ESP = { + efi = { size = "256M"; - type = "EF00"; + type = "ef00"; content = { type = "filesystem"; format = "vfat"; mountpoint = "/boot"; }; }; - zfs = { + swap = { + size = "8G"; + content = { + type = "swap"; + randomEncryption = true; + }; + }; + rpool = { size = "100%"; content = { - type = "zfs"; - pool = "rpool"; + type = "luks"; + name = "rpool_ata-APPLE_SSD_SM0512F_S1K5NYBF736152"; + settings.allowDiscards = true; + content = { + type = "zfs"; + pool = "rpool"; + }; }; }; }; @@ -35,87 +47,59 @@ ashift = "12"; }; rootFsOptions = { - canmount = "off"; - mountpoint = "none"; - dnodesize = "auto"; + compression = "zstd"; + acltype = "posix"; + atime = "off"; xattr = "sa"; + dnodesize = "auto"; + mountpoint = "none"; + canmount = "off"; + devices = "off"; + exec = "off"; + setuid = "off"; }; - postCreateHook = "zfs snapshot rpool@blank"; datasets = { - local = { + "local" = { type = "zfs_fs"; + }; + "local/root" = { + type = "zfs_fs"; + mountpoint = "/"; options = { - mountpoint = "none"; + canmount = "noauto"; + mountpoint = "/"; + exec = "on"; + setuid = "on"; }; + postCreateHook = "zfs snapshot rpool/local/root@blank"; }; "local/nix" = { type = "zfs_fs"; mountpoint = "/nix"; options = { - atime = "off"; - mountpoint = "legacy"; + canmount = "noauto"; + mountpoint = "/nix"; + exec = "on"; + setuid = "on"; }; }; - "local/tmp" = { + "local/state" = { type = "zfs_fs"; - mountpoint = "/tmp"; + mountpoint = "/state"; options = { - setuid = "off"; - devices = "off"; - mountpoint = "legacy"; + canmount = "noauto"; + mountpoint = "/state"; }; }; - system = { + "safe" = { type = "zfs_fs"; - mountpoint = "/"; - options = { - mountpoint = "legacy"; - }; }; - "system/var" = { + "safe/persist" = { type = "zfs_fs"; - mountpoint = "/var"; + mountpoint = "/persist"; options = { - mountpoint = "legacy"; - }; - }; - "system/var/tmp" = { - type = "zfs_fs"; - mountpoint = "/var/tmp"; - options = { - devices = "off"; - mountpoint = "legacy"; - }; - }; - "system/var/log" = { - type = "zfs_fs"; - mountpoint = "/var/log"; - options = { - compression = "on"; - acltype = "posix"; - mountpoint = "legacy"; - }; - }; - user = { - type = "zfs_fs"; - options = { - mountpoint = "none"; - encryption = "aes-256-gcm"; - keyformat = "passphrase"; - keylocation = "file:///tmp/secret.key"; - }; - # use this to read the key during boot - postCreateHook = '' - zfs set keylocation="prompt" "rpool/$name"; - ''; - }; - "user/home" = { - type = "zfs_fs"; - mountpoint = "/home"; - options = { - setuid = "off"; - devices = "off"; - mountpoint = "legacy"; + canmount = "noauto"; + mountpoint = "/persist"; }; }; }; diff --git a/hosts/hypnos/hardware-configuration.nix b/hosts/hypnos/hardware-configuration.nix index 6a9ba16..caed7ac 100644 --- a/hosts/hypnos/hardware-configuration.nix +++ b/hosts/hypnos/hardware-configuration.nix @@ -30,7 +30,6 @@ ]; extraModulePackages = [ config.boot.kernelPackages.broadcom_sta - config.boot.kernelPackages.nvidiaPackages.legacy_470 ]; }; @@ -40,11 +39,6 @@ hardware = { cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; - nvidia = { - package = config.boot.kernelPackages.nvidiaPackages.legacy_470; - modesetting.enable = true; - powerManagement.enable = true; - }; graphics = { enable = true; extraPackages = with pkgs; [ diff --git a/modules/nixos/deterministic-ids.nix b/modules/nixos/deterministic-ids.nix new file mode 100644 index 0000000..6c23f32 --- /dev/null +++ b/modules/nixos/deterministic-ids.nix @@ -0,0 +1,100 @@ +{ + lib, + config, + ... +}: +let + inherit (lib) + concatLists + flip + mapAttrsToList + mkDefault + mkIf + mkOption + types + ; + + cfg = config.users.deterministicIds; +in +{ + options = { + users.deterministicIds = mkOption { + default = { }; + description = '' + Maps a user or group name to its expected uid/gid values. If a user/group is + used on the system without specifying a uid/gid, this module will assign the + corresponding ids defined here, or show an error if the definition is missing. + ''; + type = types.attrsOf ( + types.submodule { + options = { + uid = mkOption { + type = types.nullOr types.int; + default = null; + description = "The uid to assign if it is missing in `users.users.`."; + }; + gid = mkOption { + type = types.nullOr types.int; + default = null; + description = "The gid to assign if it is missing in `users.groups.`."; + }; + }; + } + ); + }; + + users.users = mkOption { + type = types.attrsOf ( + types.submodule ( + { name, ... }: + { + config.uid = + let + deterministicUid = cfg.${name}.uid or null; + in + mkIf (deterministicUid != null) (mkDefault deterministicUid); + } + ) + ); + }; + + users.groups = mkOption { + type = types.attrsOf ( + types.submodule ( + { name, ... }: + { + config.gid = + let + deterministicGid = cfg.${name}.gid or null; + in + mkIf (deterministicGid != null) (mkDefault deterministicGid); + } + ) + ); + }; + }; + + config = { + assertions = + concatLists ( + flip mapAttrsToList config.users.users ( + name: user: [ + { + assertion = user.uid != null; + message = "non-deterministic uid detected for '${name}', please assign one via `users.deterministicIds`"; + } + { + assertion = !user.autoSubUidGidRange; + message = "non-deterministic subUids/subGids detected for: ${name}"; + } + ] + ) + ) + ++ flip mapAttrsToList config.users.groups ( + name: group: { + assertion = group.gid != null; + message = "non-deterministic gid detected for '${name}', please assign one via `users.deterministicIds`"; + } + ); + }; +} diff --git a/users/jordan/common/optional/graphical/awesome.nix b/users/jordan/common/optional/graphical/awesome.nix new file mode 100644 index 0000000..846c27e --- /dev/null +++ b/users/jordan/common/optional/graphical/awesome.nix @@ -0,0 +1,10 @@ +{ + ... +}: + +{ + xsession = { + enable = true; + windowManager.awesome.enable = true; + }; +} diff --git a/users/jordan/default.nix b/users/jordan/default.nix index a6c6ecc..aba5496 100644 --- a/users/jordan/default.nix +++ b/users/jordan/default.nix @@ -47,7 +47,9 @@ in ]; shell = pkgs.zsh; uid = 1000; - }; + createHome = true; + } + // lib.optionalAttrs (!config.users.mutableUsers) { autoSubUidGidRange = false; }; home-manager.users.${name} = { imports = [ diff --git a/users/jordan/hypnos.nix b/users/jordan/hypnos.nix index 01e884c..43e8066 100644 --- a/users/jordan/hypnos.nix +++ b/users/jordan/hypnos.nix @@ -5,9 +5,9 @@ { imports = [ + ./common/optional/graphical/awesome.nix ./common/optional/graphical/firefox.nix ./common/optional/graphical/fonts.nix - ./common/optional/graphical/gnome.nix ]; home.packages = with pkgs; [