fix(networking): Windows container egress is unenforceable on WinNAT+Hyper-V — evidence + VLAN recommendation - #142
Open
luthermonson wants to merge 1 commit into
Open
fix(networking): Windows container egress is unenforceable on WinNAT+Hyper-V — evidence + VLAN recommendation#142luthermonson wants to merge 1 commit into
luthermonson wants to merge 1 commit into
Conversation
…yper-V, point to VLAN Metal verification on Windows Server 2025 (build 26100) proved the RFC1918 block ACLs are stored on the HNS endpoint but not enforced, and that no per-container software egress filter is available on this host class. Replace the false 'refusing to start unfirewalled' assurance with an honest, evidenced WARN and a windowsEgressNotEnforced pointer, so the daemon never implies a containment it does not provide. Real containment must be an upstream VLAN.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary — honest negative result
I did NOT achieve a green Windows containment run. After genuine on-metal testing of every software mechanism available on the node, the evidence shows there is no per-container software egress filter that enforces on this host class (Windows Server 2025 build 26100, HNS NAT network, Hyper-V-isolated job containers). Real containment must come from outside the box — an upstream/switch VLAN whose router denies RFC1918.
This PR does not claim to fix egress. It replaces the code's false assurance ("refusing to start unfirewalled") with an honest, evidenced WARN + a
windowsEgressNotEnforcedpointer, so the daemon never implies a containment it does not provide, and so the next attempt does not repeat #1–#4.Phase 1 diagnosis — the ACLs are applied but NOT enforced
Caught a live job-container endpoint during a held containment run. The RFC1918 block ACLs
buildEgressBlockPoliciesproduces are present on the live endpoint (10.88.82.163):[{"Action":"Block","Direction":"Out","Priority":100,"Protocols":"6,17","RemoteAddresses":"10.0.0.0/8","RuleType":"Switch","Type":"ACL"}, {"...":"172.16.0.0/12"},{"...":"192.168.0.0/16"},{"...":"169.254.0.0/16"}]…yet the same run still reaches every plane (baseline, deployed v0.1.7):
So the endpoint
RuleType:"Switch"(VFP) ACLs are stored but inert.Root cause — VFP is not enforcing on the WinNAT switch
vfpctrl.exe /list-vmswitch-portenumerates the switch ports (host vNICAEAC667CPortId 1; container synthetic ports), but every port- or NAT-scoped VFP operation fails:Only passive enumeration works. On a WinNAT
natnetwork the VFP switch extension is not enforcing on the ports, soRuleType:"Switch"ACLs (and anyvfpctrl-added rule, and the nativevfpctrl"1:Block RFC1918" NAT flag) have no datapath to bite. Container→LAN egress is instead forwarded + SNATed by the host, a path the host Windows Firewall does not filter (it governs host-terminated traffic, not routing/forwarding).Why every mechanism fails here (the enforcement matrix)
vfpctrl)New-NetFirewallHyperVRule, #140)Get-NetFirewallHyperVVMCreatorandGet-NetFirewallHyperVPortare empty even with a live container → rules never attach.Add-VMNetworkAdapterExtendedAcl)Get-VMSwitch/Get-VMNetworkAdapteralso absent).route add … 127.0.0.1)The route addition failed: The parameter is incorrect.Get-NetFirewallProfile→ Windows System Error 1753 (BFE not running);Start-Service BFE/mpssvc→ "Cannot start service". Base Filtering Engine absent inside the container.Every one of these was run on the live node and observed via the containment suite; the four planes stayed reachable in each case.
The intended allow-list (mirrors
firewall_linux.go) was respected in every test: block only10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16minus the container's own10.88.0.0/16(so gateway 10.88.0.1 / DNS / default route / container-to-container survive), leaving the public internet open. The gap is enforcement, not scope.Recommendation
FWPM_LAYER_IPFORWARD_V4(the Windows analogue of the Linux iptables FORWARD chain), added via the WFP API. It is unverified (no CLI to test it; WinNAT's WFP-callout ordering is undocumented) and risky on the production node — a mis-scoped forward filter can sever the host's own management LAN, recoverable only through the fragile guest-agent. It should be prototyped in a lab, not shipped blind, rather than add a 4th untested attempt.What this PR changes
network_windows.go: keep the fail-closed ACL apply, drop the false "refusing to start unfirewalled" claim, emit a per-container WARN with the metal-verified analysis.firewall_windows.go: startup WARN that Windows egress filtering is best-effort and NOT enforced on this host class.windowsEgressNotEnforced: single-line log pointer to the analysis.test/containment-suite, separate branch) added a Windows "internet must still be reachable" probe so a future working fix is checked for over-blocking too.The ACLs are left in place — harmless, fail-closed, and correct on any future host where VFP or the Hyper-V firewall does enforce.