ADR 0010: Prefer Perimeter Firewall with Dual Ingress for Exposure
Status
Accepted
Context
Three exposure stacks were evaluated:
- Model A — Perimeter firewall (OpenWRT now, upgradable later) owns routing/NAT; Kubernetes hosts two ingress controllers (internal-only and public).
- Model B — Kubernetes-native edge using Gateway API with CNI-integrated data plane (e.g., Cilium) to terminate edge traffic directly on the cluster.
- Model C — Cloud tunnel/overlay (e.g., Cloudflare Tunnel, Tailscale Funnel) to expose services without direct inbound paths.
The homelab prioritizes a clear internal/public boundary, minimal external dependencies, and the ability to swap in a dedicated firewall when hardware/power constraints ease. Existing OpenWRT already acts as the single boundary (see ADR 0009), and split-horizon DNS is assumed (ADR 0003). Identity-first ingress is required for user-facing access (ADR 0006).
Decision Drivers
- Preserve a single, enforceable perimeter where north-south policy and logging live.
- Keep internal ingress paths isolated from public ingress while supporting split-horizon DNS.
- Allow future replacement of OpenWRT with a dedicated firewall without re-architecting cluster ingress.
- Avoid new external dependencies for routine access; tolerate them only as scoped exceptions.
- Fit power/port constraints and current hardware while enabling later VLAN/DMZ phases.
Considered Options
Model A — Perimeter Firewall + Dual Ingress
- Pros: Clear boundary; firewall enforces 80/443 exposure; ingress controllers stay inside the cluster; works with current OpenWRT and future firewall/DMZ; keeps routing off the control plane.
- Cons: Requires hairpin/port-forward rules and VIP management; firewall must forward to cluster nodes.
Model B — Kubernetes-Native Edge (Gateway API + CNI data plane)
- Pros: Uniform policy definition inside K8s; fewer port-forwards; rich L7 features.
- Cons: Pushes the trust boundary into the cluster; cluster health becomes prerequisite for edge routing; complicates future dedicated firewall insertion; higher operational complexity today.
Model C — Cloud Tunnel / Overlay Exposure
- Pros: Quick public exposure; hides home IP; minimal edge config.
- Cons: Adds third-party dependency and opaque failure modes; blurs boundary and bypasses local policy/logging; harder to reason about internal vs. public reachability.
Decision
Adopt Model A (Perimeter firewall + dual ingress):
- Keep routing/NAT/policy on the perimeter firewall (OpenWRT now; replaceable with a dedicated firewall later) and continue to expose only the minimal ports (80/443) required for public ingress.
- Run two ingress controllers in the cluster:
- Internal Ingress: LAN/VPN-only, resolves via split-horizon DNS to an internal VIP.
- Public Ingress: Receives only firewall-forwarded 80/443 traffic to a public VIP; backs the small set of intentionally exposed hostnames.
- Use identity-first auth at ingress per ADR 0006; no generic port-forwarding to services.
- Allow cloud tunnels only as scoped, documented exceptions (e.g., break-glass outbound-only tunnels) with explicit change control.
Consequences
- Boundary Clarity: North-south enforcement, logging, and DDoS controls stay at the perimeter; internal ingress remains shielded from the internet.
- Upgrade Path: A future dedicated firewall or DMZ VLAN can replace OpenWRT without reworking cluster ingress (aligns with the Network Evolution Plan).
- Operational Simplicity: Fewer moving parts at the edge; ingress lifecycle stays inside Kubernetes, where certificates and auth already live.
- Constraints-Friendly: Works within current power/port limits; no requirement to run edge data plane on K8s nodes.
- Risk: Firewall misconfiguration could still overexpose services; requires to be disciplined VIP/reservation management and monitoring of port-forwards.
Implementation Notes / Next Steps
- Reserve VIPs for internal/public ingress in the SERVER/DMZ ranges defined in the Network Evolution Plan.
- Maintain firewall rules: 80/443 to public ingress VIP only; no generic NAT for internal services (per ADR 0005).
- Keep split-horizon DNS records aligned with the two ingress VIPs.
- Document any exception tunnels with owners, scope, and teardown criteria.