[Bubblewrap/LXC] Address common network policy gaps - model 1#631
Open
dhoehna wants to merge 1 commit into
Open
[Bubblewrap/LXC] Address common network policy gaps - model 1#631dhoehna wants to merge 1 commit into
dhoehna wants to merge 1 commit into
Conversation
…(AB#62830559) - resolve_host returns dual-stack; add ip6tables v6 chain mirroring the v4 chain. - CIDR (v4/v6) passthrough; per-rule --dport and -p tcp/udp/icmp via new EgressRule model field. - Pure rule-builder helpers with unit tests; update legacy IPv6-drop tests to dual-stack. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3b78bec0-e139-4cfd-9c10-092ef986d4f4
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends the LXC firewall enforcement path to support a richer, dual-stack egress network policy model (IPv4 + IPv6), including CIDR destinations and per-rule protocol/port filtering, while preserving the legacy allowed/blocked host lists.
Changes:
- Added
ContainerPolicy.egress_ruleswith supportingEgressRule,Protocol, andRuleActiontypes inwxc_common. - Updated the LXC iptables enforcement implementation to build parallel
iptables+ip6tableschains and to preserve IPv6 literals/AAAA resolution results. - Refactored rule construction into helper functions returning argument vectors, with unit tests for the new rule-building behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/core/wxc_common/src/models.rs | Introduces the egress_rules policy model and supporting enums/structs on ContainerPolicy. |
| src/backends/lxc/common/src/network_iptables.rs | Implements dual-stack (iptables/ip6tables) rule application, CIDR/protocol/port handling, and adds unit tests for rule argument construction. |
Comment on lines
+120
to
+124
| /// Bare IPv4/IPv6 literals are retained in their matching family. CIDR | ||
| /// strings are accepted after validating the network address and prefix | ||
| /// length, then passed through unchanged. Hostnames are resolved to both A | ||
| /// and AAAA records so IPv4 destinations route to `iptables` and IPv6 | ||
| /// destinations route to `ip6tables`. |
Comment on lines
+188
to
+194
| fn protocol_arg(protocol: &Protocol) -> &'static str { | ||
| match protocol { | ||
| Protocol::Tcp => "tcp", | ||
| Protocol::Udp => "udp", | ||
| Protocol::Icmp => "icmp", | ||
| } | ||
| } |
Comment on lines
+291
to
+299
| for protocol in &protocol_options { | ||
| for port in &port_options { | ||
| let rule = Self::build_single_rule_args( | ||
| chain_name, | ||
| destination, | ||
| action, | ||
| protocol.as_ref(), | ||
| *port, | ||
| ); |
Comment on lines
482
to
+489
| Self::run_iptables( | ||
| &["-I", "FORWARD", "-o", iface, "-j", &self.chain_name], | ||
| logger, | ||
| )?; | ||
| Self::run_ip6tables( | ||
| &["-I", "FORWARD", "-o", iface, "-j", &self.chain_name], | ||
| logger, | ||
| )?; |
| // Remove from FORWARD (only if we had a veth interface and hooked it) | ||
| if let Some(ref iface) = self.veth_interface { | ||
| let _ = Self::run_iptables( | ||
| &["-D", "FORWARD", "-o", iface, "-j", &self.chain_name], |
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.
Linked work item: AB#62830559 — [Bubblewrap/LXC] Address common network policy gaps - model 1
Summary
Adds IPv6, CIDR, port, and protocol filtering to the LXC iptables enforcement path.
resolve_hostnow returns dual-stack (IPv4 + IPv6); IPv6 literals / AAAA results are retained instead of dropped.run_ip6tableshelper + a parallel v6 chain mirroring loopback / ESTABLISHED,RELATED / DNS / default-policy, with anip6tables -I FORWARDhook and matching cleanup.std::net), routed to the correct table by address family.--dport) and protocol (-p tcp/udp/icmp) enforcement via a new internalegress_rulesmodel field; the legacyallowed_hosts/blocked_hostspath is preserved.resolve_hostdoc comment were updated to the new dual-stack behavior.Model
ContainerPolicy.egress_rules: Vec<EgressRule>(+EgressRule,Protocol,RuleAction), default empty.Validation
cargo fmt --all -- --check;cargo clippy --target x86_64-unknown-linux-gnu -p lxc_common -D warnings— cleancargo test -p wxc_common— 395 passedcargo check --target x86_64-unknown-linux-gnu -p lxc_common --tests— passCoupling
EgressRule/Protocol/RuleActionare also introduced independently by the schema PR (AB#62830582) and net-model-2 (AB#62830341); merge-time reconciliation is expected. The JSON parser foregress_rulesis intentionally owned by the schema PR.Microsoft Reviewers: Open in CodeFlow