feat(web-arm): static outbound IPv6 with Postfix pinned to IPv4 #84

Merged
dominik.polakovics merged 1 commit from afk/81 into main 2026-06-03 17:54:09 +02:00

What

Give web-arm its own outbound IPv6 by statically configuring the Hetzner-routed /64 on enp1s0, without regressing outbound mail.

  • networking.interfaces.enp1s0.ipv6.addresses — static 2a01:4f8:c012:43b::1/64
  • networking.defaultGateway6 — default v6 route via the link-local fe80::1 on enp1s0
  • services.postfix.settings.main.smtp_address_preference = "ipv4" — pin outbound mail to IPv4 in the same change, so Postfix doesn't start preferring an rDNS/SPF-less v6 source for dual-stack MXes (Gmail etc.). The route without the pin is the regression.
  • docs/adr/0010-static-ipv6-on-web-arm.md — records static-over-DHCPv6/SLAAC and the mail-pin rationale.

Notes for the reviewer

  • The issue text referenced services.postfix.config, which does not exist in nixos-25.11 (the module was refactored). Used the current services.postfix.settings.main.* attribute set instead — verified against the channel; the dry-build validates it.
  • The /64 and gateway are opaque values from the Hetzner Cloud console that eval cannot check — please re-confirm 2a01:4f8:c012:43b::1/64 and fe80::1 against the console before merge.
  • Inbound IPv6 / AAAA records are out of scope (tracked in #82 pilot, #83 rollout).

Verification

  • web-arm dry-build passes via the pre-commit hook (:: web-arm OK).
  • Post-deploy (human-verified after merge, not part of this PR): ip -6 route shows default via fe80::1 dev enp1s0; curl -6 from the host reaches the v6 internet; nginx still listening on :::80/:::443; postconf smtp_address_preference reports ipv4 and mail deliverability is unchanged.

Closes #81

## What Give web-arm its own **outbound IPv6** by statically configuring the Hetzner-routed `/64` on `enp1s0`, without regressing outbound mail. - `networking.interfaces.enp1s0.ipv6.addresses` — static `2a01:4f8:c012:43b::1/64` - `networking.defaultGateway6` — default v6 route via the link-local `fe80::1` on `enp1s0` - `services.postfix.settings.main.smtp_address_preference = "ipv4"` — pin outbound mail to IPv4 **in the same change**, so Postfix doesn't start preferring an rDNS/SPF-less v6 source for dual-stack MXes (Gmail etc.). The route without the pin is the regression. - `docs/adr/0010-static-ipv6-on-web-arm.md` — records static-over-DHCPv6/SLAAC and the mail-pin rationale. ## Notes for the reviewer - The issue text referenced `services.postfix.config`, which **does not exist in nixos-25.11** (the module was refactored). Used the current `services.postfix.settings.main.*` attribute set instead — verified against the channel; the dry-build validates it. - The `/64` and gateway are opaque values from the Hetzner Cloud console that eval cannot check — **please re-confirm `2a01:4f8:c012:43b::1/64` and `fe80::1` against the console before merge.** - Inbound IPv6 / `AAAA` records are out of scope (tracked in #82 pilot, #83 rollout). ## Verification - web-arm dry-build passes via the pre-commit hook (`:: web-arm OK`). - Post-deploy (human-verified after merge, not part of this PR): `ip -6 route` shows `default via fe80::1 dev enp1s0`; `curl -6` from the host reaches the v6 internet; nginx still listening on `:::80`/`:::443`; `postconf smtp_address_preference` reports `ipv4` and mail deliverability is unchanged. Closes #81
Declare the Hetzner-routed /64 (2a01:4f8:c012:43b::1/64) and the link-local
default gateway (fe80::1) statically on enp1s0, giving web-arm working
outbound IPv6. Hetzner offers no DHCPv6 and SLAAC is unsuitable on this
forwarding host (RA-acceptance off, MAC-derived address a poor inbound AAAA
target), so the address is declared statically the way cloud-init would.

Pin outbound SMTP to IPv4 in the same change: the new v6 source has no
rDNS/SPF, so Postfix's default (any) would prefer it when delivering to
dual-stack MXes (Gmail etc.) and silently regress deliverability. The route
without the pin is the regression, so they ship together.

Add ADR 0010 recording static-over-DHCPv6/SLAAC and the mail-pin rationale.
Sign in to join this conversation.
No reviewers
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
Cloonar/nixos!84
No description provided.