feat(router): isolated guest VLAN + LAN /23 #554

Open
lytedev wants to merge 1 commit from router-guest-vlan into main
Owner

Sets up an isolated, internet-only guest WiFi network (for hosting a home exchange) and tightens the LAN subnet.

What

  • New opt-in lyte.router.guest module block: an internet-only guest network over a tagged VLAN (default VLAN 199, 192.168.199.0/24).
  • APs tag a guest SSID with the VLAN id; the router routes it to WAN, and the nftables policy drop walls it off from the LAN and from the router itself (only DHCP allowed back). Guests get upstream DNS directly, so they never touch the router's internal resolver.
  • Tighten the LAN /16/23 (512 addresses) on the router host.

Why router-enforced (not UniFi GUI)

The network has no UniFi gateway — the self-hosted controller on beefcake only manages APs. UniFi's built-in guest isolation needs a gateway, so true L3 isolation has to be enforced on the NixOS router. The AP just VLAN-tags the SSID.

Implementation

  • systemd-networkd VLAN netdev (guest) tagged onto the LAN trunk.
  • IPv4-only guest network, with inline notes documenting how to add IPv6 parity later (the firewall already covers v6).
  • dnsmasq DHCP scope matched by the auto-set interface tag; dhcp-option hands guests upstream DNS.
  • nftables: guest → WAN accept, guest → router DHCP-only.

The /16/23 change is safe: DHCP already hands out a /24, so existing 192.168.0.x clients are unaffected; this just removes the over-broad default and clears the overlap with the guest range.

Validation

  • nix build .#nixosConfigurations.router.config.system.build.toplevel passes (exit 0), including the nftables checkRuleset at build time.

Follow-up (post-merge/deploy)

  • Deploy: nix develop -c deploy -s --targets .#router (management rides tailscale0, so the LAN re-addressing won't drop the control connection; magic rollback as safety net).
  • Then in UniFi: create the guest SSID, set VLAN 199, enable Client Device Isolation (do not use the "Guest Network" toggle — no gateway to honor it).
Sets up an isolated, internet-only guest WiFi network (for hosting a home exchange) and tightens the LAN subnet. ## What - New opt-in `lyte.router.guest` module block: an internet-only guest network over a tagged VLAN (default **VLAN 199**, `192.168.199.0/24`). - APs tag a guest SSID with the VLAN id; the router routes it to WAN, and the nftables `policy drop` walls it off from the LAN and from the router itself (only DHCP allowed back). Guests get upstream DNS directly, so they never touch the router's internal resolver. - Tighten the LAN `/16` → `/23` (512 addresses) on the `router` host. ## Why router-enforced (not UniFi GUI) The network has **no UniFi gateway** — the self-hosted controller on beefcake only manages APs. UniFi's built-in guest isolation needs a gateway, so true L3 isolation has to be enforced on the NixOS router. The AP just VLAN-tags the SSID. ## Implementation - systemd-networkd VLAN netdev (`guest`) tagged onto the LAN trunk. - IPv4-only guest network, with inline notes documenting how to add IPv6 parity later (the firewall already covers v6). - dnsmasq DHCP scope matched by the auto-set interface tag; `dhcp-option` hands guests upstream DNS. - nftables: `guest → WAN` accept, `guest → router` DHCP-only. The `/16`→`/23` change is safe: DHCP already hands out a `/24`, so existing `192.168.0.x` clients are unaffected; this just removes the over-broad default and clears the overlap with the guest range. ## Validation - `nix build .#nixosConfigurations.router.config.system.build.toplevel` passes (exit 0), including the nftables `checkRuleset` at build time. ## Follow-up (post-merge/deploy) - Deploy: `nix develop -c deploy -s --targets .#router` (management rides tailscale0, so the LAN re-addressing won't drop the control connection; magic rollback as safety net). - Then in UniFi: create the guest SSID, set **VLAN 199**, enable **Client Device Isolation** (do *not* use the "Guest Network" toggle — no gateway to honor it).
feat(router): add isolated guest VLAN; tighten LAN to /23
Some checks failed
/ check-format (push) Successful in 21s
/ build (push) Has been cancelled
2cec8bd126
Add an opt-in `lyte.router.guest` block delivering an internet-only guest
network over a tagged VLAN (default VLAN 199, 192.168.199.0/24). Wireless
APs tag a guest SSID with the VLAN id; the router routes it to WAN while
the nftables `policy drop` walls it off from the LAN and from the router
itself (only DHCP is allowed back). Guests are handed upstream DNS
directly so they never touch the router's internal resolver.

Implemented via a systemd-networkd VLAN netdev tagged onto the LAN trunk,
an IPv4-only guest network (with inline notes for adding IPv6 parity
later), a dnsmasq DHCP scope matched by the interface tag, and two
nftables rules (guest->WAN accept, guest->router DHCP-only). Isolation is
enforced at the router because the network has no UniFi gateway (the
self-hosted controller only manages APs).

Also tighten the LAN from the over-broad /16 default to /23 (512
addresses) on the router host. DHCP already hands out a /24, so existing
clients are unaffected; this frees 192.168.199.0/24 for the guest VLAN
and removes the latent subnet overlap.
lytedev force-pushed router-guest-vlan from 2cec8bd126
Some checks failed
/ check-format (push) Successful in 21s
/ build (push) Has been cancelled
to ef9b368e7f
All checks were successful
/ check-format (push) Successful in 7s
/ build (push) Successful in 19m56s
2026-06-02 09:25:02 -05:00
Compare
All checks were successful
/ check-format (push) Successful in 7s
Required
Details
/ build (push) Successful in 19m56s
Required
Details
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin router-guest-vlan:router-guest-vlan
git switch router-guest-vlan
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
lytedev/nix!554
No description provided.