forked from jan-leila/nix-config
		
	
		
			
				
	
	
		
			462 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			462 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| {
 | |
|   lib,
 | |
|   config,
 | |
|   inputs,
 | |
|   ...
 | |
| }: let
 | |
|   SOPS_AGE_KEY_DIRECTORY = import ../../const/sops_age_key_directory.nix;
 | |
| 
 | |
|   host = config.host;
 | |
| 
 | |
|   principleUsers = host.principleUsers;
 | |
|   terminalUsers = host.terminalUsers;
 | |
|   normalUsers = host.normalUsers;
 | |
| 
 | |
|   uids = {
 | |
|     leyla = 1000;
 | |
|     eve = 1002;
 | |
|     ivy = 1004;
 | |
|     jellyfin = 2000;
 | |
|     forgejo = 2002;
 | |
|     hass = 2004;
 | |
|     syncthing = 2007;
 | |
|     ollama = 2008;
 | |
|     git = 2009;
 | |
|     immich = 2010;
 | |
|     qbittorrent = 2011;
 | |
|     paperless = 2012;
 | |
|     actual = 2013;
 | |
|     radarr = 2014;
 | |
|     sonarr = 2015;
 | |
|     bazarr = 2016;
 | |
|     lidarr = 2017;
 | |
|   };
 | |
| 
 | |
|   gids = {
 | |
|     leyla = 1000;
 | |
|     eve = 1002;
 | |
|     ivy = 1004;
 | |
|     users = 100;
 | |
|     jellyfin_media = 2001;
 | |
|     jellyfin = 2000;
 | |
|     forgejo = 2002;
 | |
|     hass = 2004;
 | |
|     syncthing = 2007;
 | |
|     ollama = 2008;
 | |
|     git = 2009;
 | |
|     immich = 2010;
 | |
|     qbittorrent = 2011;
 | |
|     paperless = 2012;
 | |
|     actual = 2013;
 | |
|     radarr = 2014;
 | |
|     sonarr = 2015;
 | |
|     bazarr = 2016;
 | |
|     lidarr = 2017;
 | |
|   };
 | |
| 
 | |
|   users = config.users.users;
 | |
|   leyla = users.leyla.name;
 | |
|   eve = users.eve.name;
 | |
|   ivy = users.ivy.name;
 | |
