{ self }: { config, lib, pkgs, ... }: let cfg = config.services.prometheus.exporters.nixos; in { options.services.prometheus.exporters.nixos = { enable = lib.mkEnableOption "NixOS Prometheus exporter"; port = lib.mkOption { type = lib.types.port; default = 9971; description = "Port to listen on."; }; listenAddress = lib.mkOption { type = lib.types.str; default = "0.0.0.0"; description = "Address to listen on."; }; flake = { enable = lib.mkEnableOption "flake collector"; url = lib.mkOption { type = lib.types.str; default = ""; description = '' Flake URL for revision comparison. Required if flake collector is enabled. ''; }; checkInterval = lib.mkOption { type = lib.types.str; default = "1h"; description = "Interval between remote flake checks."; }; }; openFirewall = lib.mkOption { type = lib.types.bool; default = false; description = "Open the firewall for the exporter port."; }; user = lib.mkOption { type = lib.types.str; default = "nixos-exporter"; description = "User to run the exporter as."; }; group = lib.mkOption { type = lib.types.str; default = "nixos-exporter"; description = "Group to run the exporter as."; }; package = lib.mkOption { type = lib.types.package; default = self.packages.${pkgs.system}.default; description = "The nixos-exporter package to use."; }; }; config = lib.mkIf cfg.enable { assertions = [ { assertion = cfg.flake.enable -> cfg.flake.url != ""; message = "services.prometheus.exporters.nixos.flake.url must be set when flake collector is enabled"; } ]; users.users.${cfg.user} = { isSystemUser = true; group = cfg.group; description = "NixOS exporter user"; }; users.groups.${cfg.group} = { }; systemd.services.prometheus-nixos-exporter = { description = "Prometheus NixOS Exporter"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; # nix is required for flake collector, git for git+https:// URLs path = lib.mkIf cfg.flake.enable [ config.nix.package pkgs.git ]; serviceConfig = { User = cfg.user; Group = cfg.group; ExecStart = lib.concatStringsSep " " ([ "${cfg.package}/bin/nixos-exporter" "--listen=${cfg.listenAddress}:${toString cfg.port}" ] ++ lib.optionals cfg.flake.enable [ "--collector.flake" "--flake.url=${cfg.flake.url}" "--flake.check-interval=${cfg.flake.checkInterval}" ]); Restart = "on-failure"; RestartSec = "5s"; # Hardening NoNewPrivileges = true; ProtectSystem = "strict"; ProtectHome = true; PrivateTmp = true; PrivateDevices = true; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectControlGroups = true; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; MemoryDenyWriteExecute = true; LockPersonality = true; }; }; networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ]; }; }