check / check (push) Failing after 2m13s
Every resolution walked the root servers in a fixed order, so a.root-servers.net got every first query and its timeouts were paid on every lookup. Each list of servers the resolver walks is now walked in a random order from rand.Shuffle, chosen anew each time; a server that does not reply, refuses, or gives an error reply or a referral that leads no closer is still passed over for the next. When a referral names a zone's nameservers without their addresses, all of them are now looked up, not only the first that resolves, so the zone is not given up because the first nameserver whose address was found gave no usable reply. No test fails if the walk stops shuffling: which server a live query reached is not observable. Model: opus-5-5
8.2 KiB
8.2 KiB
Workflow
- branch (from
next) - do the work in Next Step
- move Next Step to the top of Completed Steps
- move the top item of Future Steps into Next Step
- commit (
TODO.mdchanges in the same commit as the work) - push
- open a PR against
next
Status
pre-1.0. No git tags. Work lands on next by PR. Open work for 1.0 is tracked
on the 1.0 milestone: https://git.eeqj.de/sneak/dnswatcher/milestone/7
Next Step
trial run of the finished image: #149
Completed Steps
- 2026-10-02: the resolver tries root servers, and every other server list it walks, in a random order each time, not always from the top (closes #138).
- 2026-10-02: a name listed more than once in
DNSWATCHER_TARGETS, in any letter case or with a trailing dot, is watched once (closes #207). - 2026-10-01: README checked against the code and corrected: metrics, CORS, notification retries, CNAMEs, state file fields, Design tree (closes #108).
- 2026-10-01: a certificate within the expiry warning period is warned about on every TLS check, where some checks used to skip it at random (closes #204).
- 2026-10-01: a domain's NS set is its delegation from the parent zone's servers, not whichever of its own servers answered first (closes #200).
- 2026-10-01: README has Getting Started, Rationale and TODO sections, and its Architecture section is now Design, in the order policy sets (closes #173).
- 2026-10-01: a zone's server that answers SERVFAIL or a referral leading no closer is passed over for the next, as one that times out is (closes #197).
- 2026-10-01: when none of a configured name's nameservers answered, the port state saved for its addresses is kept, not removed (closes #193).
- 2026-10-01:
ResolveIPAddressesreturns an error, not no addresses, when no nameserver of the name's zone answered (closes #190). - 2026-10-01:
make fmtandmake fmt-checkcover Markdown with prettier, run in Docker at the version pinned byyarn.lock(closes #119). - 2026-10-01:
make fmt-checkfails on a filegoimportswould change; both format scripts rungoimportsat its pinned commit, not fromPATH(#119). - 2026-10-01: a hostname is queried at the servers of the zone it is in, found by following delegations for the name, not its last two labels (closes #189).
- 2026-10-01: each nameserver's addresses are saved with its domain, and a change while it stays in the delegation is notified (closes #105).
- 2026-10-01: the watcher saves state when it stops, and shutdown waits for that save, so it no longer relies on the state's own stop hook (closes #114).
- 2026-10-01:
DNSWATCHER_SENTRY_DSNreports panics in HTTP handlers to Sentry, and a DSN Sentry cannot parse stops startup (closes #107). - 2026-10-01: a port or TLS check that shutdown cuts short saves nothing and sends no notification, as a cut-short DNS lookup already did (closes #185).
- 2026-10-01: the client address from
X-Forwarded-Foris the last entry that is not a trusted proxy, not the first, which the client sets (closes #181). - 2026-10-01: a nameserver that does not answer is saved as
errorwith the reason, and NS failure and NS recovery are notified (closes #104). - 2026-10-01: a
DNSWATCHER_DNS_INTERVALorDNSWATCHER_TLS_INTERVALthat is not a positive duration stops startup; empty means the default (closes #177). - 2026-10-01:
/metricsallows each client address 30 requests a minute, counted before Basic Auth, and answers 429 beyond that (closes #101). - 2026-10-01: the image built by
make dockerreports thegit describeversion, notdev, and the startup log now shows it (closes #109). - 2026-10-01: two notify shutdown tests always release the delivery they hold, so a drain that returns early fails them instead of hanging (closes #176).
- 2026-10-01:
script/install-precommitasks git for the repository's git directory, somake hooksalso works where.gitis a file (closes #129). - 2026-10-01:
TODO.mdbrought up to date: open issues listed by URL, every Completed Steps entry cut to at most two lines (closes #146). - 2026-10-01: wildcard CORS now applies only to the public routes, not to
/metrics, and allows only the methods they serve (closes #100). - 2026-10-01:
internal/stateandinternal/watcherno longer export test-only constructors: two moved toexport_test.go, one is deleted (closes #111). - 2026-10-01: notify shutdown tests use one timing constant per meaning, name the bound they check, and require the drain's debug line (closes #116).
- 2026-09-29: the entrypoint chowns the data directory to
dnswatcherand runs dnswatcher as that user, so a host bind mount needs no chown (closes #166). - 2026-09-29: the live-DNS test package is renamed
internal/livednstest;make lintfails when program code imports it (closes #164). - 2026-09-29:
.golangci.ymlre-fetched fromsneak/prompts, withgomodguard_v2and the orgdepguardtest-supportrule (closes #123). - 2026-09-29: watcher and resolver tests that look something up in DNS use the real resolver against live DNS servers (closes #159).
- 2026-09-28: the inconsistency alert is sent once, when two nameservers start to disagree; every pair of nameservers is compared (closes #158).
- 2026-09-28: DNS names in record values (CNAME, MX, SRV and NS targets) are lower-cased, so letter case alone is not a change (closes #157).
- 2026-09-28: lint and tests run on every build:
script/cibuildandscript/dockerpass--no-cache-filter=lint,builder(closes #115). - 2026-09-28: the server timeout test drives
Runand checks the timeouts on thehttp.Serverit serves (closes #120). - 2026-09-28: upaas deploy readiness: the image runs as user
dnswatcherwith aHEALTHCHECK; README "Running under upaas" (closes #147). - 2026-09-21: added behavioural tests for
internal/globals,internal/healthcheck, andinternal/logger(closes #110). - 2026-09-21:
go mod tidydropped the redundantgolang.org/x/sync// indirectline soscript/bootstrapleaves a clean tree (#132) - 2026-08-10: comment-only corrections to
script/bootstrap,script/cibuildandDockerfile.lint; no behaviour changed. - 2026-08-10: MIT
LICENSEadded at the repository root; the README's first line and License section name the licence. - 2026-08-10: policy scaffold present:
REPO_POLICIES.md,.editorconfig,.dockerignore, CI workflow,make fmt-check,make docker,make hooks. - 2026-08-10: Go's test cache disabled in
script/test(-count=1), so every run queries live DNS; a failed run is rerun with-v. - 2026-08-10: live-DNS tests made robust rather than gated (#93): a limit on concurrent lookups, retries, and a quorum across nameservers.
- 2026-08-10: all linting moved into Docker:
script/lintbuildsDockerfile.lint, and the rootDockerfilehas its own lint stage. - 2026-08-09: in-flight notification deliveries are drained at shutdown, bounded by the shutdown deadline (#106).
- 2026-08-09:
http.Serversets all four socket timeouts;WriteTimeoutstays above the 60s handler timeout (#99). - 2026-08-09:
SecurityHeaders()middleware sets HSTS, CSP and the other security headersREPO_POLICIES.mdrequires on every response. - 2026-08-07: golangci-lint bumped to v2.12.2 and
.golangci.ymlset to the org config; fixed the resultinggoconst,duplandlllfindings. - 2026-07-07 Adopted scripts-to-rule-them-all:
script/entrypoints, Makefile shims, README Entrypoints section - 2026-02-20: iterative DNS resolver implemented
- 2026-02-20: CI actions and go install refs pinned to commit SHAs; Gitea Actions workflow added
- 2026-02-20: watcher monitoring orchestrator merged to main (#8)
- 2026-02-20: DOMAINS/HOSTNAMES unified into single TARGETS config (#11)
- 2026-02-19: TCP port connectivity checker, made concurrent with port validation; gosec G704 SSRF findings fixed without suppression
- 2026-02-19: TLS certificate inspector with no-peer-certificates error path and IP SANs
- 2026-02-19: gosec SSRF and formatting fixes on main
- 2026-02-19: initial scaffold with per-nameserver DNS monitoring model