Loop icon
Download icon
Get icon
Script icon
If icon
SlackIncomingWebhook icon
Set icon
Schedule icon

Catch DNSSEC Validation Failures and Expiring Signatures Before Users Do

Check your DNSSEC-signed domains hourly and alert in Slack on validation failures, signatures close to expiry, DS record changes or DNSSEC removal.

Categories
Infrastructure

DNSSEC failures are outages that look like nothing from the inside. When a zone's signatures expire because the signer stopped, or the DS record at the registrar no longer matches the zone's keys after a botched rollover or a DNS provider move, every validating resolver (Cloudflare 1.1.1.1, Google 8.8.8.8 and most large ISPs) returns SERVFAIL. Non-validating office networks keep working, so the team often learns about it from customers.

This blueprint asks a validating resolver about each domain every hour, through DNS-over-HTTPS JSON, and reports, once each and again when resolved:

  • validation failing (SERVFAIL with validation, an answer without), with the resolver's extended error, such as "DNSKEY Missing no SEP matching the DS";
  • the SOA signature (RRSIG) getting close to expiry, measured as the share of its validity period left, because signers use very different lifetimes (Cloudflare signs on the fly with signatures valid for about two days, BIND and Knot commonly use two to four weeks);
  • DS records changing (expected in a planned key rollover, suspicious otherwise);
  • DS records disappearing, which means DNSSEC was switched off;
  • the domain failing even without validation, which is a DNS outage rather than DNSSEC.

Unsigned domains are reported only if they stop resolving.

How it works

For each entry in domains (Loop, four at a time):

  1. query_validated looks up the SOA record with validation, the way users see it.
  2. query_unvalidated repeats it with checking disabled (cd=1) and returns the RRSIG.
  3. query_ds reads the DS records from the parent zone.
  4. load_previous reads the DS records and findings from the last run in the Kestra KV store.
  5. evaluate decides whether the domain is signed and validates, computes how much of the signature's validity is left, and lists new and resolved findings.
  6. if_changed skips Slack when nothing changed.
  7. alert_owner posts the findings, the current state and a DNSViz link.
  8. remember_state stores the state for the next comparison, after the alert.

Prerequisites

  • A Slack Incoming Webhook. DNS-over-HTTPS is public and needs no key.

Secrets

  • SLACK_WEBHOOK_URL: Slack Incoming Webhook URL for alerts and failures.

In the open-source edition, secrets are environment variables on the Kestra container, prefixed with SECRET_ and base64-encoded. See how to manage secrets.

Inputs

  • domains (JSON): list of {"domain", "owner"} objects, using the zone apex.
  • min_signature_percent (INT, default 15): the signature expiry warning. Signers renew a signature while a quarter to a half of its validity is left, so less than 15% means re-signing has stopped.
  • doh_url (STRING, default Cloudflare): the resolver. https://dns.google/resolve works too.

Quick start

  1. Add the Slack secret and list your domains.
  2. Execute the flow. Any current problem is posted; healthy domains are recorded.
  3. Enable hourly.

To see a failure, run the flow with dnssec-failed.org, a domain kept deliberately broken for testing: it is reported as failing validation.

Outputs

  • {{ outputs.evaluate.vars }} per iteration: summary, new, resolved, and state (signed, ds, findings).
  • KV entries dnssec_watch_<domain>: the recorded state.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.