checker-dangling/README.md

65 lines
3.1 KiB
Markdown

# 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:
1. Classifies the target as in-zone or external relative to the zone's
eTLD+1 (via `golang.org/x/net/publicsuffix`).
2. Performs a single, time-bounded DNS resolution to detect immediate
breakage (`nxdomain`, `servfail`, `no_answer`, `timeout`).
3. Publishes a `DiscoveryEntry` per pointer:
- `dangling.external-target.v1` for external pointers — companion
checkers (notably the host's `domain_expiry`) subscribe to this
type and run RDAP/WHOIS on the registrable domain.
- `dangling.in-zone-target.v1` for 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
```sh
make # standalone binary
make plugin # .so plugin for happyDomain
make docker # Docker image
make test # run the unit tests
```