- Go 97.8%
- Makefile 1.3%
- Dockerfile 0.9%
|
All checks were successful
continuous-integration/drone/push Build is passing
|
||
|---|---|---|
| checker | ||
| contract | ||
| plugin | ||
| .drone-manifest.yml | ||
| .drone.yml | ||
| .gitignore | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| main.go | ||
| Makefile | ||
| NOTICE | ||
| README.md | ||
checker-dangling
A happyDomain checker that scans a working zone for dangling subdomains:
records (CNAME / MX / SRV / NS) whose targets resolve to NXDOMAIN,
or whose external registrable domain is expired, in pendingDelete, or
recently re-registered. This is the attack class popularised by Ars
Technica in 2017, where universities ended up serving porn from CNAMEs
that pointed at decommissioned third-party services after malicious
actors re-registered the lapsed targets.
It runs in three deployment modes (standalone HTTP binary, Go plugin, Docker image), like every other checker in the happyDomain ecosystem.
How it works
The checker walks every service in the working zone (AutoFillZone) and
extracts pointer records from svcs.CNAME, svcs.SpecialCNAME,
svcs.MXs, svcs.UnknownSRV, and svcs.Orphan bodies (the latter
covering bare NS/CNAME/MX records when no dedicated service is
attached). For each (owner, rrtype, target) triple it:
- Classifies the target as in-zone or external relative to the zone's
eTLD+1 (via
golang.org/x/net/publicsuffix). - Performs a single, time-bounded DNS resolution to detect immediate
breakage (
nxdomain,servfail,no_answer,timeout). - Publishes a
DiscoveryEntryper pointer:dangling.external-target.v1for external pointers — companion checkers (notably the host'sdomain_expiry) subscribe to this type and run RDAP/WHOIS on the registrable domain.dangling.in-zone-target.v1for same-registrable pointers — used as a join key for future reachability checkers (alias / ping / http) that may consume it.
Verdict matrix
| Signal | Severity | Source |
|---|---|---|
| Target NXDOMAIN | Critical | local DNS resolution |
| Target SERVFAIL | Warning | local DNS resolution |
| Target NOERROR with empty answer | Info | local DNS resolution |
| Registrable domain expired | Critical | whois related obs. |
Registrable status pendingDelete / redemptionPeriod |
Critical | whois related obs. |
| Registrable registered within the last 90 days | Warning | whois related obs. |
The rule emits one CheckState per impacted owner and ranks them by
descending severity so the report's "Fix this first" card always
matches the rule output.
Companion: domain_expiry
For the WHOIS-driven signals to fire, the host's existing
domain_expiry checker must be extended to subscribe to
dangling.external-target.v1 entries via AutoFillDiscoveryEntries,
run RDAP per registrable domain, and publish a per-Ref whois
observation. Without that subscription the checker still works as a
DNS-only dangling detector.
Build
make # standalone binary
make plugin # .so plugin for happyDomain
make docker # Docker image
make test # run the unit tests