Unverified Commit 11660971 authored by Sandro Jäckel's avatar Sandro Jäckel Committed by GitHub
Browse files

Merge pull request #302375 from SebastianWendel/init-prometheus-dnssec-exporter

nixos/prometheus-dnssec-exporter: init
parents 671372c8 87374908
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -19405,6 +19405,12 @@
    github = "sweenu";
    githubId = 7051978;
  };
  swendel = {
    name = "Sebastian Wendel";
    email = "nixpkgs.aiX5ph@srx.digital";
    github = "SebastianWendel";
    githubId = 919570;
  };
  swesterfeld = {
    email = "stefan@space.twc.de";
    github = "swesterfeld";
+2 −0
Original line number Diff line number Diff line
@@ -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).
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ let
    "collectd"
    "dmarc"
    "dnsmasq"
    "dnssec"
    "domain"
    "dovecot"
    "fastly"
+90 −0
Original line number Diff line number Diff line
{ 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; };
  };
}
+48 −0
Original line number Diff line number Diff line
@@ -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.
Loading