You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[WSLC] Proposal: Built-in proxy for networking - #1625
WSLC networking today supports only all-allow (BRIDGED) or all-deny (NONE). This design adds a per-container controller container that enforces TCP CIDR and port rules, and lets egress, ingress and hostLoopback defaults be set independently. It uses the existing network fields.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
The design leaves unresolved DNS policy enforcement gaps, Windows loopback port collisions, and crash recovery that cannot reclaim networks while orphan workloads remain attached.
This documentation-only PR proposes a per-container WSLC networking controller for #1462, extending today’s all-or-nothing networking with TCP CIDR and port filtering through existing network fields.
Changes:
Defines proxy selection, host-loopback access, port relaying, and custom-proxy behavior.
Describes controller lifecycle, cleanup, prerequisites, staged delivery, and planned validation.
Provides Rust, .NET, and Node usage examples, compatibility notes, and open API questions.
Lifecycle exec cannot remain unchanged: state_aware.rs::exec_config injects proxy variables only from the current exec request, and the daemon passes that environment to the new process. After provisioning a CIDR-filtered container, an exec without networkProxy therefore lacks the controller proxy variables, so even permitted HTTP(S) connections fail on the internal-only network. Specify controller endpoint retention and proxy-variable injection for every proxied exec, including replacement environments, and validate an exec without an explicit proxy setting.
The reason will be displayed to describe this comment to others. Learn more.
to confirm, is the controller container a seperate wsl container we spin up? or is it another executable the we'll add to mxc? just want to make sure I understand what controller means here is all.
The reason will be displayed to describe this comment to others. Learn more.
UDP/ICMP behavior will only change for configs that modify themselves in such a way that traffic gets proxied. allow-all or deny-all configs remain unaffected.
[P2] With egress.default: allow, denied ingress/host loopback, and networkProxy, the mode table selects Proxied, but the custom-proxy path permits only the proxy endpoint rather than all TCP. Reject this combination in proxied mode, as the linked Bubblewrap guide does, or define how all-TCP access is preserved. Keep the existing all-allow BRIDGED cooperative-proxy case unchanged and add the mixed-default combination to the validation plan.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed to evaluate the design’s attribution of host-loopback access to the SDK upgrade rather than MXC’s deliberate per-session enablement.
Tracking microsoft/WSL#42161, which adds the ability to connect/disconnect networks to running containers. Would allow one container to manage the proxy for everything.
The reason will be displayed to describe this comment to others. Learn more.
note: Not sure if you can get around this but when you start accepting host names you have to start thinking about DNS changes. e.g When we resolve the name on windows, the address can change right after. I assume we don't do any refreshing or anything like that right? Just a one time thing?
The reason will be displayed to describe this comment to others. Learn more.
thought: we should ask them for a listing API for sure. But in the meantime, we probably can't do the owership thing since multiple apps could be using mxc at the same time. For the exact name, I suppose we could do that and add our own guid at the end? Assuming WslcSetContainerSettingsName can allow duplicates.
If the app crashes though, then I don't think we can do anything since all our internal state will be lost. Probably will need to document.
The reason will be displayed to describe this comment to others. Learn more.
thought: I don't think we can do anything about this until we get a general solution from the Networking team tbh. Process container has the same issue with dns bypass.
The reason will be displayed to describe this comment to others. Learn more.
The main question isn't if someone should bring their own, the main question is, do we load the filtering script onto the container at runtime (e.g. using stock alpine), or do we bake it in on top of the base image and sign it?
The reason will be displayed to describe this comment to others. Learn more.
The controller container will have the filtering script inside of it. The networking policy is converted into environment variables that are set on the controller container. The filtering script reads those env vars and creates network rules to follow the policy.
The reason will be displayed to describe this comment to others. Learn more.
to confirm, is the controller container a seperate wsl container we spin up? or is it another executable the we'll add to mxc? just want to make sure I understand what controller means here is all.
The reason will be displayed to describe this comment to others. Learn more.
note: lets see if we can update the doc to remove any answered questions before check in. I still had a question about what the controller is and whether it's a wslc concept or we're creating it ourselves.
The reason will be displayed to describe this comment to others. Learn more.
The controller is an image we build from a Dockerfile during CI and ship with the binaries. The image will include the filtering script and the packages it needs. At build time, the hash of the image will be embedded into wxc-exec and the daemon. At runtime, MXC will only use the controller image with that hash.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Adding a member to Node V1’s closed BackendCapability union breaks source compatibility for existing callers using exhaustive switches or complete capability-keyed records.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed because crash recovery could mistake a pending reservation for confirmed ownership and force-delete another tool’s resource in shared storage.
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
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
WSLC networking today supports only all-allow (
BRIDGED) or all-deny (NONE). This design adds a per-container controller container that enforces TCP CIDR and port rules, and letsegress,ingressandhostLoopbackdefaults be set independently. It uses the existing network fields.Microsoft Reviewers: Open in CodeFlow