internal DNS: nodes find each other via BIND populated by octodns (#785) #1146

Merged
kiara merged 3 commits from kiara/fediversity:785-nodes-find-each-other into main 2026-06-29 18:32:45 +02:00
Owner

Closes #785 (and stands up the #200 internal DNS node).

What

Nodes in the hosting-provider group can now resolve each other by FQDN. A BIND named master for abundos.eu runs in the group; the existing octodns-zone effect renders one A/AAAA record per group node from the group's machines data and pushes them into the live daemon via RFC2136 dynamic update. Other group nodes point networking.nameservers at the BIND node.

This is declarative, deploy-time discovery: the zone is a pure function of the data model, so adding a node or changing its IP is a redeploy, not a hand-edited zone file. No runtime service-discovery mesh. The bind.nix header documents when a runtime system (etcd+CoreDNS or Consul) would instead be the better fit -- once membership churns between deploys or resolution must be health-aware.

Changes

  • src/effects/default.nix -- new bind provider on octodns-zone (octodns_bind.Rfc2136Provider, TSIG key_secret via the secretFiles env-ref mechanism, renders key_secret: env/BIND_KEY_SECRET).
  • src/applications/hosting-provider/bind/default.nix + bind.nix -- thin app + NixOS BIND master, RFC2136 allow-update { key octodns; }, TSIG key included from out-of-band /var/lib/named/octodns.key, writable zone dir so dynamic updates persist.
  • src/applications/hosting-provider/internal-dns.nix -- group resolver module (nameservers = mkBefore [ bindIpv4 bindIpv6 ]), wired per-node in hosts-common.nix, gated on the group having a bind node and excluding the bind node itself (no forwarder self-loop). Upstream Procolix resolvers kept as fallback.
  • src/setups/groups/hosting-provider.nix -- bind machine (network.name = "ns1"), mkZone helper (skips null/0.0.0.0/:: placeholders) + exported zone.
  • src/setups/hosts-common.nix -- octodns effect wiring mirroring the netbox block, surfacing octodns.{validate,sync}.
  • checks/integrations/octodns/nixosTest.nix -- group-derived-zone build-time assert + live subtests: TSIG-signed AXFR + RFC2136 push into a running bind, then cross-node dig +short fedi201.abundos.eu peer resolution. Existing powerdns subtests retained (moved off :53 to :5300, only its :8081 API is used).

Test

integrations-octodns is green on fediversity-ci (117.75s), including the live RFC2136 update (signer "octodns" approved, adding an RR at 'fedi201.abundos.eu' A 95.215.187.201) and the peer node resolving fedi201.abundos.eu cross-network.

Flag for review

  • The bind node IP (95.215.187.200 / 2a00:51c0:13:1305::200) is a placeholder allocation -- confirm with the operator.
  • Production setups/nixos/networking.nix disables the NixOS firewall and uses a static default-drop nftables ruleset with no port 53. A real deploy also needs an nftables rule opening 53 scoped to the internal subnet (not cluster-wide); the per-app networking.firewall.allowed*Ports set here is a no-op there.
  • The TSIG key is delivered out-of-band on both the bind node and the deployer (never baked into the store).

Disclaimer: I used a coding agent in the creation of this patch.

Closes #785 (and stands up the #200 internal DNS node). ## What Nodes in the hosting-provider group can now resolve each other by FQDN. A BIND `named` master for `abundos.eu` runs in the group; the existing `octodns-zone` effect renders one A/AAAA record per group node from the group's `machines` data and pushes them into the live daemon via RFC2136 dynamic update. Other group nodes point `networking.nameservers` at the BIND node. This is declarative, deploy-time discovery: the zone is a pure function of the data model, so adding a node or changing its IP is a redeploy, not a hand-edited zone file. No runtime service-discovery mesh. The `bind.nix` header documents when a runtime system (`etcd`+CoreDNS or Consul) would instead be the better fit -- once membership churns between deploys or resolution must be health-aware. ## Changes - `src/effects/default.nix` -- new `bind` provider on `octodns-zone` (`octodns_bind.Rfc2136Provider`, TSIG `key_secret` via the `secretFiles` env-ref mechanism, renders `key_secret: env/BIND_KEY_SECRET`). - `src/applications/hosting-provider/bind/default.nix` + `bind.nix` -- thin app + NixOS BIND master, RFC2136 `allow-update { key octodns; }`, TSIG key `include`d from out-of-band `/var/lib/named/octodns.key`, writable zone dir so dynamic updates persist. - `src/applications/hosting-provider/internal-dns.nix` -- group resolver module (`nameservers = mkBefore [ bindIpv4 bindIpv6 ]`), wired per-node in `hosts-common.nix`, gated on the group having a bind node and excluding the bind node itself (no forwarder self-loop). Upstream Procolix resolvers kept as fallback. - `src/setups/groups/hosting-provider.nix` -- `bind` machine (`network.name = "ns1"`), `mkZone` helper (skips null/`0.0.0.0`/`::` placeholders) + exported `zone`. - `src/setups/hosts-common.nix` -- octodns effect wiring mirroring the netbox block, surfacing `octodns.{validate,sync}`. - `checks/integrations/octodns/nixosTest.nix` -- group-derived-zone build-time assert + live subtests: TSIG-signed AXFR + RFC2136 push into a running bind, then cross-node `dig +short fedi201.abundos.eu` peer resolution. Existing powerdns subtests retained (moved off :53 to :5300, only its :8081 API is used). ## Test `integrations-octodns` is green on fediversity-ci (117.75s), including the live RFC2136 update (`signer "octodns" approved`, `adding an RR at 'fedi201.abundos.eu' A 95.215.187.201`) and the peer node resolving `fedi201.abundos.eu` cross-network. ## Flag for review - The bind node IP (`95.215.187.200` / `2a00:51c0:13:1305::200`) is a placeholder allocation -- confirm with the operator. - Production `setups/nixos/networking.nix` disables the NixOS firewall and uses a static default-drop `nftables` ruleset with no port 53. A real deploy also needs an nftables rule opening 53 scoped to the internal subnet (not cluster-wide); the per-app `networking.firewall.allowed*Ports` set here is a no-op there. - The TSIG key is delivered out-of-band on both the bind node and the deployer (never baked into the store). Disclaimer: I used a coding agent in the creation of this patch.
kiara force-pushed 785-nodes-find-each-other from 600d020566
Some checks failed
nixosConfigurations-dev-forgejo / dev-forgejo (pull_request) Successful in 13s
nixosConfigurations-hosting-provider-api / hosting-provider-api (pull_request) Successful in 15s
nixosConfigurations-dev-forgejo-runner / dev-forgejo-runner (pull_request) Successful in 17s
nixosConfigurations-hosting-provider-authelia / hosting-provider-authelia (pull_request) Successful in 19s
devShells-default / default (pull_request) Successful in 22s
nixosConfigurations-hosting-provider-bind / hosting-provider-bind (pull_request) Successful in 18s
nix-unit-contracts-lib / contracts-lib (pull_request) Successful in 23s
checks-deployment-nixos-hosts / deployment-nixos-hosts (pull_request) Successful in 29s
nix-unit-effects-common-lib / effects-common-lib (pull_request) Successful in 24s
nixosConfigurations-hosting-provider-garage / hosting-provider-garage (pull_request) Successful in 15s
nixosConfigurations-hosting-provider-incus / hosting-provider-incus (pull_request) Successful in 14s
nixosConfigurations-hosting-provider-monitoring / hosting-provider-monitoring (pull_request) Successful in 14s
nixosConfigurations-hosting-provider-lldap / hosting-provider-lldap (pull_request) Successful in 19s
nix-unit-effects-tf-common-conversion / effects-tf-common-conversion (pull_request) Successful in 12s
nixosConfigurations-hosting-provider-netbox / hosting-provider-netbox (pull_request) Successful in 15s
nixosConfigurations-hosting-provider-openbao / hosting-provider-openbao (pull_request) Successful in 13s
checks-integrations-octodns / integrations-octodns (pull_request) Successful in 43s
nixosConfigurations-hosting-provider-otel-collector / hosting-provider-otel-collector (pull_request) Successful in 14s
nix-unit-lib-data-model / lib-data-model (pull_request) Successful in 21s
nix-unit-lib-function / lib-function (pull_request) Successful in 21s
nixosConfigurations-hosting-provider-panel / hosting-provider-panel (pull_request) Successful in 17s
nixosConfigurations-hosting-provider-spire / hosting-provider-spire (pull_request) Successful in 16s
nixosConfigurations-hosting-provider-postgresql / hosting-provider-postgresql (pull_request) Successful in 20s
nix-unit-lib-renames-for-source / lib-renames-for-source (pull_request) Successful in 10s
nix-unit-lib-lib / lib-lib (pull_request) Successful in 22s
nix-unit-resources-garage-forward-compat / resources-garage-forward-compat (pull_request) Successful in 9s
nixosConfigurations-hosting-provider-terraform-backend / hosting-provider-terraform-backend (pull_request) Successful in 17s
nixosConfigurations-hosting-provider-valkey / hosting-provider-valkey (pull_request) Successful in 18s
nixosConfigurations-hosting-provider-windmill / hosting-provider-windmill (pull_request) Successful in 16s
nixosConfigurations-operator-authelia / operator-authelia (pull_request) Successful in 16s
nixosConfigurations-operator-lldap / operator-lldap (pull_request) Successful in 15s
nix-unit-resources-redis-port / resources-redis-port (pull_request) Successful in 8s
nixosConfigurations-operator-mastodon / operator-mastodon (pull_request) Successful in 15s
nix-unit-resources-generateFiles / resources-generateFiles (pull_request) Successful in 22s
nixosConfigurations-operator-combined / operator-combined (pull_request) Successful in 25s
nixosConfigurations-operator-peertube / operator-peertube (pull_request) Successful in 16s
nixosConfigurations-operator-pixelfed / operator-pixelfed (pull_request) Successful in 15s
nixosConfigurations-operator-postgresql / operator-postgresql (pull_request) Successful in 15s
nix-unit-resources-otel / resources-otel (pull_request) Successful in 28s
nixosConfigurations-operator-smtp / operator-smtp (pull_request) Successful in 15s
nixosConfigurations-operator-valkey / operator-valkey (pull_request) Successful in 15s
nix-unit-resources-secrets / resources-secrets (pull_request) Successful in 19s
Nix flake completeness check / _complete (pull_request) Successful in 2m4s
checks-contracts-chaining / contracts-chaining (pull_request) Successful in 10s
checks-contracts-cross-node / contracts-cross-node (pull_request) Successful in 11s
checks-contracts-filebackup-hardcoded-file-backup / contracts-filebackup-hardcoded-file-backup (pull_request) Successful in 12s
checks-contracts-filesecrets-hardcoded-secret / contracts-filesecrets-hardcoded-secret (pull_request) Successful in 9s
checks-contracts-generatefiles-vars-openbao / contracts-generatefiles-vars-openbao (pull_request) Successful in 9s
checks-contracts-generatefiles-vars / contracts-generatefiles-vars (pull_request) Successful in 9s
checks-contracts-ldap-lldap / contracts-ldap-lldap (pull_request) Successful in 9s
checks-contracts-ldap-openldap / contracts-ldap-openldap (pull_request) Successful in 10s
checks-contracts-oidc-dex / contracts-oidc-dex (pull_request) Successful in 10s
checks-contracts-postgresql / contracts-postgresql (pull_request) Successful in 9s
checks-contracts-redis-valkey / contracts-redis-valkey (pull_request) Successful in 9s
checks-contracts-s3-minio / contracts-s3-minio (pull_request) Successful in 9s
checks-contracts-smtp-maddy / contracts-smtp-maddy (pull_request) Successful in 9s
checks-contracts-smtp-opensmtpd / contracts-smtp-opensmtpd (pull_request) Successful in 10s
checks-contracts-ssl-self-signed / contracts-ssl-self-signed (pull_request) Successful in 10s
checks-contracts-streamingbackup-hardcoded / contracts-streamingbackup-hardcoded (pull_request) Successful in 11s
checks-contracts-systemd-openbaod / contracts-systemd-openbaod (pull_request) Successful in 14s
checks-panel-docs / panel-docs (pull_request) Successful in 12s
checks-resources-secrets-agenix / resources-secrets-agenix (pull_request) Successful in 14s
checks-test-otel-wiring / test-otel-wiring (pull_request) Successful in 13s
flake-show / flake-show (pull_request) Successful in 4m57s
checks-test-valkey-service / test-valkey-service (pull_request) Successful in 11s
checks-treefmt / treefmt (pull_request) Successful in 12s
checks-deployment-tf-incus-hosts / deployment-tf-incus-hosts (pull_request) Successful in 6m25s
checks-deployment-tf-hosts / deployment-tf-hosts (pull_request) Successful in 9m1s
checks-core-docs / core-docs (pull_request) Successful in 9m6s
checks-deployment-ssh-hosts / deployment-ssh-hosts (pull_request) Successful in 14m25s
checks-test-monitoring-storage / test-monitoring-storage (pull_request) Failing after 16m9s
checks-integrations-spire-incus / integrations-spire-incus (pull_request) Successful in 4m56s
checks-apps-api / apps-api (pull_request) Failing after 24m12s
checks-apps-tf / apps-tf (pull_request) Successful in 58m28s
checks-apps-tf-incus / apps-tf-incus (pull_request) Has been cancelled
to de7c2e76f6
All checks were successful
checks-contracts-chaining / contracts-chaining (pull_request) Successful in 14s
nixosConfigurations-dev-forgejo-runner / dev-forgejo-runner (pull_request) Successful in 18s
nixosConfigurations-dev-forgejo / dev-forgejo (pull_request) Successful in 18s
nixosConfigurations-hosting-provider-api / hosting-provider-api (pull_request) Successful in 17s
nixosConfigurations-hosting-provider-authelia / hosting-provider-authelia (pull_request) Successful in 19s
devShells-default / default (pull_request) Successful in 22s
nixosConfigurations-hosting-provider-bind / hosting-provider-bind (pull_request) Successful in 19s
nix-unit-contracts-lib / contracts-lib (pull_request) Successful in 25s
checks-deployment-nixos-hosts / deployment-nixos-hosts (pull_request) Successful in 31s
nix-unit-effects-common-lib / effects-common-lib (pull_request) Successful in 26s
checks-contracts-cross-node / contracts-cross-node (pull_request) Successful in 15s
nixosConfigurations-hosting-provider-garage / hosting-provider-garage (pull_request) Successful in 18s
nix-unit-effects-tf-common-conversion / effects-tf-common-conversion (pull_request) Successful in 12s
nixosConfigurations-hosting-provider-incus / hosting-provider-incus (pull_request) Successful in 17s
nixosConfigurations-hosting-provider-monitoring / hosting-provider-monitoring (pull_request) Successful in 17s
nixosConfigurations-hosting-provider-lldap / hosting-provider-lldap (pull_request) Successful in 20s
checks-integrations-octodns / integrations-octodns (pull_request) Successful in 41s
nixosConfigurations-hosting-provider-netbox / hosting-provider-netbox (pull_request) Successful in 17s
checks-contracts-filebackup-hardcoded-file-backup / contracts-filebackup-hardcoded-file-backup (pull_request) Successful in 16s
nixosConfigurations-hosting-provider-openbao / hosting-provider-openbao (pull_request) Successful in 13s
nix-unit-lib-data-model / lib-data-model (pull_request) Successful in 23s
nixosConfigurations-hosting-provider-otel-collector / hosting-provider-otel-collector (pull_request) Successful in 15s
nix-unit-lib-function / lib-function (pull_request) Successful in 21s
nixosConfigurations-hosting-provider-panel / hosting-provider-panel (pull_request) Successful in 15s
nix-unit-lib-lib / lib-lib (pull_request) Successful in 22s
nixosConfigurations-hosting-provider-spire / hosting-provider-spire (pull_request) Successful in 17s
nix-unit-lib-renames-for-source / lib-renames-for-source (pull_request) Successful in 10s
nix-unit-resources-garage-forward-compat / resources-garage-forward-compat (pull_request) Successful in 8s
nixosConfigurations-hosting-provider-postgresql / hosting-provider-postgresql (pull_request) Successful in 20s
checks-contracts-filesecrets-hardcoded-secret / contracts-filesecrets-hardcoded-secret (pull_request) Successful in 13s
nixosConfigurations-hosting-provider-valkey / hosting-provider-valkey (pull_request) Successful in 19s
nixosConfigurations-hosting-provider-terraform-backend / hosting-provider-terraform-backend (pull_request) Successful in 20s
nix-unit-resources-redis-port / resources-redis-port (pull_request) Successful in 8s
nixosConfigurations-hosting-provider-windmill / hosting-provider-windmill (pull_request) Successful in 19s
checks-contracts-generatefiles-vars-openbao / contracts-generatefiles-vars-openbao (pull_request) Successful in 13s
nixosConfigurations-operator-authelia / operator-authelia (pull_request) Successful in 17s
nix-unit-resources-generateFiles / resources-generateFiles (pull_request) Successful in 23s
nixosConfigurations-operator-combined / operator-combined (pull_request) Successful in 24s
nixosConfigurations-operator-lldap / operator-lldap (pull_request) Successful in 17s
nixosConfigurations-operator-mastodon / operator-mastodon (pull_request) Successful in 15s
nixosConfigurations-operator-peertube / operator-peertube (pull_request) Successful in 15s
checks-contracts-generatefiles-vars / contracts-generatefiles-vars (pull_request) Successful in 12s
nix-unit-resources-otel / resources-otel (pull_request) Successful in 28s
nix-unit-resources-secrets / resources-secrets (pull_request) Successful in 19s
nixosConfigurations-operator-pixelfed / operator-pixelfed (pull_request) Successful in 15s
nixosConfigurations-operator-valkey / operator-valkey (pull_request) Successful in 14s
nixosConfigurations-operator-postgresql / operator-postgresql (pull_request) Successful in 15s
nixosConfigurations-operator-smtp / operator-smtp (pull_request) Successful in 14s
checks-contracts-ldap-lldap / contracts-ldap-lldap (pull_request) Successful in 12s
checks-contracts-ldap-openldap / contracts-ldap-openldap (pull_request) Successful in 10s
Nix flake completeness check / _complete (pull_request) Successful in 2m10s
checks-contracts-oidc-dex / contracts-oidc-dex (pull_request) Successful in 9s
checks-contracts-postgresql / contracts-postgresql (pull_request) Successful in 9s
checks-contracts-redis-valkey / contracts-redis-valkey (pull_request) Successful in 9s
checks-contracts-s3-minio / contracts-s3-minio (pull_request) Successful in 9s
checks-contracts-smtp-maddy / contracts-smtp-maddy (pull_request) Successful in 10s
checks-contracts-smtp-opensmtpd / contracts-smtp-opensmtpd (pull_request) Successful in 9s
checks-contracts-ssl-self-signed / contracts-ssl-self-signed (pull_request) Successful in 8s
checks-contracts-streamingbackup-hardcoded / contracts-streamingbackup-hardcoded (pull_request) Successful in 9s
checks-panel-docs / panel-docs (pull_request) Successful in 6s
checks-contracts-systemd-openbaod / contracts-systemd-openbaod (pull_request) Successful in 9s
checks-resources-secrets-agenix / resources-secrets-agenix (pull_request) Successful in 9s
checks-test-monitoring-storage / test-monitoring-storage (pull_request) Successful in 9s
checks-test-otel-wiring / test-otel-wiring (pull_request) Successful in 9s
checks-test-valkey-service / test-valkey-service (pull_request) Successful in 9s
checks-treefmt / treefmt (pull_request) Successful in 9s
flake-show / flake-show (pull_request) Successful in 4m38s
checks-deployment-tf-incus-hosts / deployment-tf-incus-hosts (pull_request) Successful in 5m20s
checks-core-docs / core-docs (pull_request) Successful in 8m5s
checks-deployment-tf-hosts / deployment-tf-hosts (pull_request) Successful in 8m11s
checks-deployment-ssh-hosts / deployment-ssh-hosts (pull_request) Successful in 13m2s
checks-apps-tf / apps-tf (pull_request) Successful in 57m18s
checks-integrations-spire-incus / integrations-spire-incus (pull_request) Successful in 4m35s
checks-apps-api / apps-api (pull_request) Successful in 42m13s
checks-apps-tf-incus / apps-tf-incus (pull_request) Successful in 44m36s
2026-06-29 14:37:18 +02:00
Compare
kiara changed title from WIP: internal DNS: nodes find each other via BIND populated by octodns (#785) to internal DNS: nodes find each other via BIND populated by octodns (#785) 2026-06-29 16:38:24 +02:00
kiara merged commit 1ea27d64d0 into main 2026-06-29 18:32:45 +02:00
kiara deleted branch 785-nodes-find-each-other 2026-06-29 18:32:45 +02:00
Sign in to join this conversation.
No reviewers
fediversity/developers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
fediversity/fediversity!1146
No description provided.