about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorSandro <sandro.jaeckel@gmail.com>2024-04-17 21:48:59 +0200
committerGitHub <noreply@github.com>2024-04-17 21:48:59 +0200
commit1166097197f43e45c377449c58455e32f11b87f6 (patch)
tree3eebc3c885576822319756510747c3c6ead5bc3f /nixos
parent671372c8ed0e0a12e1de3e2e93abd19cd1d6c631 (diff)
parent8737490803c127dba0e01c748a66db3d24d7c1f8 (diff)
Merge pull request #302375 from SebastianWendel/init-prometheus-dnssec-exporter
nixos/prometheus-dnssec-exporter: init
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/release-notes/rl-2405.section.md2
-rw-r--r--nixos/modules/services/monitoring/prometheus/exporters.nix1
-rw-r--r--nixos/modules/services/monitoring/prometheus/exporters/dnssec.nix90
-rw-r--r--nixos/tests/prometheus-exporters.nix48
4 files changed, 141 insertions, 0 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md
index f1eb69bdaec6d..918a45ac3f7de 100644
--- a/nixos/doc/manual/release-notes/rl-2405.section.md
+++ b/nixos/doc/manual/release-notes/rl-2405.section.md
@@ -139,6 +139,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - [ping_exporter](https://github.com/czerwonk/ping_exporter), a Prometheus exporter for ICMP echo requests. Available as [services.prometheus.exporters.ping](#opt-services.prometheus.exporters.ping.enable).
 
+- [Prometheus DNSSEC Exporter](https://github.com/chrj/prometheus-dnssec-exporter), check for validity and expiration in DNSSEC signatures and expose metrics for Prometheus. Available as [services.prometheus.exporters.dnssec](#opt-services.prometheus.exporters.dnssec.enable).
+
 - [TigerBeetle](https://tigerbeetle.com/), a distributed financial accounting database designed for mission critical safety and performance. Available as [services.tigerbeetle](#opt-services.tigerbeetle.enable).
 
 - [go-camo](https://github.com/cactus/go-camo), a secure image proxy server. Available as [services.go-camo](#opt-services.go-camo.enable).
diff --git a/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixos/modules/services/monitoring/prometheus/exporters.nix
index a9eab3e7055cc..2dc12a221bf06 100644
--- a/nixos/modules/services/monitoring/prometheus/exporters.nix
+++ b/nixos/modules/services/monitoring/prometheus/exporters.nix
@@ -31,6 +31,7 @@ let
     "collectd"
     "dmarc"
     "dnsmasq"
+    "dnssec"
     "domain"
     "dovecot"
     "fastly"
diff --git a/nixos/modules/services/monitoring/prometheus/exporters/dnssec.nix b/nixos/modules/services/monitoring/prometheus/exporters/dnssec.nix
new file mode 100644
index 0000000000000..dda1ad1988a61
--- /dev/null
+++ b/nixos/modules/services/monitoring/prometheus/exporters/dnssec.nix
@@ -0,0 +1,90 @@
+{ config, lib, pkgs, ... }:
+let
+  cfg = config.services.prometheus.exporters.dnssec;
+  configFormat = pkgs.formats.toml { };
+  configFile = configFormat.generate "dnssec-checks.toml" cfg.configuration;
+in {
+  port = 9204;
+  extraOpts = {
+    configuration = lib.mkOption {
+      type = lib.types.nullOr lib.types.attrs;
+      default = null;
+      description = ''
+        dnssec exporter configuration as nix attribute set.
+
+        See <https://github.com/chrj/prometheus-dnssec-exporter/blob/master/README.md>
+        for the description of the configuration file format.
+      '';
+      example = lib.literalExpression ''
+        {
+          records = [
+            {
+              zone = "ietf.org";
+              record = "@";
+              type = "SOA";
+            }
+            {
+              zone = "verisigninc.com";
+              record = "@";
+              type = "SOA";
+            }
+          ];
+        }
+      '';
+    };
+
+    listenAddress = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
+      default = null;
+      description = ''
+        Listen address as host IP and port definition.
+      '';
+      example = ":9204";
+    };
+
+    resolvers = lib.mkOption {
+      type = lib.types.listOf lib.types.str;
+      default = [ ];
+      description = ''
+        DNSSEC capable resolver to be used for the check.
+      '';
+      example = [ "0.0.0.0:53" ];
+    };
+
+    timeout = lib.mkOption {
+      type = lib.types.nullOr lib.types.str;
+      default = null;
+      description = ''
+        DNS request timeout duration.
+      '';
+      example = "10s";
+    };
+
+    extraFlags = lib.mkOption {
+      type = lib.types.listOf lib.types.str;
+      default = [ ];
+      description = ''
+        Extra commandline options when launching Prometheus.
+      '';
+    };
+  };
+
+  serviceOpts = {
+    serviceConfig = let
+      startScript = pkgs.writeShellScriptBin "prometheus-dnssec-exporter-start"
+        "${lib.concatStringsSep " "
+        ([ "${pkgs.prometheus-dnssec-exporter}/bin/prometheus-dnssec-exporter" ]
+          ++ lib.optionals (cfg.configuration != null)
+          [ "-config ${configFile}" ]
+          ++ lib.optionals (cfg.listenAddress != null)
+          [ "-listen-address ${lib.escapeShellArg cfg.listenAddress}" ]
+          ++ lib.optionals (cfg.resolvers != [ ]) [
+            "-resolvers ${
+              lib.escapeShellArg (lib.concatStringsSep "," cfg.resolvers)
+            }"
+          ] ++ lib.optionals (cfg.timeout != null)
+          [ "-timeout ${lib.escapeShellArg cfg.timeout}" ] ++ cfg.extraFlags)}";
+    in { ExecStart = lib.getExe startScript; };
+  };
+}
+
diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix
index 3dc368e320ff2..576253450814f 100644
--- a/nixos/tests/prometheus-exporters.nix
+++ b/nixos/tests/prometheus-exporters.nix
@@ -227,6 +227,54 @@ let
       '';
     };
 
+    dnssec = {
+      exporterConfig = {
+        enable = true;
+        configuration = {
+          records = [
+            {
+              zone = "example.com";
+              record = "@";
+              type = "SOA";
+            }
+          ];
+        };
+        resolvers = [ "127.0.0.1:53" ];
+      };
+      metricProvider = {
+        services.knot = {
+          enable = true;
+          settingsFile = pkgs.writeText "knot.conf" ''
+            server:
+              listen: 127.0.0.1@53
+            template:
+              - id: default
+                storage: ${pkgs.buildEnv {
+                  name = "zones";
+                  paths = [(pkgs.writeTextDir "example.com.zone" ''
+                    @ SOA ns1.example.com. noc.example.com. 2024032401 86400 7200 3600000 172800
+                    @       NS      ns1
+                    ns1     A       192.168.0.1
+                  '')];
+                }}
+                zonefile-load: difference
+                zonefile-sync: -1
+            zone:
+              - domain: example.com
+                file: example.com.zone
+                dnssec-signing: on
+          '';
+        };
+      };
+      exporterTest = ''
+        wait_for_unit("knot.service")
+        wait_for_open_port(53)
+        wait_for_unit("prometheus-dnssec-exporter.service")
+        wait_for_open_port(9204)
+        succeed("curl -sSf http://localhost:9204/metrics | grep 'example.com'")
+      '';
+    };
+
     # Access to WHOIS server is required to properly test this exporter, so
     # just perform basic sanity check that the exporter is running and returns
     # a failure.