353 lines
9.1 KiB
Nix
353 lines
9.1 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;
|
|
jellyfin = 2000;
|
|
forgejo = 2002;
|
|
adguardhome = 2003;
|
|
hass = 2004;
|
|
syncthing = 2007;
|
|
ollama = 2008;
|
|
git = 2009;
|
|
immich = 2010;
|
|
qbittorrent = 2011;
|
|
};
|
|
|
|
gids = {
|
|
leyla = 1000;
|
|
eve = 1002;
|
|
users = 100;
|
|
jellyfin_media = 2001;
|
|
jellyfin = 2000;
|
|
forgejo = 2002;
|
|
adguardhome = 2003;
|
|
hass = 2004;
|
|
syncthing = 2007;
|
|
ollama = 2008;
|
|
git = 2009;
|
|
immich = 2010;
|
|
qbittorrent = 2011;
|
|
};
|
|
|
|
users = config.users.users;
|
|
leyla = users.leyla.name;
|
|
eve = users.eve.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";
|
|
};
|
|
};
|
|
};
|
|
|
|
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"];
|
|
hashedPasswordFile = config.sops.secrets."passwords/eve".path;
|
|
isNormalUser = host.users.eve.isNormalUser;
|
|
isSystemUser = !host.users.eve.isNormalUser;
|
|
group = config.users.users.eve.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;
|
|
};
|
|
|
|
adguardhome = {
|
|
uid = lib.mkForce uids.adguardhome;
|
|
isSystemUser = true;
|
|
group = config.users.users.adguardhome.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;
|
|
isNormalUser = true;
|
|
group = config.users.users.qbittorrent.name;
|
|
};
|
|
};
|
|
|
|
groups = {
|
|
leyla = {
|
|
gid = lib.mkForce gids.leyla;
|
|
members = [
|
|
leyla
|
|
];
|
|
};
|
|
|
|
eve = {
|
|
gid = lib.mkForce gids.eve;
|
|
members = [
|
|
eve
|
|
];
|
|
};
|
|
|
|
users = {
|
|
gid = lib.mkForce gids.users;
|
|
members = [
|
|
leyla
|
|
eve
|
|
];
|
|
};
|
|
|
|
jellyfin_media = {
|
|
gid = lib.mkForce gids.jellyfin_media;
|
|
members = [
|
|
users.jellyfin.name
|
|
leyla
|
|
eve
|
|
];
|
|
};
|
|
|
|
jellyfin = {
|
|
gid = lib.mkForce gids.jellyfin;
|
|
members = [
|
|
users.jellyfin.name
|
|
# leyla
|
|
];
|
|
};
|
|
|
|
forgejo = {
|
|
gid = lib.mkForce gids.forgejo;
|
|
members = [
|
|
users.forgejo.name
|
|
# leyla
|
|
];
|
|
};
|
|
|
|
adguardhome = {
|
|
gid = lib.mkForce gids.adguardhome;
|
|
members = [
|
|
users.adguardhome.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
|
|
];
|
|
};
|
|
|
|
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
|
|
];
|
|
};
|
|
};
|
|
};
|
|
}
|
|
(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
|
|
)
|
|
);
|
|
})
|
|
];
|
|
}
|