- Go 99.1%
- Makefile 0.5%
- Dockerfile 0.4%
| checker | ||
| plugin | ||
| .gitignore | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| main.go | ||
| Makefile | ||
| README.md | ||
checker-resolver-propagation
Worldwide DNS propagation checker for happyDomain.
Probes a curated catalog of public recursive resolvers (Cloudflare, Google, Quad9, OpenDNS, Yandex, regional ISPs, …) across multiple transports (UDP, TCP, DoT, DoH) and regions, then compares their answers to the zone's authoritative nameservers to detect propagation gaps, regional splits, SOA serial drift, stale caches, DNSSEC validation failures, SERVFAIL/NXDOMAIN inconsistencies, and resolver filtering.
Usage
Standalone HTTP server
# Build and run
make
./checker-resolver-propagation -listen :8080
The server exposes:
GET /health: health checkPOST /collect: collect propagation observations (happyDomain external checker protocol)POST /evaluate: run the evaluation rules against an observationPOST /report: extract metrics / HTML report from an observation
Docker
make docker
docker run -p 8080:8080 happydomain/checker-resolver-propagation
happyDomain plugin
make plugin
# produces checker-resolver-propagation.so, loadable by happyDomain as a Go plugin
The plugin exposes a NewCheckerPlugin symbol returning the checker
definition and observation provider, which happyDomain registers in its
global registries at load time.
Versioning
The binary, plugin, and Docker image embed a version string overridable at build time:
make CHECKER_VERSION=1.2.3
make plugin CHECKER_VERSION=1.2.3
make docker CHECKER_VERSION=1.2.3
happyDomain remote endpoint
Set the endpoint admin option for the resolver-propagation checker to
the URL of the running checker-resolver-propagation server (e.g.,
http://checker-resolver-propagation:8080). happyDomain will delegate
observation collection to this endpoint.
This checker applies to service-level checks and is restricted to
the abstract.Origin and abstract.NSOnlyOrigin services (the zone
apex / NS configuration).
Options
| Id | Type | Default | Description |
|---|---|---|---|
recordTypes |
string | SOA,NS,A,AAAA,MX,TXT,CAA |
Comma-separated list of RR types to probe at the apex (and at each subdomains entry). |
subdomains |
string | www |
Comma-separated list of owner names to probe in addition to the apex (e.g. www,mail,@). Empty = apex only. |
includeFiltered |
bool | false |
Probe filtering resolvers (malware/family/adblock). Their answers routinely diverge by design. |
region |
string | all |
Restrict to a region: all, global, na, eu, asia, ru, me. |
transports |
string | udp |
Comma-separated transports to probe: udp, tcp, dot, doh. Encrypted transports are only used where published. |
resolverAllowlist |
string | Comma-separated resolver IDs or IPs to probe exclusively (e.g. cloudflare,google,9.9.9.9). Empty = catalog selection. |
|
latencyThresholdMs |
uint | 500 |
Resolvers averaging above this value emit an info finding. |
runTimeoutSeconds |
uint | 30 |
Hard wall-clock budget for one propagation run. Slower resolvers report as unreachable. |
Rules
Each rule emits a finding code. Severity can be affected by the options above.
| Code | Default severity | Condition |
|---|---|---|
rprop_no_resolvers |
critical | The current option set selects no resolver from the catalog. |
rprop_all_resolvers_down |
critical | Every selected resolver failed to answer (likely no DNS connectivity from the checker host). |
rprop_resolver_unreachable |
warning | An individual resolver failed to answer within the run budget. |
rprop_resolver_high_latency |
info | A resolver's average response time exceeds latencyThresholdMs. |
rprop_resolver_filtered_hit |
info | A filtered resolver returned a different answer than the consensus (typical blocklist behaviour). Only when includeFiltered is enabled. |
rprop_partial_propagation |
warning | Public resolvers disagree on the answer for a probed RRset. |
rprop_answer_drift |
critical | The public consensus differs from the answer served by the zone's authoritative nameservers. |
rprop_unexpected_nxdomain |
critical | Some resolvers return NXDOMAIN while others return NOERROR for the same RRset. |
rprop_unexpected_servfail |
critical | A resolver returns SERVFAIL (usually a DNSSEC or reachability failure). |
rprop_regional_split |
warning | Every resolver of a region agrees on an answer that differs from the global consensus. |
rprop_serial_drift |
warning | Unfiltered resolvers disagree on the SOA serial. |
rprop_stale_cache |
info | A resolver still serves an SOA serial below the one last observed by happyDomain. |
rprop_dnssec_failure |
critical | A validating resolver fails to validate the zone's DNSSEC chain (returns SERVFAIL with AD/CD semantics). |
rprop_dnssec_not_validated |
info | A validating resolver answered without setting AD on a signed zone. |
License
Licensed under the MIT License (see LICENSE).