Local zones were only editable as mounted files, so operators could not manage DNS entries from the console. Add a Local zones editor backed by a shared Kubernetes ConfigMap, validate master files before saving, scope the pod service account to that ConfigMap, and reload changed zones on every replica while flushing stale cache entries.
This commit is contained in:
1 parent
2a7ac824f7
commit
32f940b763
18 files changed
+727
-36
No files matched your search
@@ -397,13 +397,12 @@ local traffic counted correctly — see STATUS.md for the change note.
|
||||
but there is no zone transfer, so nothing calls it.
|
||||
|
||||
**Zone name from a path.** `localzone.Load` derives each file's origin with
|
||||
`zonefile.OriginFromPath`, which takes the base name and truncates it at the
|
||||
first dot: `zones/lan.zone` and `lan.zone` both become the origin `lan.`
|
||||
(the doc comment on that function says `ads.zone.`, which is wrong — see
|
||||
[Known inconsistencies](#known-inconsistencies)). An explicit `$ORIGIN` inside
|
||||
the file wins, because `Parse` starts from that derived origin and the
|
||||
directive replaces it. Records that fall outside their own zone are dropped
|
||||
(`localzone.add` returns false).
|
||||
`zonefile.OriginFromPath`. Legacy names truncate at the first dot, so
|
||||
`zones/lan.zone` becomes `lan.`. The console marks fully-qualified zone names
|
||||
with `zone--`, so `zone--example.com.zone` becomes `example.com.`. An explicit
|
||||
`$ORIGIN` inside the file wins, because `Parse` starts from that derived origin
|
||||
and the directive replaces it. Records that fall outside their own zone are
|
||||
dropped (`localzone.add` returns false).
|
||||
|
||||
The practical consequence: a *relative* name is qualified with the file's base
|
||||
name, not with the zone you had in mind. In `local.example.zone` (origin
|
||||
@@ -431,6 +430,15 @@ records mean and where they are matched:
|
||||
one-label and deeper wildcards, SRV, TXT). `deploy/zones/local.rpz.zone.example`
|
||||
is a policy zone.
|
||||
|
||||
**Edit zones in the console.** Open **Local zones** to create a zone or edit its
|
||||
RFC 1035 master-file records. In Kubernetes, the editor stores each file in the
|
||||
`fancy-dns-zones` ConfigMap; both replicas watch the projected files and reload
|
||||
them automatically. The API validates every file and its record owners before
|
||||
saving. The pod's service account can read and patch only this ConfigMap. The
|
||||
ConfigMap's `data` is intentionally left out of the GitOps manifest so console
|
||||
edits persist across reconciliation. For a standalone install, manage zone
|
||||
files on disk and reload the configuration.
|
||||
|
||||
## Blocklists
|
||||
|
||||
A source is compiled into rules, and every source is merged into one immutable
|
||||
@@ -662,11 +670,12 @@ Things to know before you apply it:
|
||||
* **No zone transfer.** AXFR/IXFR are not implemented: the master-file parser
|
||||
knows the record types, but nothing serves or accepts a transfer, and
|
||||
`zonefile.SerialNext` is unused.
|
||||
* **No dynamic update.** An UPDATE message passes the engine's shape check
|
||||
* **No RFC 2136 dynamic update.** An UPDATE message passes the engine's shape check
|
||||
(`validate` tolerates `OpcodeUpdate`) and is then handled as an ordinary
|
||||
query. There is no RFC 2136 handling, no journal and no NOTIFY. A local zone
|
||||
only changes when the file changes and the config is reloaded (SIGHUP,
|
||||
`POST /api/settings/reload`, or a restart).
|
||||
query. There is no wire-protocol update handling, journal or NOTIFY. Local
|
||||
zones are editable from the console's **Local zones** page. Kubernetes pods
|
||||
reload changed zone files automatically; standalone file edits need a config
|
||||
reload or restart.
|
||||
* **No HTTP/3** for DoH despite `dns.doh.transport.mode` / `alt_svc`; the
|
||||
listener is h2 with an h2c fallback.
|
||||
* **No certificate automation**: certificates are files on disk, one per
|
||||
@@ -774,11 +783,6 @@ Found while writing this file; each is a to-do, not something fixed here.
|
||||
15. **`internal/config/config.go` (`Valkey.TLS`)** — `cluster.valkey.tls` is
|
||||
never applied; `internal/cluster/cluster.go:dial` builds a plain
|
||||
`redis.Client` with no `TLSConfig`.
|
||||
16. **`internal/zonefile/zonefile.go:525-526` — the `OriginFromPath` doc
|
||||
comment is wrong.** It claims `"rpz/ads.zone"` and `"ads.zone"` both become
|
||||
`"ads.zone."`; the code truncates at the first dot, so both become `"ads."`.
|
||||
The behaviour is what `localzone.Load` and `blocklist.parseRPZFiles` rely
|
||||
on — fix the comment.
|
||||
17. **`internal/zonefile/zonefile.go:1-8` and `:238-243` — the package comment
|
||||
advertises `$INCLUDE`, the parser rejects it** ("`$INCLUDE … is not
|
||||
supported; use blocklist.local_zones or a list source instead`"), and
|
||||
@@ -790,10 +794,6 @@ Found while writing this file; each is a to-do, not something fixed here.
|
||||
Unprivileged use needs the same `sed` rewrite the CI smoke test does
|
||||
(`.github/workflows/ci.yml`, "Smoke test the real binary"), or a port you
|
||||
can bind.
|
||||
19. **`deploy/k8s/10-deployment.yaml` — the comment tells the reader to manage
|
||||
zones "through the admin API (`/api/zones`)", which does not exist.** There
|
||||
is no zone endpoint in `internal/api/api.go:routes`; local zones are edited
|
||||
on disk.
|
||||
20. **`deploy/k8s/20-service.yaml` — the load-balancer comment says to leave
|
||||
the LB health check on the HTTP admin port, but the `fancy-dns-dns`
|
||||
LoadBalancer Service publishes only 53/UDP, 53/TCP and 853/TCP.** The admin
|
||||
|
||||
Reference in new issue
Block a user