watcher: notify nameserver address changes (closes #105)
check / check (push) Failing after 2m11s

Each domain check now looks up the addresses every nameserver's name
resolves to, with the resolver's ResolveIPAddresses, and saves them
sorted in the domain's state. A nameserver that stays in the
delegation and resolves to different addresses sends one NS Address
Change notification naming the domain, the nameserver and the old and
new addresses. Added or removed nameservers get only the NS change
notification. A failed or empty lookup keeps the previous addresses,
because the resolver returns no address without an error when every
server it asks times out. State files without the field load, and the
next check fills it in silently. Watcher tests that run domain checks
use example.com, which has two nameservers, to stay within the
per-attempt limit.

Model: opus-5-5
This commit was merged in pull request #187.
This commit is contained in:
2026-10-01 23:23:26 +02:00
parent f6567df2d0
commit c247f6bcf5
8 changed files with 479 additions and 21 deletions
+17 -2
View File
@@ -46,10 +46,15 @@ rejected.
- Every **1 hour**, performs a full iterative trace from root servers to
discover all authoritative nameservers (NS records) for each domain.
- Queries **every** discovered authoritative nameserver independently.
- Stores the NS record set as observed by the delegation chain.
- Stores the NS record set as observed by the delegation chain, and the
IPv4 and IPv6 addresses each nameserver's name resolves to.
- Any change triggers a notification:
- NS added to or removed from the delegation.
- NS IP address changed (glue record change).
- NS address change: a nameserver that stays in the delegation
resolves to different addresses than on the previous check. A
nameserver added or removed gets only the NS change notification.
When the lookup of a nameserver's addresses fails or finds none,
its previous addresses are kept and nothing is sent.
### DNS Hostname Monitoring (Subdomains)
@@ -139,6 +144,8 @@ includes:
- **DNS record changes**: Which hostname, which nameserver, what record
type, old values, new values.
- **DNS NS changes**: Which domain, which nameservers were added/removed.
- **NS address changes**: Which domain, which nameserver, its old and
new addresses.
- **NS query failures**: Which nameserver failed, error type (timeout,
SERVFAIL, REFUSED, network error), which hostname/domain affected.
- **NS recoveries**: Which nameserver recovered, which hostname/domain.
@@ -418,6 +425,10 @@ not as a merged view, to enable inconsistency detection.
"domains": {
"example.com": {
"nameservers": ["ns1.example.com.", "ns2.example.com."],
"nameserverAddresses": {
"ns1.example.com.": ["192.0.2.53", "2001:db8::53"],
"ns2.example.com.": ["198.51.100.53"]
},
"lastChecked": "2026-02-19T12:00:00Z"
}
},
@@ -481,6 +492,10 @@ A nameserver that answers NXDOMAIN or with no records has status `ok` and
empty `records`. A nameserver whose query failed has status `error`, empty
`records`, and the reason in `error`.
`nameserverAddresses` lists, by nameserver, the sorted addresses its name
resolves to. A state file without it loads, and the next check fills it in
without a notification.
---
## Entrypoints