diff --git a/lib/fudo/client/dns.nix b/lib/fudo/client/dns.nix index 68adf81..cdd5a5c 100644 --- a/lib/fudo/client/dns.nix +++ b/lib/fudo/client/dns.nix @@ -80,11 +80,7 @@ in { }; }; - groups = { - "${cfg.user}" = { - members = [ cfg.user ]; - }; - }; + groups = { "${cfg.user}" = { members = [ cfg.user ]; }; }; }; systemd = { @@ -104,7 +100,7 @@ in { services.backplane-dns-client-pw-file = { enable = true; - requiredBy = [ "backplane-dns-client.services" ]; + requiredBy = [ "backplane-dns-client.service" ]; reloadIfChanged = true; serviceConfig = { Type = "oneshot"; }; script = '' diff --git a/lib/fudo/prometheus.nix b/lib/fudo/prometheus.nix index 87aabd8..dbecdc0 100644 --- a/lib/fudo/prometheus.nix +++ b/lib/fudo/prometheus.nix @@ -8,6 +8,13 @@ in { options.fudo.metrics.prometheus = with types; { enable = mkEnableOption "Fudo Prometheus Data-Gathering Server"; + package = mkOption { + type = package; + default = pkgs.prometheus; + defaultText = literalExpression "pkgs.prometheus"; + description = "The prometheus package that should be used."; + }; + service-discovery-dns = mkOption { type = attrsOf (listOf str); description = '' @@ -119,9 +126,10 @@ in { services.prometheus = { enable = true; - webExternalUrl = "https://${cfg.hostname}"; + package = cfg.package; + listenAddress = "127.0.0.1"; port = 9090; @@ -131,14 +139,14 @@ in { honor_labels = false; scheme = if cfg.private-network then "http" else "https"; metrics_path = "/metrics/${type}"; - dns_sd_configs = if (hasAttr type cfg.service-discovery-dns) then [{ - names = cfg.service-discovery-dns.${type}; - }] else - [ ]; static_configs = if (hasAttr type cfg.static-targets) then [{ targets = cfg.static-targets.${type}; }] else [ ]; + dns_sd_configs = if (hasAttr type cfg.service-discovery-dns) then [{ + names = cfg.service-discovery-dns.${type}; + }] else + [ ]; }; in map make-job [ "docker" "node" "dovecot" "postfix" "rspamd" ]; diff --git a/lib/fudo/system.nix b/lib/fudo/system.nix index e1a037e..c371460 100644 --- a/lib/fudo/system.nix +++ b/lib/fudo/system.nix @@ -431,12 +431,12 @@ in { SecureBits = mkIf ((length opts.requiredCapabilities) > 0) "keep-caps"; DynamicUser = mkIf (opts.user == null) opts.dynamicUser; + Restart = opts.restartWhen; WorkingDirectory = mkIf (opts.workingDirectory != null) opts.workingDirectory; - RestrictAddressFamilies = - optionals (opts.addressFamilies != null) - (restrict-address-families opts.addressFamilies); + RestrictAddressFamilies = optionals (opts.addressFamilies != null) + (restrict-address-families opts.addressFamilies); RestrictNamespaces = opts.restrictNamespaces; User = mkIf (opts.user != null) opts.user; Group = mkIf (opts.group != null) opts.group; diff --git a/lib/types/host.nix b/lib/types/host.nix index fb3cfef..7a84dea 100644 --- a/lib/types/host.nix +++ b/lib/types/host.nix @@ -1,350 +1,360 @@ { lib, ... }: with lib; -let - passwd = import ../passwd.nix { inherit lib; }; +let passwd = import ../passwd.nix { inherit lib; }; in rec { - encryptedFSOpts = { ... }: let - mountpoint = { mp, ... }: { + encryptedFSOpts = { ... }: + let + mountpoint = { mp, ... }: { + options = with types; { + mountpoint = mkOption { + type = str; + description = "Path at which to mount the filesystem."; + default = mp; + }; + + options = mkOption { + type = listOf str; + description = + "List of filesystem options specific to this mountpoint (eg: subvol)."; + }; + + group = mkOption { + type = nullOr str; + description = "Group to which the mountpoint should belong."; + default = null; + }; + + users = mkOption { + type = listOf str; + description = '' + List of users who should have access to the filesystem. + + Requires a group to be set. + ''; + default = [ ]; + }; + + world-readable = mkOption { + type = bool; + description = "Whether to leave the top level world-readable."; + default = true; + }; + }; + }; + in { options = with types; { - mountpoint = mkOption { + encrypted-device = mkOption { type = str; - description = "Path at which to mount the filesystem."; - default = mp; + description = "Path to the encrypted device."; + }; + + key-path = mkOption { + type = str; + description = '' + Path at which to locate the key file. + + The filesystem will be decrypted and mounted once available."; + ''; + }; + + filesystem-type = mkOption { + type = str; + description = "Filesystem type of the decrypted filesystem."; }; options = mkOption { type = listOf str; - description = "List of filesystem options specific to this mountpoint (eg: subvol)."; + description = "List of filesystem options with which to mount."; }; - group = mkOption { - type = nullOr str; - description = "Group to which the mountpoint should belong."; - default = null; - }; - - users = mkOption { - type = listOf str; - description = '' - List of users who should have access to the filesystem. - - Requires a group to be set. - ''; - default = [ ]; - }; - - world-readable = mkOption { - type = bool; - description = "Whether to leave the top level world-readable."; - default = true; + mountpoints = mkOption { + type = attrsOf (submodule mountpoint); + description = + "A map of mountpoints for this filesystem to fs options. Multiple to support btrfs."; + default = { }; }; }; }; - in { - options = with types; { - encrypted-device = mkOption { - type = str; - description = "Path to the encrypted device."; - }; - - key-path = mkOption { - type = str; - description = '' - Path at which to locate the key file. - - The filesystem will be decrypted and mounted once available."; - ''; - }; - - filesystem-type = mkOption { - type = str; - description = "Filesystem type of the decrypted filesystem."; - }; - - options = mkOption { - type = listOf str; - description = "List of filesystem options with which to mount."; - }; - - mountpoints = mkOption { - type = attrsOf (submodule mountpoint); - description = "A map of mountpoints for this filesystem to fs options. Multiple to support btrfs."; - default = {}; - }; - }; - }; masterKeyOpts = { ... }: { options = with types; { key-path = mkOption { type = str; - description = "Path of the host master key file, used to decrypt secrets."; + description = + "Path of the host master key file, used to decrypt secrets."; }; public-key = mkOption { type = str; - description = "Public key used during deployment to decrypt secrets for the host."; + description = + "Public key used during deployment to decrypt secrets for the host."; }; }; }; - hostOpts = { name, ... }: let - hostname = name; - in { - options = with types; { - master-key = mkOption { - type = nullOr (submodule masterKeyOpts); - description = "Public key for the host master key, used by the host to decrypt secrets."; - }; - - domain = mkOption { - type = str; - description = - "Primary domain to which the host belongs, in the form of a domain name."; - default = "fudo.org"; - }; - - extra-domains = mkOption { - type = listOf str; - description = "Extra domain in which this host is reachable."; - default = [ ]; - }; - - aliases = mkOption { - type = listOf str; - description = - "Host aliases used by the current host. Note this will be multiplied with extra-domains."; - default = [ ]; - }; - - site = mkOption { - type = str; - description = "Site at which the host is located."; - default = "unsited"; - }; - - local-networks = mkOption { - type = listOf str; - description = - "A list of networks to be considered trusted by this host."; - default = [ "127.0.0.0/8" ]; - }; - - profile = mkOption { - type = listOf (enum ["desktop" "server" "laptop"]); - description = - "The profile to be applied to the host, determining what software is included."; - }; - - admin-email = mkOption { - type = nullOr str; - description = "Email for the administrator of this host."; - default = null; - }; - - local-users = mkOption { - type = listOf str; - description = - "List of users who should have local (i.e. login) access to the host."; - default = [ ]; - }; - - description = mkOption { - type = str; - description = "Description of this host."; - default = "Another Fudo Host."; - }; - - local-admins = mkOption { - type = listOf str; - description = - "A list of users who should have admin access to this host."; - default = [ ]; - }; - - local-groups = mkOption { - type = listOf str; - description = "List of groups which should exist on this host."; - default = [ ]; - }; - - ssh-fingerprints = mkOption { - type = listOf str; - description = '' - A list of DNS SSHFP records for this host. Get with `ssh-keygen -r ` - ''; - default = [ ]; - }; - - rp = mkOption { - type = nullOr str; - description = "Responsible person."; - default = null; - }; - - tmp-on-tmpfs = mkOption { - type = bool; - description = - "Use tmpfs for /tmp. Great if you've got enough (>16G) RAM."; - default = true; - }; - - enable-gui = mkEnableOption "Install desktop GUI software."; - - docker-server = mkEnableOption "Enable Docker on the current host."; - - kerberos-services = mkOption { - type = listOf str; - description = - "List of services which should exist for this host, if it belongs to a realm."; - default = [ "ssh" "host" ]; - }; - - ssh-pubkeys = mkOption { - type = listOf path; - description = - "SSH key files of the host."; - default = []; - }; - - build-pubkeys = mkOption { - type = listOf str; - description = "SSH public keys used to access the build server."; - default = [ ]; - }; - - external-interfaces = mkOption { - type = listOf str; - description = "A list of interfaces on which to enable the firewall."; - default = [ ]; - }; - - keytab-secret-file = mkOption { - type = nullOr str; - description = "Keytab from which to create a keytab secret."; - default = null; - }; - - keep-cool = mkOption { - type = bool; - description = "A host that tends to overheat. Try to keep it cooler."; - default = false; - }; - - nixos-system = mkOption { - type = bool; - description = "Whether the host is a NixOS system."; - default = true; - }; - - arch = mkOption { - type = str; - description = "System architecture of the system."; - }; - - machine-id = mkOption { - type = nullOr str; - description = "Machine id of the system. See: man machine-id."; - default = null; - }; - - android-dev = mkEnableOption "Enable ADB on the host."; - - encrypted-filesystems = mkOption { - type = attrsOf (submodule encryptedFSOpts); - description = "List of encrypted filesystems to mount on the local host when the key is available."; - default = { }; - }; - - hardened = mkOption { - type = bool; - description = "Harden the host, applying additional security."; - default = false; - }; - - wireguard = let - clientOpts = { - options = { - ip = mkOption { - type = nullOr str; - description = "IP address assigned to this host in the WireGuard network."; - }; - - bound = mkOption { - type = bool; - description = "Whether to route all traffic from this host."; - default = false; - }; - }; + hostOpts = { name, ... }: + let hostname = name; + in { + options = with types; { + master-key = mkOption { + type = nullOr (submodule masterKeyOpts); + description = + "Public key for the host master key, used by the host to decrypt secrets."; }; - wireguardOpts = { - options = { - private-key-file = mkOption { - type = str; - description = "WireGuard private key file of the host."; - }; - - public-key = mkOption { - type = str; - description = "WireGuard public key."; - }; - - client = mkOption { - type = nullOr (submodule clientOpts); - default = null; - }; - }; - }; - in mkOption { - type = nullOr (submodule wireguardOpts); - default = null; - }; - - initrd-network = let - keypair-type = { ... }: { - options = { - public-key = mkOption { - type = str; - description = "SSH public key."; - }; - - private-key-file = mkOption { - type = str; - description = "Path to SSH private key (on the local host!)."; - }; - }; + domain = mkOption { + type = str; + description = + "Primary domain to which the host belongs, in the form of a domain name."; + default = "fudo.org"; }; - initrd-network-config = { ... }: { - options = { - ip = mkOption { - type = str; - description = "IP to assign to the initrd image, allowing access to host during bootup."; - }; - keypair = mkOption { - type = (submodule keypair-type); - description = "SSH host key pair to use for initrd."; - }; - interface = mkOption { - type = str; - description = "Name of interface on which to listen for connections."; - }; - }; + extra-domains = mkOption { + type = listOf str; + description = "Extra domain in which this host is reachable."; + default = [ ]; }; - in mkOption { - type = nullOr (submodule initrd-network-config); - description = "Configuration parameters to set up initrd SSH network."; - default = null; - }; + aliases = mkOption { + type = listOf str; + description = + "Host aliases used by the current host. Note this will be multiplied with extra-domains."; + default = [ ]; + }; - backplane-password-file = mkOption { - options = path; - description = "File containing the password used by this host to connect to the backplane."; + site = mkOption { + type = str; + description = "Site at which the host is located."; + default = "unsited"; + }; + + local-networks = mkOption { + type = listOf str; + description = + "A list of networks to be considered trusted by this host."; + default = [ "127.0.0.0/8" ]; + }; + + profile = mkOption { + type = listOf (enum [ "desktop" "server" "laptop" ]); + description = + "The profile to be applied to the host, determining what software is included."; + }; + + admin-email = mkOption { + type = nullOr str; + description = "Email for the administrator of this host."; + default = null; + }; + + local-users = mkOption { + type = listOf str; + description = + "List of users who should have local (i.e. login) access to the host."; + default = [ ]; + }; + + description = mkOption { + type = str; + description = "Description of this host."; + default = "Another Fudo Host."; + }; + + local-admins = mkOption { + type = listOf str; + description = + "A list of users who should have admin access to this host."; + default = [ ]; + }; + + local-groups = mkOption { + type = listOf str; + description = "List of groups which should exist on this host."; + default = [ ]; + }; + + ssh-fingerprints = mkOption { + type = listOf str; + description = '' + A list of DNS SSHFP records for this host. Get with `ssh-keygen -r ` + ''; + default = [ ]; + }; + + rp = mkOption { + type = nullOr str; + description = "Responsible person."; + default = null; + }; + + tmp-on-tmpfs = mkOption { + type = bool; + description = + "Use tmpfs for /tmp. Great if you've got enough (>16G) RAM."; + default = true; + }; + + enable-gui = mkEnableOption "Install desktop GUI software."; + + docker-server = mkEnableOption "Enable Docker on the current host."; + + kerberos-services = mkOption { + type = listOf str; + description = + "List of services which should exist for this host, if it belongs to a realm."; + default = [ "ssh" "host" ]; + }; + + ssh-pubkeys = mkOption { + type = listOf path; + description = "SSH key files of the host."; + default = [ ]; + }; + + build-pubkeys = mkOption { + type = listOf str; + description = "SSH public keys used to access the build server."; + default = [ ]; + }; + + external-interfaces = mkOption { + type = listOf str; + description = "A list of interfaces on which to enable the firewall."; + default = [ ]; + }; + + keytab-secret-file = mkOption { + type = nullOr str; + description = "Keytab from which to create a keytab secret."; + default = null; + }; + + keep-cool = mkOption { + type = bool; + description = "A host that tends to overheat. Try to keep it cooler."; + default = false; + }; + + nixos-system = mkOption { + type = bool; + description = "Whether the host is a NixOS system."; + default = true; + }; + + arch = mkOption { + type = str; + description = "System architecture of the system."; + }; + + machine-id = mkOption { + type = nullOr str; + description = "Machine id of the system. See: man machine-id."; + default = null; + }; + + android-dev = mkEnableOption "Enable ADB on the host."; + + encrypted-filesystems = mkOption { + type = attrsOf (submodule encryptedFSOpts); + description = + "List of encrypted filesystems to mount on the local host when the key is available."; + default = { }; + }; + + hardened = mkOption { + type = bool; + description = "Harden the host, applying additional security."; + default = false; + }; + + wireguard = let + clientOpts = { + options = { + ip = mkOption { + type = nullOr str; + description = + "IP address assigned to this host in the WireGuard network."; + }; + + bound = mkOption { + type = bool; + description = "Whether to route all traffic from this host."; + default = false; + }; + }; + }; + + wireguardOpts = { + options = { + private-key-file = mkOption { + type = str; + description = "WireGuard private key file of the host."; + }; + + public-key = mkOption { + type = str; + description = "WireGuard public key."; + }; + + client = mkOption { + type = nullOr (submodule clientOpts); + default = null; + }; + }; + }; + in mkOption { + type = nullOr (submodule wireguardOpts); + default = null; + }; + + initrd-network = let + keypair-type = { ... }: { + options = { + public-key = mkOption { + type = str; + description = "SSH public key."; + }; + + private-key-file = mkOption { + type = str; + description = "Path to SSH private key (on the local host!)."; + }; + }; + }; + + initrd-network-config = { ... }: { + options = { + ip = mkOption { + type = str; + description = + "IP to assign to the initrd image, allowing access to host during bootup."; + }; + keypair = mkOption { + type = (submodule keypair-type); + description = "SSH host key pair to use for initrd."; + }; + interface = mkOption { + type = str; + description = + "Name of interface on which to listen for connections."; + }; + }; + }; + + in mkOption { + type = nullOr (submodule initrd-network-config); + description = + "Configuration parameters to set up initrd SSH network."; + default = null; + }; + + backplane-password-file = mkOption { + type = path; + description = + "File containing the password used by this host to connect to the backplane."; + }; }; }; - }; }