- Go 98.6%
- Makefile 0.8%
- Dockerfile 0.6%
| checker | ||
| plugin | ||
| .gitignore | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| main.go | ||
| Makefile | ||
| NOTICE | ||
| README.md | ||
checker-dnssec
DNSSEC operational hygiene checker for happyDomain.
Cryptographic chain validation is delegated to checker-dnsviz. This
checker focuses on policy and operational hygiene:
- NSEC vs NSEC3 zone walking exposure
- RFC 9276 NSEC3 parameter compliance (iterations, salt)
- Algorithm policy and key sizes (allowed / forbidden / modern)
- RRSIG presence, validity windows and freshness
- TTL recommendations for DNSKEY / RRSIG
- Per-name-server consistency of the DNSKEY RRset and denial scheme
The HTML report is laid out so the most common operator-facing failure scenarios appear first, with a fix line citing the relevant RFC.
Usage
Standalone HTTP server
# Build and run
make
./checker-dnssec -listen :8080
The server exposes:
GET /health: health checkPOST /collect: collect DNSSEC observations (happyDomain external checker protocol)
Docker
make docker
docker run -p 8080:8080 happydomain/checker-dnssec
happyDomain plugin
make plugin
# produces checker-dnssec.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 DNSSEC checker to the URL of the
running checker-dnssec server (e.g., http://checker-dnssec:8080).
happyDomain will delegate observation collection to this endpoint.
Build
make # standalone binary
make docker # FROM scratch image
make plugin # Go plugin (.so)
make test # tests
Options
Admin options
| Id | Type | Default | Description |
|---|---|---|---|
resolver |
string | /etc/resolv.conf |
Bootstrap recursive resolver (host:port) used to discover the apex name servers and look up the parent DS. |
User options
| Id | Type | Default | Description |
|---|---|---|---|
nsec3IterationsMax |
uint | 0 |
RFC 9276 §3.1 ceiling on NSEC3PARAM.Iterations. Increase only if your signer cannot publish 0 yet. |
nsec3IterationsSeverity |
choice | warn |
Severity when iterations exceed the ceiling. Use crit to enforce RFC 9276 strictly. |
signatureFreshness |
uint | 7 |
Warn when the closest RRSIG expires in fewer than this many days. |
signatureFreshnessCrit |
uint | 1 |
Critical when the closest RRSIG expires in fewer than this many days. |
minRSAKeySize |
uint | 2048 |
Minimum acceptable RSA modulus size, in bits. |
requireSEP |
bool | true |
Require at least one DNSKEY with the SEP bit (KSK). |
dnskeyTTLMin |
uint | 3600 |
Minimum DNSKEY TTL, in seconds; shorter TTLs hurt cacheability. |
Rules
| Code | Description | Severity |
|---|---|---|
dnssec_zone_signed |
Detects a zone advertised as signed at the parent (DS) but no DNSKEY served at the apex. | CRITICAL |
dnssec_dnskey_consistent |
Verifies that every authoritative server returns the same DNSKEY RRset. | CRITICAL |
dnssec_dnskey_query_ok |
Verifies that every authoritative server answered the DNSKEY query. | CRITICAL |
dnssec_algorithm_allowed |
Rejects DNSKEYs that use a forbidden algorithm or are not in the allowed list. | CRITICAL |
dnssec_algorithm_modern |
Recommends ECDSAP256SHA256 (13) or Ed25519 (15) over RSA. | WARNING |
dnssec_rsa_keysize |
Verifies RSA DNSKEYs reach a minimum modulus size (default 2048 bits). | CRITICAL |
dnssec_ksk_present |
Verifies at least one DNSKEY has the SEP bit (KSK). | CRITICAL |
dnssec_dnskey_count |
Warns when too many DNSKEYs are published, inflating responses and amplification potential. | WARNING |
dnssec_rrsig_present_dnskey |
Ensures the DNSKEY RRset is signed. | CRITICAL |
dnssec_rrsig_present_soa |
Ensures the SOA RRset is signed. | CRITICAL |
dnssec_rrsig_validity_window |
Verifies that every observed RRSIG is currently within [Inception, Expiration]. | CRITICAL |
dnssec_rrsig_freshness |
Warns when RRSIGs are close to expiring; preemptive alert for stuck signers. | CRITICAL |
dnssec_denial_uses_nsec3 |
Warns when the zone uses NSEC for negative answers, which makes the zone walkable (RFC 5155 / RFC 7129). | WARNING |
dnssec_nsec3_iterations |
Verifies that NSEC3PARAM.Iterations is at most nsec3IterationsMax (default 0, per RFC 9276 §3.1). | CRITICAL |
dnssec_nsec3_salt_empty |
Verifies that NSEC3PARAM.SaltLength is 0 (RFC 9276 §3.1: a salt buys no measurable protection). | WARNING |
dnssec_nsec3_optout_only_when_signed_delegations |
Reports informational note when the OPT-OUT flag is set on NSEC3PARAM in a leaf zone. | INFO |
dnssec_denial_consistent |
Verifies that every authoritative server uses the same denial-of-existence scheme. | WARNING |
dnssec_dnskey_ttl_min |
Warns when the DNSKEY TTL is too short to be useful for caching. | WARNING |
License
Licensed under the MIT License (see LICENSE).