From 003637f43527533855a4c84f6b2d5ac2e4a3f585 Mon Sep 17 00:00:00 2001 From: niten Date: Mon, 22 Nov 2021 10:17:44 -0800 Subject: [PATCH] Moving config stuff from ./lib into ./config --- config/default.nix | 4 ++ config/dns.nix | 69 ++++++++++++++++++++++++++++++ config/instance.nix | 56 ++++++++++++++++++++++++ config/kerberos.nix | 74 ++++++++++++++++++++++++++++++++ config/user-config.nix | 97 ++++++++++++++++++++++++++++++++++++++++++ config/users.nix | 5 +-- flake.lock | 87 +++++++++++++++++++++++++++++++++---- flake.nix | 77 ++++++++++++++------------------- initialize.nix | 1 - 9 files changed, 410 insertions(+), 60 deletions(-) create mode 100644 config/dns.nix create mode 100644 config/instance.nix create mode 100644 config/kerberos.nix create mode 100644 config/user-config.nix diff --git a/config/default.nix b/config/default.nix index a8a443a..169e985 100644 --- a/config/default.nix +++ b/config/default.nix @@ -7,11 +7,15 @@ ./client.nix ./common.nix ./domains.nix + ./dns.nix ./groups.nix ./hosts.nix + ./instance.nix + ./kerberos.nix ./networks.nix ./sites.nix ./users.nix + ./user-config.nix ./wireless-networks.nix ]; } diff --git a/config/dns.nix b/config/dns.nix new file mode 100644 index 0000000..bf84435 --- /dev/null +++ b/config/dns.nix @@ -0,0 +1,69 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + hostname = config.instance.hostname; + domain = config.instance.local-domain; + cfg = config.fudo.domains.${domain}; + + served-domain = cfg.primary-nameserver != null; + + is-primary = hostname == cfg.primary-nameserver; + + create-srv-record = port: hostname: { + port = port; + host = hostname; + }; + +in { + config = { + fudo.dns = mkIf is-primary (let + primary-ip = pkgs.lib.fudo.network.host-ipv4 config hostname; + all-ips = pkgs.lib.fudo.network.host-ips config hostname; + in { + enable = true; + identity = "${hostname}.${domain}"; + nameservers = { + ns1 = { + ipv4-address = primary-ip; + description = "Primary ${domain} nameserver"; + }; + }; + + # Deliberately leaving out localhost so the primary nameserver + # can use a custom recursor + listen-ips = all-ips; + + domains = { + ${domain} = { + dnssec = true; + default-host = primary-ip; + gssapi-realm = cfg.gssapi-realm; + mx = optional (cfg.primary-mailserver != null) + cfg.primary-mailserver; + # TODO: there's no guarantee this exists... + dmarc-report-address = "dmarc-report@${domain}"; + + network-definition = let + network = config.fudo.networks.${domain}; + in network // { + srv-records = { + tcp = { + domain = [{ + host = "ns1.${domain}"; + port = 53; + }]; + }; + udp = { + domain = [{ + host = "ns1.${domain}"; + port = 53; + }]; + }; + }; + }; + }; + }; + }); + }; +} diff --git a/config/instance.nix b/config/instance.nix new file mode 100644 index 0000000..0bdb6a7 --- /dev/null +++ b/config/instance.nix @@ -0,0 +1,56 @@ +{ config, lib, pkgs, ... }: + +with lib; +{ + config = let + local-host = config.instance.hostname; + local-domain = config.fudo.hosts.${local-host}.domain; + local-site = config.fudo.hosts.${local-host}.site; + + host = config.fudo.hosts.${local-host}; + + host-user-list = host.local-users; + domain-user-list = config.fudo.domains."${local-domain}".local-users; + site-user-list = config.fudo.sites."${local-site}".local-users; + local-users = + getAttrs (host-user-list ++ domain-user-list ++ site-user-list) config.fudo.users; + + host-admin-list = host.local-admins; + domain-admin-list = config.fudo.domains."${local-domain}".local-admins; + site-admin-list = config.fudo.sites."${local-site}".local-admins; + local-admins = host-admin-list ++ domain-admin-list ++ site-admin-list; + + host-group-list = host.local-groups; + domain-group-list = config.fudo.domains."${local-domain}".local-groups; + site-group-list = config.fudo.sites."${local-site}".local-groups; + local-groups = + getAttrs (host-group-list ++ domain-group-list ++ site-group-list) + config.fudo.groups; + + local-hosts = + filterAttrs (host: hostOpts: hostOpts.site == local-site) config.fudo.hosts; + + local-networks = + host.local-networks ++ + config.fudo.domains.${local-domain}.local-networks ++ + config.fudo.sites.${local-site}.local-networks; + + local-profile = host.profile; + + host-fqdn = "${config.instance.hostname}.${local-domain}"; + + in { + instance = { + inherit + host-fqdn + local-domain + local-site + local-users + local-admins + local-groups + local-hosts + local-profile + local-networks; + }; + }; +} diff --git a/config/kerberos.nix b/config/kerberos.nix new file mode 100644 index 0000000..f104c0a --- /dev/null +++ b/config/kerberos.nix @@ -0,0 +1,74 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + hostname = config.instance.hostname; + domain = config.instance.local-domain; + cfg = config.fudo.domains.${domain}; + +in { + config = let + hostname = config.instance.hostname; + is-master = hostname == cfg.kerberos-master; + is-slave = elem hostname cfg.kerberos-slaves; + + kerberized-domain = cfg.kerberos-master != null; + + in { + fudo = { + auth.kdc = mkIf (is-master || is-slave) { + enable = true; + realm = cfg.gssapi-realm; + # TODO: Also bind to ::1? + bind-addresses = + (pkgs.lib.fudo.network.host-ips config hostname) ++ + [ "127.0.0.1" ] ++ (optional config.networking.enableIPv6 "::1"); + master-config = mkIf is-master { + acl = let + admin-entries = genAttrs cfg.local-admins + (admin: { + perms = [ "add" "change-password" "list" ]; + }); + in admin-entries // { + "*/root" = { perms = [ "all" ]; }; + }; + }; + slave-config = mkIf is-slave { + master-host = cfg.kerberos-master; + # You gotta provide the keytab yourself, sorry... + }; + }; + + dns.domains.${domain} = { + network-definition = mkIf kerberized-domain { + srv-records = let + get-fqdn = hostname: + "${hostname}.${config.fudo.hosts.${hostname}.domain}"; + + create-srv-record = port: hostname: { + port = port; + host = hostname; + }; + + all-servers = map get-fqdn + ([cfg.kerberos-master] ++ cfg.kerberos-slaves); + + master-servers = + map get-fqdn [cfg.kerberos-master]; + + in { + tcp = { + kerberos = map (create-srv-record 88) all-servers; + kerberos-adm = map (create-srv-record 749) master-servers; + }; + udp = { + kerberos = map (create-srv-record 88) all-servers; + kerberos-master = map (create-srv-record 88) master-servers; + kpasswd = map (create-srv-record 464) master-servers; + }; + }; + }; + }; + }; + }; +} diff --git a/config/user-config.nix b/config/user-config.nix new file mode 100644 index 0000000..ff1dea2 --- /dev/null +++ b/config/user-config.nix @@ -0,0 +1,97 @@ +{ config, lib, pkgs, ... }: + +with lib; +{ + config = let + filterExistingUsers = users: group-members: + let user-list = attrNames users; + in filter (username: elem username user-list) + group-members; + + hostname = config.instance.hostname; + host-cfg = config.fudo.hosts.${hostname}; + in { + fudo.auth.ldap-server = { + users = filterAttrs + (username: userOpts: userOpts.ldap-hashed-passwd != null) + config.fudo.users; + + groups = config.fudo.groups; + + system-users = config.fudo.system-users; + }; + + programs.ssh.extraConfig = mkAfter '' + IdentityFile %h/.ssh/id_rsa + IdentityFile /etc/ssh/private_keys.d/%u.key + ''; + + environment.etc = mapAttrs' (username: userOpts: + nameValuePair + "ssh/private_keys.d/${username}" + { + text = concatStringsSep "\n" + (map (keypair: readFile keypair.public-key) + userOpts.ssh-keys); + }) + sys.local-users; + + users = { + users = mapAttrs (username: userOpts: { + isNormalUser = true; + uid = userOpts.uid; + createHome = true; + description = userOpts.common-name; + group = userOpts.primary-group; + home = if (userOpts.home-directory != null) then + userOpts.home-directory + else + "/home/${userOpts.primary-group}/${username}"; + hashedPassword = userOpts.login-hashed-passwd; + openssh.authorizedKeys.keys = userOpts.ssh-authorized-keys; + }) sys.local-users; + + groups = (mapAttrs (groupname: groupOpts: { + gid = groupOpts.gid; + members = filterExistingUsers sys.local-users groupOpts.members; + }) sys.local-groups) // { + wheel = { members = sys.local-admins; }; + docker = mkIf (host-cfg.docker-server) { members = sys.local-admins; }; + }; + }; + + services.nfs.idmapd.settings = let + local-domain = config.instance.local-domain; + local-admins = config.instance.local-admins; + local-users = config.instance.local-users; + local-realm = config.fudo.domains.${local-domain}.gssapi-realm; + in { + General = { + Verbosity = 10; + # Domain = local-domain; + "Local-Realms" = local-realm; + }; + Translation = { + GSS-Methods = "static"; + }; + Static = let + generate-admin-entry = admin: userOpts: + nameValuePair "${admin}/root@${local-realm}" "root"; + generate-user-entry = user: userOpts: + nameValuePair "${user}@${local-realm}" user; + + admin-entries = + mapAttrs' generate-admin-entry (getAttrs local-admins local-users); + user-entries = + mapAttrs' generate-user-entry local-users; + in admin-entries // user-entries; + }; + + # Group home directories have to exist, otherwise users can't log in + systemd.tmpfiles.rules = let + groups-with-members = attrNames + (filterAttrs (group: groupOpts: (length groupOpts.members) > 0) + sys.local-groups); + in map (group: "d /home/${group} 550 root ${group} - -") groups-with-members; + }; +} diff --git a/config/users.nix b/config/users.nix index 280f476..5dc00ea 100644 --- a/config/users.nix +++ b/config/users.nix @@ -1,9 +1,6 @@ { config, lib, pkgs, ... }: -let - # home-generator = pkgs.callPackage ../nix-home {}; - -in { +{ config.fudo.users = { niten = { uid = 10000; diff --git a/flake.lock b/flake.lock index 237dca0..e000f3f 100644 --- a/flake.lock +++ b/flake.lock @@ -46,9 +46,9 @@ "evil-org-mode": "evil-org-mode", "evil-quick-diff": "evil-quick-diff", "explain-pause-mode": "explain-pause-mode", - "flake-utils": "flake-utils", + "flake-utils": "flake-utils_2", "nix-straight": "nix-straight", - "nixpkgs": "nixpkgs", + "nixpkgs": "nixpkgs_2", "nose": "nose", "ob-racket": "ob-racket", "org": "org", @@ -214,6 +214,21 @@ } }, "flake-utils": { + "locked": { + "lastModified": 1637014545, + "narHash": "sha256-26IZAc5yzlD9FlDT54io1oqG/bBoyka+FJk5guaX4x4=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "bba5dcc8e0b20ab664967ad83d24d64cb64ec4f4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { "locked": { "lastModified": 1623875721, "narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=", @@ -228,12 +243,28 @@ "type": "github" } }, + "fudo-entities": { + "inputs": { + "flake-utils": "flake-utils", + "fudo-lib": "fudo-lib", + "nixpkgs": "nixpkgs" + }, + "locked": { + "narHash": "sha256-0hx0bItc00j8+Rnm0MDZ0EWhWpnVeaEBtnVP7Bzc0Rw=", + "path": "/state/fudo-entities", + "type": "path" + }, + "original": { + "path": "/state/fudo-entities", + "type": "path" + } + }, "fudo-home": { "inputs": { "doom-emacs": "doom-emacs", "home-manager": "home-manager", "niten-doom-config": "niten-doom-config", - "nixpkgs": "nixpkgs_2" + "nixpkgs": "nixpkgs_3" }, "locked": { "narHash": "sha256-TpFI+nD+c9JXhKKDBgIHJhIfveTScBD6gotTPt8tvg4=", @@ -245,6 +276,28 @@ "type": "path" } }, + "fudo-lib": { + "locked": { + "narHash": "sha256-Syzn7n7RzfbFFfE4luEEbcVo05Eq0eLed9QtCwXux1c=", + "path": "/state/fudo-lib", + "type": "path" + }, + "original": { + "path": "/state/fudo-lib", + "type": "path" + } + }, + "fudo-lib_2": { + "locked": { + "narHash": "sha256-Syzn7n7RzfbFFfE4luEEbcVo05Eq0eLed9QtCwXux1c=", + "path": "/state/fudo-lib", + "type": "path" + }, + "original": { + "path": "/state/fudo-lib", + "type": "path" + } + }, "fudo-pkgs": { "locked": { "narHash": "sha256-XwEs/VkqJp1mNwYUeBUqCPrW6GUEwAxbXMVOy7bF2P8=", @@ -346,6 +399,20 @@ } }, "nixpkgs": { + "locked": { + "lastModified": 1637600646, + "narHash": "sha256-Nr/+8/ySh2Ezis0lWEn8jqdRax8ZVHAA9IGV0m0NA9I=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4418f362e68c69226807a5837fcbfc94f0b92adb", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1626852498, "narHash": "sha256-lOXUJvi0FJUXHTVSiC5qsMRtEUgqM4mGZpMESLuGhmo=", @@ -360,7 +427,7 @@ "type": "indirect" } }, - "nixpkgs_2": { + "nixpkgs_3": { "locked": { "lastModified": 1636944046, "narHash": "sha256-74KLDsiWSBsYXKj/ql9EGbw1TbIJRE7clFkhl30HV/c=", @@ -375,13 +442,13 @@ "type": "indirect" } }, - "nixpkgs_3": { + "nixpkgs_4": { "locked": { - "lastModified": 1636944046, - "narHash": "sha256-74KLDsiWSBsYXKj/ql9EGbw1TbIJRE7clFkhl30HV/c=", + "lastModified": 1637448181, + "narHash": "sha256-ujcXli4esmtIHUBjE1BjmMuBWrcNvlHZrVXx56i5B1M=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "46251a79f752ae1d46ef733e8e9760b6d3429da4", + "rev": "d5b65f812cd4f5a8fa74b406075b59a46f1cfd98", "type": "github" }, "original": { @@ -516,10 +583,12 @@ }, "root": { "inputs": { + "fudo-entities": "fudo-entities", "fudo-home": "fudo-home", + "fudo-lib": "fudo-lib_2", "fudo-pkgs": "fudo-pkgs", "fudo-secrets": "fudo-secrets", - "nixpkgs": "nixpkgs_3" + "nixpkgs": "nixpkgs_4" } }, "rotate-text": { diff --git a/flake.nix b/flake.nix index 76e4308..82f019c 100644 --- a/flake.nix +++ b/flake.nix @@ -6,49 +6,48 @@ fudo-home.url = "path:/state/nixops/fudo-home"; + fudo-entities.url = "path:/state/fudo-entities"; + + fudo-lib.url = "path:/state/fudo-lib"; + fudo-pkgs.url = "path:/state/nixops/fudo-pkgs"; fudo-secrets.url = "path:/state/secrets"; }; - outputs = { self, nixpkgs, fudo-home, fudo-pkgs, fudo-secrets, ... }: + outputs = { self, + nixpkgs, + fudo-home, + fudo-lib, + fudo-entities, + fudo-pkgs, + fudo-secrets, + ... }: with nixpkgs.lib; let sys-lib = import ./lib/system.nix { lib = nixpkgs.lib; }; - fudo-nix-hosts = nixpkgs.lib.filterAttrs + fudo-nix-hosts = filterAttrs (hostname: hostOpts: hostOpts.nixos-system) - (sys-lib.hosts ./config/hosts); + (fudo-entities.entities.hosts); - fudo-networks = sys-lib.networks ./config/networks; - in { - fudoHosts = fudo-nix-hosts; + fudo-networks = fudo-entities.entities.networks; - fudoNetworks = fudo-networks; - - nixosModule = { - imports = [ - ./lib - ]; - }; - - nixosConfigurations = let - - build-timestamp = self.sourceInfo.lastModified; - - pkgs-for = arch: import nixpkgs { - system = arch; - config = { - allowUnfree = true; - permittedInsecurePackages = [ - "openssh-with-gssapi-8.4p1" - ]; - }; - overlays = [ - fudo-pkgs.overlay - (import ./lib/overlay.nix) + pkgs-for = arch: import nixpkgs { + system = arch; + config = { + allowUnfree = true; + permittedInsecurePackages = [ + "openssh-with-gssapi-8.4p1" ]; }; + overlays = [ + fudo-lib.overlay + fudo-pkgs.overlay + ]; + }; + in { + nixosConfigurations = let in mapAttrs (hostname: hostOpts: let system = hostOpts.arch; site = hostOpts.site; @@ -62,15 +61,13 @@ in [ fudo-home.nixosModule fudo-secrets.nixosModule + fudo-lib.nixosModule ({ config, ... }: let network-hosts = config.fudo.networks.${domain}.hosts; - host-filesystem-keys = - config.fudo.secrets.files.host-filesystem-keys; in { imports = [ - ./lib - ./config + fudo-entities.nixosModule (config-path + /hardware/${hostname}.nix) (config-path + /host-config/${hostname}.nix) (config-path + /profile-config/${profile}.nix) @@ -78,23 +75,11 @@ (config-path + /site-config/${site}.nix) ]; instance = { - inherit hostname build-timestamp; + inherit hostname; build-seed = builtins.readFile config.fudo.secrets.files.build-seed; }; nixpkgs.pkgs = pkgs-for system; - # deployment = { - # targetHost = - # network-hosts.${hostname}.ipv4-address; - - # keys = if (hasAttr hostname host-filesystem-keys) then - # mapAttrs (secret: secret-file: { - # keyFile = secret-file; - # user = "root"; - # permissions = "0400"; - # }) host-filesystem-keys.${hostname} - # else {}; - # }; }) ]; }) fudo-nix-hosts; diff --git a/initialize.nix b/initialize.nix index a45c3ee..f8e438c 100644 --- a/initialize.nix +++ b/initialize.nix @@ -6,7 +6,6 @@ let in { imports = [ - ./lib ./config ] ++ (filter pathExists [ (config-dir + /hardware/${hostname}.nix)