Files
dnswatcher/TODO.md
T
sneak 43931fb9ac
check / check (push) Failing after 1m23s
resolver: query a hostname at its own zone's servers (closes #189)
A hostname's nameservers came from its last two labels, so a name under
co.uk was asked at the co.uk servers and a name in a delegated subdomain
at the parent's servers; both only refer onward. The hostname now goes
through FindAuthoritativeNameservers, which follows delegations for the
name and walks up its labels until it finds the zone it is in.

followDelegation now stops at an authoritative reply: that server holds
the zone, so its reply is not a referral. Without this a CNAME answered
with the zone's NS records in the authority section, as Route 53 does,
was followed as a referral until the delegation limit.

Model: opus-5-5
2026-10-01 21:12:40 +00:00

120 lines
6.8 KiB
Markdown

# 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.md` changes 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
nameserver IP address changes: https://git.eeqj.de/sneak/dnswatcher/issues/105
# Completed Steps
- 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: 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-For` is 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 `error` with the
reason, and NS failure and NS recovery are notified (closes #104).
- 2026-10-01: a `DNSWATCHER_DNS_INTERVAL` or `DNSWATCHER_TLS_INTERVAL` that is
not a positive duration stops startup; empty means the default (closes #177).
- 2026-10-01: `/metrics` allows 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 docker` reports the `git describe`
version, not `dev`, 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-precommit` asks git for the repository's git
directory, so `make hooks` also works where `.git` is a file (closes #129).
- 2026-10-01: `TODO.md` brought 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/state` and `internal/watcher` no longer export test-only
constructors: two moved to `export_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 `dnswatcher` and 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 lint` fails when program code imports it (closes #164).
- 2026-09-29: `.golangci.yml` re-fetched from `sneak/prompts`, with
`gomodguard_v2` and the org `depguard` `test-support` rule (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/cibuild` and
`script/docker` pass `--no-cache-filter=lint,builder` (closes #115).
- 2026-09-28: the server timeout test drives `Run` and checks the timeouts on
the `http.Server` it serves (closes #120).
- 2026-09-28: upaas deploy readiness: the image runs as user `dnswatcher` with a
`HEALTHCHECK`; README "Running under upaas" (closes #147).
- 2026-09-21: added behavioural tests for `internal/globals`,
`internal/healthcheck`, and `internal/logger` (closes #110).
- 2026-09-21: `go mod tidy` dropped the redundant `golang.org/x/sync`
`// indirect` line so `script/bootstrap` leaves a clean tree (#132)
- 2026-08-10: comment-only corrections to `script/bootstrap`, `script/cibuild`
and `Dockerfile.lint`; no behaviour changed.
- 2026-08-10: MIT `LICENSE` added 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/lint` builds
`Dockerfile.lint`, and the root `Dockerfile` has 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.Server` sets all four socket timeouts; `WriteTimeout` stays
above the 60s handler timeout (#99).
- 2026-08-09: `SecurityHeaders()` middleware sets HSTS, CSP and the other
security headers `REPO_POLICIES.md` requires on every response.
- 2026-08-07: golangci-lint bumped to v2.12.2 and `.golangci.yml` set to the org
config; fixed the resulting `goconst`, `dupl` and `lll` findings.
- 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
# Future Steps
- `DNSWATCHER_SENTRY_DSN` does nothing:
https://git.eeqj.de/sneak/dnswatcher/issues/107
- trial run of the finished image:
https://git.eeqj.de/sneak/dnswatcher/issues/149
- 1.0 readiness: run it with a real config and read the logs:
https://git.eeqj.de/sneak/dnswatcher/issues/66
- `goimports` in `make fmt-check`, Markdown formatting:
https://git.eeqj.de/sneak/dnswatcher/issues/119
- final state save at shutdown: https://git.eeqj.de/sneak/dnswatcher/issues/114
- README accuracy sweep: https://git.eeqj.de/sneak/dnswatcher/issues/108
- README sections required by policy:
https://git.eeqj.de/sneak/dnswatcher/issues/173
- fixed root server order: https://git.eeqj.de/sneak/dnswatcher/issues/138
- review toward 1.0: https://git.eeqj.de/sneak/dnswatcher/issues/144