A single-call DNS health audit
Auditing the health of a DNS zone usually means orchestrating seven separate calls — DNSSEC, CAA, AXFR, NSEC3, open-resolver, SOA, subdomain-exposure — then aggregating the results yourself. The zone-hygiene composite endpoint runs nine independent DNS health checks in one request and returns a weighted score with a letter grade. Here's the walkthrough, with the standards each check is grounded in.
The audit problem
Most DNS health questions don't have a single answer — they have nine. Is the zone DNSSEC-signed and validating cleanly? Is there a CAA record restricting certificate issuance? Is AXFR refused? Are NSEC3 parameters compliant with RFC 9276? Are any of the nameservers acting as open recursive resolvers? Are SOA serial numbers consistent across resolvers? Are the SOA timer values within sensible bounds? Is there a wildcard at the apex? Are sensitive subdomain names accidentally public?
Any one of these has its own dedicated endpoint and its own canonical specification. But operators rarely want them in isolation — they want a single audit, refreshed on a schedule, with one number that says "this zone is fine" or "this zone needs attention." Until recently, the only way to get that was to wire seven calls together yourself, build a scoring rubric, and decide what to do when checks disagree.
The zone-hygiene composite endpoint at `/v1/dns/zone-hygiene` does this orchestration in one request. It fans out to all nine checks in parallel, aggregates the findings, applies a weighted score, and returns a letter grade alongside the structured detail.
The nine checks
Each check has its own specification:
1. Nameserver redundancy — at least two authoritative NSes per RFC 1034 §4.2.2. 2. SOA serial consistency across resolvers — drift indicates replication is failing silently. 3. SOA field validation against RIPE-203 bounds: refresh ≥ 24h, retry ≥ 2h, expire ≥ 14d, minimum (negative-cache TTL) ≤ 24h. 4. Wildcard detection at the apex — affects how every other subdomain check should be interpreted. 5. Sensitive-subdomain exposure — public DNS records for names like `admin.`, `vpn.`, `jenkins.`, `kibana.`, `prometheus.`, `phpmyadmin.` (filtered against the wildcard's IPs to avoid false positives). 6. Open-resolver detection on each NS — sends a recursive query for a name the NS isn't authoritative for; if it returns a recursive answer, the NS is being abused as a reflection-amplification source. 7. DNSSEC posture — full cryptographic verification per RFC 4034 (DS digest match, RRSIG signature verification). See the DNSSEC cryptographic verification guide for the deep dive. 8. CAA presence — without CAA, any CA can issue certificates for the domain. Specified in RFC 8659. 9. Zone-transfer (AXFR) exposure — open AXFR per RFC 5936 leaks the entire zone.
Each check produces zero or more findings with a severity (`critical`, `high`, `medium`, `low`, `info`). Findings drive the weighted score.
How the score works
The score starts at 100 and deducts points by finding severity:
| Severity | Points deducted | |---|---| | critical | 30 | | high | 18 | | medium | 8 | | low | 3 | | info | 0 |
Multiple findings stack. The minimum is 0, the maximum is 100. The letter grade derives mechanically:
| Score | Grade | |---|---| | ≥ 90 | A | | ≥ 80 | B | | ≥ 70 | C | | ≥ 60 | D | | < 60 | F |
The `checks[]` array in the response gives a per-area summary — for each of the nine checks, you see whether it passed, the highest-severity finding raised, and the count of findings. So you get both the top-line score and the per-area drill-down, without having to walk the full `findings` array yourself.
A live walkthrough
Reading the response, the most useful fields top-down are:
`hygiene_grade` and `hygiene_score` — the headline. A score of 87 / grade B is the typical "mostly fine, a few mediums to fix."
`checks[]` — the nine per-area summaries. Sort by severity_max descending to see which areas need attention first.
`composite` — the cross-endpoint cliff notes: `dnssec_status`, `has_caa`, `zone_transfer_vulnerable`, `nsec3_compliant`. Useful for dashboards that want a single boolean per area.
`open_resolver_check[]` — per-NS open-resolver detail. An entry with `is_open_resolver: true` is a critical finding.
`soa_field_validation[]` — per-field RIPE-203 status. Common pattern: `expire` set too low (some operators copy default values from old tutorials).
`exposed_subdomains[]` — sensitive subdomains that resolve publicly with non-wildcard IPs. The names are pre-filtered against the wildcard, so what's left is genuine exposure.
`findings[]` and `recommendations[]` — narrative detail and suggested fixes.
The response is bigger than most endpoints — running nine checks produces nine areas of detail. For lightweight monitoring, the score-and-grade pair is usually enough; for full audits, drill into the per-check arrays.
curl -sH "Authorization: Bearer $KEY" \
'https://api.edgedns.dev/v1/dns/zone-hygiene?domain=example.com' | jq '.data | {
grade: .hygiene_grade,
score: .hygiene_score,
checks: .checks,
composite: .composite,
open_resolvers: .open_resolvers_detected,
soa_drift: .soa_drift_detected,
wildcard: .wildcard_detected,
exposed: .exposed_count
}'Compared to manual workflows and competing tools
Compared to `dig` orchestration. Replicating this audit by hand requires running multiple `dig` invocations against multiple resolvers, parsing presentation-form output, computing SHA-256 digests for the DNSSEC check, opening TCP sockets for AXFR, and writing the scoring rubric. The composite endpoint replaces that workflow with a single HTTP request and a structured JSON response.
Compared to intoDNS. intoDNS is a venerable web tool that runs a similar set of checks. It's interactive (web-only), targets the same kinds of operators, and surfaces similar findings. The composite endpoint covers the same ground in a programmatic API with structured output suitable for dashboards, CI pipelines, and continuous monitoring.
Compared to nslookup.io DNS Health. nslookup.io DNS Health runs 39 checks across DNSSEC, MX, CAA, and others. The composite endpoint covers the most operationally important subset — the nine checks — with cryptographic DNSSEC verification baked in, and a programmatic interface.
Compared to dnsviz. dnsviz is the gold-standard interactive DNSSEC visualizer. It produces beautiful chain-of-trust diagrams. The composite endpoint isn't a visualization — it's an audit. The two are complementary.
When to call it
On every zone change. Catch SOA-drift, expiring RRSIGs, and accidentally-public subdomains in the window before they cause downstream issues.
On a schedule for production zones. Daily for most zones; hourly for high-traffic or compliance-sensitive zones. The score is stable across runs (cached for 5 minutes), so frequent polls are cheap.
Before issuing a new TLS certificate. The CAA + DNSSEC parts of the composite cover exactly the controls a CA would consult during issuance.
As part of an incident post-mortem. When something DNS-related broke, the composite gives you a single snapshot of zone state — useful as evidence and as a baseline for the fix.
Not for every customer-facing query. The composite runs ~50 sub-requests under the hood; treat it as an audit endpoint, not a hot-path lookup. Use `/v1/dns/lookup` for hot-path needs.
Integrating into CI / monitoring
Two patterns work well:
CI gate. Block deploys (or fail a pre-flight job) when the score drops below a threshold. The example above fails the build when the grade falls below B.
Continuous monitoring. Schedule the call from a monitoring tool (cron, GitHub Actions, your alerting platform) and alert on grade regressions. A drop from A to C between two runs almost always indicates a real issue.
For longer-running observability, the score is a useful single dimension to chart over time — gradual erosion of zone hygiene is the normal failure mode for any production zone, and a 90-day score timeline makes the trend visible before an incident forces it.
// Block deploys when the zone falls below grade B
const res = await fetch(
`https://api.edgedns.dev/v1/dns/zone-hygiene?domain=${domain}`,
{ headers: { Authorization: `Bearer ${process.env.EDGEDNS_API_KEY}` } }
);
const { data } = await res.json();
if (data.hygiene_score < 80) {
console.error(`DNS hygiene below threshold: ${data.hygiene_grade} (${data.hygiene_score})`);
console.error('Failed checks:', data.checks.filter(c => !c.passed));
process.exit(1);
}Further reading
Standards underlying the composite:
RFC 1034 — Domain names, concepts and facilities (NS redundancy)
RFC 5011 — Automated trust anchor updates
RFC 4034 — DNSSEC resource records
RFC 5936 — AXFR
RFC 8659 — CAA
RFC 9276 — NSEC3 parameter guidance
RIPE-203 — SOA timer values
Related EdgeDNS resources:
DNSSEC cryptographic verification — deep dive on the DNSSEC layer of the composite
`/v1/dns/zone-hygiene` — the endpoint reference
DNS Vulnerability Assessment use case — pen-tester-oriented narrative
Related Guides
DNSSEC cryptographic verification: what we actually verify
DNSSEC is supposed to give you a cryptographic guarantee that a DNS answer is authentic. Most tools that claim to "check DNSSEC" don't actually verify any cryptography — they trust the recursive resolver's AD bit and call it a day. EdgeDNS reconstructs the canonical signed RRset and runs the math locally. Here's what that means, why the difference matters, and how to read what comes back.
Fast-flux vs CDN: how to tell them apart
Fast-flux DNS — the IP-rotation technique used by botnets to keep phishing and malware infrastructure online — looks identical to a CDN at the surface. Both rotate IPs, both use short TTLs, both serve different addresses to different users. The signal that actually separates them is ASN diversity. This guide walks through the detection model, why naive checks produce false positives, and how the EdgeDNS fast-flux endpoint resolves the ambiguity.
Need Programmatic Access?
Automate domain intelligence with 100+ API endpoints and a free MCP server for AI integration.