| in {
 | |
|   config = lib.mkMerge [
 | |
|     {
 | |
|       # principle users are by definition trusted
 | |
|       nix.settings.trusted-users = builtins.map (user: user.name) principleUsers;
 | |
| 
 | |
|       # we should only be able to ssh into principle users of a computer who are also set up for terminal access
 | |
|       services.openssh.settings.AllowUsers = builtins.map (user: user.name) (lib.lists.intersectLists terminalUsers principleUsers);
 | |
| 
 | |
|       # we need to set up env variables to nix can find keys to decrypt passwords on rebuild
 | |
|       environment = {
 | |
|         sessionVariables = {
 | |
|           SOPS_AGE_KEY_DIRECTORY = SOPS_AGE_KEY_DIRECTORY;
 | |
|           SOPS_AGE_KEY_FILE = "${SOPS_AGE_KEY_DIRECTORY}/key.txt";
 | |
|         };
 | |
|       };
 | |
| 
 | |
|       # set up user passwords
 | |
|       sops = {
 | |
|         defaultSopsFormat = "yaml";
 | |
|         gnupg.sshKeyPaths = [];
 | |
| 
 | |
|         age = {
 | |
|           keyFile = "/var/lib/sops-nix/key.txt";
 | |
|           sshKeyPaths = [];
 | |
|           # generateKey = true;
 | |
|         };
 | |
| 
 | |
|         secrets = {
 | |
|           "passwords/leyla" = {
 | |
|             neededForUsers = true;
 | |
|             sopsFile = "${inputs.secrets}/user-passwords.yaml";
 | |
|           };
 | |
|           "passwords/eve" = {
 | |
|             neededForUsers = true;
 | |
|             sopsFile = "${inputs.secrets}/user-passwords.yaml";
 | |
|           };
 | |
|           "passwords/ivy" = {
 | |
|             neededForUsers = true;
 | |
|             sopsFile = "${inputs.secrets}/user-passwords.yaml";
 | |
|           };
 | |
|         };
 | |
|       };
 | |
| 
 | |
|       users = {
 | |
|         mutableUsers = false;
 | |
|         users = {
 | |
|           leyla = {
 | |
|             uid = lib.mkForce uids.leyla;
 | |
|             name = lib.mkForce host.users.leyla.name;
 | |
|             description = "Leyla";
 | |
|             extraGroups =
 | |
|               (lib.lists.optionals host.users.leyla.isNormalUser ["networkmanager"])
 | |
|               ++ (lib.lists.optionals host.users.leyla.isPrincipleUser ["wheel" "dialout"])
 | |
|               ++ (lib.lists.optionals host.users.leyla.isDesktopUser ["adbusers"]);
 | |
|             hashedPasswordFile = config.sops.secrets."passwords/leyla".path;
 | |
|             isNormalUser = host.users.leyla.isNormalUser;
 | |
|             isSystemUser = !host.users.leyla.isNormalUser;
 | |
|             group = config.users.users.leyla.name;
 | |
|           };
 | |
| 
 | |
|           eve = {
 | |
|             uid = lib.mkForce uids.eve;
 | |
|             name = lib.mkForce host.users.eve.name;
 | |
|             description = "Eve";
 | |
|             extraGroups =
 | |
|               lib.optionals host.users.eve.isNormalUser ["networkmanager"]
 | |
|               ++ (lib.lists.optionals host.users.eve.isPrincipleUser ["wheel"]);
 | |
|             hashedPasswordFile = config.sops.secrets."passwords/eve".path;
 | |
|             isNormalUser = host.users.eve.isNormalUser;
 | |
|             isSystemUser = !host.users.eve.isNormalUser;
 | |
|             group = config.users.users.eve.name;
 | |
|           };
 | |
| 
 | |
|           ivy = {
 | |
|             uid = lib.mkForce uids.ivy;
 | |
|             name = lib.mkForce host.users.ivy.name;
 | |
|             description = "Ivy";
 | |
|             extraGroups =
 | |
|               lib.optionals host.users.ivy.isNormalUser ["networkmanager"]
 | |
|               ++ (lib.lists.optionals host.users.ivy.isPrincipleUser ["wheel"]);
 | |
|             hashedPasswordFile = config.sops.secrets."passwords/ivy".path;
 | |
|             isNormalUser = host.users.ivy.isNormalUser;
 | |
|             isSystemUser = !host.users.ivy.isNormalUser;
 | |
|             group = config.users.users.ivy.name;
 | |
|           };
 | |
| 
 | |
|           jellyfin = {
 | |
|             uid = lib.mkForce uids.jellyfin;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.jellyfin.name;
 | |
|           };
 | |
| 
 | |
|           forgejo = {
 | |
|             uid = lib.mkForce uids.forgejo;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.forgejo.name;
 | |
|           };
 | |
| 
 | |
|           hass = {
 | |
|             uid = lib.mkForce uids.hass;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.hass.name;
 | |
|           };
 | |
| 
 | |
|           syncthing = {
 | |
|             uid = lib.mkForce uids.syncthing;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.syncthing.name;
 | |
|           };
 | |
| 
 | |
|           ollama = {
 | |
|             uid = lib.mkForce uids.ollama;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.ollama.name;
 | |
|           };
 | |
| 
 | |
|           git = {
 | |
|             uid = lib.mkForce uids.git;
 | |
|             isSystemUser = !config.services.forgejo.enable;
 | |
|             isNormalUser = config.services.forgejo.enable;
 | |
|             group = config.users.users.git.name;
 | |
|           };
 | |
| 
 | |
|           immich = {
 | |
|             uid = lib.mkForce uids.immich;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.immich.name;
 | |
|           };
 | |
| 
 | |
|           qbittorrent = {
 | |
|             uid = lib.mkForce uids.qbittorrent;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.qbittorrent.name;
 | |
|           };
 | |
| 
 | |
|           paperless = {
 | |
|             uid = lib.mkForce uids.paperless;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.paperless.name;
 | |
|           };
 | |
| 
 | |
|           actual = {
 | |
|             uid = lib.mkForce uids.actual;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.actual.name;
 | |
|           };
 | |
| 
 | |
|           radarr = {
 | |
|             uid = lib.mkForce uids.radarr;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.radarr.name;
 | |
|           };
 | |
| 
 | |
|           sonarr = {
 | |
|             uid = lib.mkForce uids.sonarr;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.sonarr.name;
 | |
|           };
 | |
| 
 | |
|           bazarr = {
 | |
|             uid = lib.mkForce uids.bazarr;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.bazarr.name;
 | |
|           };
 | |
| 
 | |
|           lidarr = {
 | |
|             uid = lib.mkForce uids.lidarr;
 | |
|             isSystemUser = true;
 | |
|             group = config.users.users.lidarr.name;
 | |
|           };
 | |
|         };
 | |
| 
 | |
|         groups = {
 | |
|           leyla = {
 | |
|             gid = lib.mkForce gids.leyla;
 | |
|             members = [
 | |
|               leyla
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           eve = {
 | |
|             gid = lib.mkForce gids.eve;
 | |
|             members = [
 | |
|               eve
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           ivy = {
 | |
|             gid = lib.mkForce gids.ivy;
 | |
|             members = [
 | |
|               ivy
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           users = {
 | |
|             gid = lib.mkForce gids.users;
 | |
|             members = [
 | |
|               leyla
 | |
|               eve
 | |
|               ivy
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           jellyfin_media = {
 | |
|             gid = lib.mkForce gids.jellyfin_media;
 | |
|             members = [
 | |
|               users.jellyfin.name
 | |
|               users.radarr.name
 | |
|               users.sonarr.name
 | |
|               users.bazarr.name
 | |
|               users.lidarr.name
 | |
|               leyla
 | |
|               eve
 | |
|               ivy
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           jellyfin = {
 | |
|             gid = lib.mkForce gids.jellyfin;
 | |
|             members = [
 | |
|               users.jellyfin.name
 | |
|               # leyla
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           forgejo = {
 | |
|             gid = lib.mkForce gids.forgejo;
 | |
|             members = [
 | |
|               users.forgejo.name
 | |
|               # leyla
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           hass = {
 | |
|             gid = lib.mkForce gids.hass;
 | |
|             members = [
 | |
|               users.hass.name
 | |
|               # leyla
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           syncthing = {
 | |
|             gid = lib.mkForce gids.syncthing;
 | |
|             members = [
 | |
|               users.syncthing.name
 | |
|               leyla
 | |
|               eve
 | |
|               ivy
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           ollama = {
 | |
|             gid = lib.mkForce gids.ollama;
 | |
|             members = [
 | |
|               users.ollama.name
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           git = {
 | |
|             gid = lib.mkForce gids.git;
 | |
|             members = [
 | |
|               users.git.name
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           immich = {
 | |
|             gid = lib.mkForce gids.immich;
 | |
|             members = [
 | |
|               users.immich.name
 | |
|               # leyla
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           qbittorrent = {
 | |
|             gid = lib.mkForce gids.qbittorrent;
 | |
|             members = [
 | |
|               users.qbittorrent.name
 | |
|               leyla
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           paperless = {
 | |
|             gid = lib.mkForce gids.paperless;
 | |
|             members = [
 | |
|               users.paperless.name
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           actual = {
 | |
|             gid = lib.mkForce gids.actual;
 | |
|             members = [
 | |
|               users.actual.name
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           radarr = {
 | |
|             gid = lib.mkForce gids.radarr;
 | |
|             members = [
 | |
|               users.radarr.name
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           sonarr = {
 | |
|             gid = lib.mkForce gids.sonarr;
 | |
|             members = [
 | |
|               users.sonarr.name
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           bazarr = {
 | |
|             gid = lib.mkForce gids.bazarr;
 | |
|             members = [
 | |
|               users.bazarr.name
 | |
|             ];
 | |
|           };
 | |
| 
 | |
|           lidarr = {
 | |
|             gid = lib.mkForce gids.lidarr;
 | |
|             members = [
 | |
|               users.lidarr.name
 | |
|             ];
 | |
|           };
 | |
|         };
 | |
|       };
 | |
|     }
 | |
|     (lib.mkIf config.host.impermanence.enable {
 | |
|       boot.initrd.postResumeCommands = lib.mkAfter (
 | |
|         lib.strings.concatLines (builtins.map (user: "zfs rollback -r rpool/local/home/${user.name}@blank")
 | |
|           normalUsers)
 | |
|       );
 | |
| 
 | |
|       systemd = {
 | |
|         tmpfiles.rules =
 | |
|           builtins.map (
 | |
|             user: "d /persist/home/${user.name} 700 ${user.name} ${user.name} -"
 | |
|           )
 | |
|           normalUsers;
 | |
|       };
 | |
| 
 | |
|       fileSystems = lib.mkMerge [
 | |
|         {
 | |
|           ${SOPS_AGE_KEY_DIRECTORY}.neededForBoot = true;
 | |
|         }
 | |
|         (
 | |
|           builtins.listToAttrs (
 | |
|             builtins.map (user:
 | |
|               lib.attrsets.nameValuePair "/persist/home/${user.name}" {
 | |
|                 neededForBoot = true;
 | |
|               })
 | |
|             normalUsers
 | |
|           )
 | |
|         )
 | |
|         (
 | |
|           builtins.listToAttrs (
 | |
|             builtins.map (user:
 | |
|               lib.attrsets.nameValuePair "/home/${user.name}" {
 | |
|                 neededForBoot = true;
 | |
|               })
 | |
|             normalUsers
 | |
|           )
 | |
|         )
 | |
|       ];
 | |
| 
 | |
|       host.storage.pool.extraDatasets = lib.mkMerge (
 | |
|         [
 | |
|           {
 | |
|             # sops age key needs to be available to pre persist for user generation
 | |
|             "local/system/sops" = {
 | |
|               type = "zfs_fs";
 | |
|               mountpoint = SOPS_AGE_KEY_DIRECTORY;
 | |
|               options = {
 | |
|                 atime = "off";
 | |
|                 relatime = "off";
 | |
|                 canmount = "on";
 | |
|               };
 | |
|             };
 | |
|           }
 | |
|         ]
 | |
|         ++ (
 | |
|           builtins.map (user: {
 | |
|             "local/home/${user.name}" = {
 | |
|               type = "zfs_fs";
 | |
|               mountpoint = "/home/${user.name}";
 | |
|               options = {
 | |
|                 canmount = "on";
 | |
|               };
 | |
|               postCreateHook = ''
 | |
|                 zfs snapshot rpool/local/home/${user.name}@blank
 | |
|               '';
 | |
|             };
 | |
|             "persist/home/${user.name}" = {
 | |
|               type = "zfs_fs";
 | |
|               mountpoint = "/persist/home/${user.name}";
 | |
|             };
 | |
|           })
 | |
|           normalUsers
 | |
|         )
 | |
|       );
 | |
|     })
 | |
|   ];
 | |
| }
 |