A Prometheus exporter that exposes metrics on DNSSEC-signed DNS zones. One of its core features is that it compares a zone's CDS record set to the DS record set in the parent zone.
Go to file
s3lph 54c3cb51a4
/ build_debian (push) Successful in 2m0s Details
/ compile (push) Successful in 1m11s Details
/ golangci-lint (push) Successful in 2m3s Details
feat: migrate from woodpecker to forgejo actions
2023-12-19 06:24:38 +01:00
.forgejo/workflows feat: migrate from woodpecker to forgejo actions 2023-12-19 06:24:38 +01:00
package/debian/prometheus-dnssec-exporter fix: typo in postinst script 2023-10-31 02:05:36 +01:00
.gitignore fix: gitignore 2023-07-29 14:48:20 +02:00
Makefile Fix release pipeline 2022-10-14 02:35:45 +02:00
README.md feat: migrate from woodpecker to forgejo actions 2023-12-19 06:24:38 +01:00
go.mod Config file support, more metrics 2022-04-08 21:21:58 +02:00
go.sum Initial commit 2022-04-08 03:02:20 +02:00
main.go happier golangci-lint 2022-04-08 21:28:31 +02:00



A Prometheus exporter that exposes metrics on DNSSEC-signed DNS zones. One of its core features is that it compares a zone's CDS record set to the DS record set in the parent zone.


From Source

git clone https://gitlab.com/s3lph/prometheus-dnssec-exporter
cd prometheus-dnssec-exporter
make prometheus-dnssec-exporter

Debian Package

There is an automatically built Debian package in my repository.

Follow the instructions at https://git.kabelsalat.ch/s3lph/-/packages/debian/prometheus-dnssec-exporter to add the repository and install the package.

If you do not want to add my repository to your system, you can also download the deb package from the repository instead.



The DNSSEC exporter requires a configuration file. When using the Debian package, this file is located at /etc/prometheus/dnssec-exporter/config.yaml


## dnssec exporter configuration
#  # The resolver to use.  Must be DNSSEC validating, and
#  # must not strip DNSSEC responses.
#  resolver:
#  # List of zones to resolve.
#  zones:
#    - example.org.
#    - example.com.

## TLS and Basic Auth can be configured here as well, see for details:
## https://github.com/prometheus/exporter-toolkit/blob/master/web/tls_config.go#L36
#  user1: pass1
#  user2: pass2
#  cert_file: server.crt
#  key_file: server.key

You should at least provide the resolver to use (the DNSSEC exporter only works with a DNSSEC-validating resolver!) and the zones you want to collect metrics on:

    - example.org.
    - example.com.
    - subdomain.example.com.


You can start the exporter using the following command:

prometheus-dnssec-exporter --config=path/to/dnssec-exporter/config.yaml --web.listen-address=:9142

The Debian package provides a systemd service unit that does the job for you:

systemctl enable --now prometheus-dnssec-exporter


The following metrics are exposed at the /metrics HTTP endpoint:

# HELP dnssec_cds_count Number of CDS records present in the zone
# TYPE dnssec_cds_count gauge
dnssec_cds_count{parent="org.",tld="org.",zone="example.org."} 1
dnssec_cds_count{parent="com.",tld="com.",zone="example.com."} 1
dnssec_cds_count{parent="example.com.",tld="com.",zone="subdomain.example.com."} 1
# HELP dnssec_cds_ds_match 1 if the CDS and DS records match, 0 otherwise
# TYPE dnssec_cds_ds_match gauge
dnssec_cds_ds_match{parent="org.",tld="org.",zone="example.org."} 0
dnssec_cds_ds_match{parent="com.",tld="com.",zone="example.com."} 1
dnssec_cds_ds_match{parent="example.com.",tld="com.",zone="subdomain.example.com."} 1
# HELP dnssec_cds_rcode RCode of the CDS record answer
# TYPE dnssec_cds_rcode gauge
dnssec_cds_rcode{parent="org.",tld="org.",zone="example.org."} 0
dnssec_cds_rcode{parent="com.",tld="com.",zone="example.com."} 0
dnssec_cds_rcode{parent="example.com.",tld="com.",zone="subdomain.example.com."} 0
# HELP dnssec_ds_count Number of DS record is present in the parent zone
# TYPE dnssec_ds_count gauge
dnssec_ds_count{parent="org.",tld="org.",zone="example.org."} 1
dnssec_ds_count{parent="com.",tld="com.",zone="example.com."} 1
dnssec_ds_count{parent="example.com.",tld="com.",zone="subdomain.example.com."} 1
# HELP dnssec_ds_rcode RCode of the DS record answer
# TYPE dnssec_ds_rcode gauge
dnssec_ds_rcode{parent="org.",tld="org.",zone="example.org."} 0
dnssec_ds_rcode{parent="com.",tld="com.",zone="example.com."} 0
dnssec_ds_rcode{parent="example.com.",tld="com.",zone="subdomain.example.com."} 0
# HELP dnssec_signature_ok 1 if the DNSSEC signature is present and valid, 0 otherwise
# TYPE dnssec_signature_ok gauge
dnssec_signature_ok{parent="org.",tld="org.",zone="example.org."} 1
dnssec_signature_ok{parent="com.",tld="com.",zone="example.com."} 1
dnssec_signature_ok{parent="example.com.",tld="com.",zone="subdomain.example.com."} 1
# HELP dnssec_signature_rcode RCode of the DNS query
# TYPE dnssec_signature_rcode gauge
dnssec_signature_rcode{parent="org.",tld="org.",zone="example.org."} 0
dnssec_signature_rcode{parent="com.",tld="com.",zone="example.com."} 0
dnssec_signature_rcode{parent="example.com.",tld="com.",zone="subdomain.example.com."} 0

The two metrics that are probably the most important are:

  • dnssec_signature_ok: If this is 0, the chain of trust to your zone is broken.
  • dnssec_cds_ds_match: If this is 0, it's most likely a KSK rollover is in progress. If your registry does not support CDS submission, this is the sign that you need to replace the DS records in the parent zone.