# prometheus-dnssec-exporter 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. ## Installation ### From Source ```bash 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. ## Usage ### Configuration The DNSSEC exporter requires a configuration file. When using the Debian package, this file is located at `/etc/prometheus/dnssec-exporter/config.yaml` ```yaml --- ## dnssec exporter configuration # #dns: # # The resolver to use. Must be DNSSEC validating, and # # must not strip DNSSEC responses. # resolver: 1.1.1.1:53 # # 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 # #basic_auth_users: # user1: pass1 # user2: pass2 #tls_server_config: # 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: ```yaml --- dns: resolver: 9.9.9.9:53 zones: - example.org. - example.com. - subdomain.example.com. ``` ### Running You can start the exporter using the following command: ```bash 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: ```bash systemctl enable --now prometheus-dnssec-exporter ``` ## Metrics The following metrics are exposed at the `/metrics` HTTP endpoint: ```prometheus # 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.