Skip to content

fix(network): normalize IPv4-mapped transparent TCP destinations - #5101

Merged
FrostGod merged 3 commits into
mainfrom
fix/5093-normalize-mapped-ipv4/FrostGod
Nov 5, 2026
Merged

FrostGod merged 3 commits into
mainfrom
fix/5093-normalize-mapped-ipv4/FrostGod

Conversation

@FrostGod

@FrostGod FrostGod commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

A transparent TCP connection allowed for an IPv4 destination was denied when a dual-stack client used its ::ffff: form. Canonicalize the destination before routing, policy DNS lookup, policy evaluation, and denial reporting, while preserving native IPv6 scope and flow information.

Related Issue

Closes #5093

Changes

  • Normalize the staged destination IP with to_canonical().
  • Add five regression tests covering allowed endpoints, DNS hostname recovery and pinned addresses, denial hosts, metadata blocking, and native IPv6 preservation.
  • Exercise the reserved relay with both IPv4 and IPv4-mapped IPv6 destinations.
  • Extend the existing Docker/Podman TCP E2E probe with an actual IPv4-mapped AF_INET6 connection, and document equivalent IPv4 policy matching.

Release Notes

Transparent TCP connections now evaluate IPv4-mapped IPv6 destinations as IPv4. If an endpoint rule uses host: "::ffff:203.0.113.7", change it to host: "203.0.113.7".

Testing

  • Scoped formatting, Clippy, and documentation navigation checks pass.
  • Unit tests added: 5 new regressions and 23 existing staged-open/reserved-routing checks pass, including both address forms for the reserved relay.
  • Existing E2E test extended; local execution did not reach the tests.

Commands passed:

  • cargo test --offline -p openshell-supervisor-network --lib proxy::tests::ipv4_mapped
  • cargo test --offline -p openshell-supervisor-network --lib -- proxy::tests::ipv4_mapped staged_ reserved_ metadata_staging --test-threads=1
  • cargo clippy --offline -p openshell-supervisor-network --lib --tests -- -D warnings
  • cargo fmt --check -p openshell-supervisor-network -p openshell-isolation-interface
  • rustfmt --check --edition 2024 e2e/rust/tests/transparent_tcp.rs
  • mise run --skip-tools docs:nav

The focused Docker E2E run was canceled after stalling on base-image metadata from ghcr.io/astral-sh/uv and nvcr.io/nvidia/base/ubuntu, before sandbox tests started. The repository-wide commit hook also failed in unrelated local Python tooling; the commit uses the completed scoped checks above.

Checklist

  • Follows Conventional Commits.
  • Commit signed off (DCO).
  • Relevant network-policy documentation updated.

@copy-pr-bot

copy-pr-bot Bot commented Nov 1, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown

@EmilienM EmilienM left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another iteration needed: 1 major, 3 minor (inline, 1 below)

The core fix is right and the new unit tests pass locally. The major is about verification, not the code: the new e2e probe has never executed, and the V6-family relay establishment it covers only runs on that path.

Outside the diff:

  • Minor: crates/openshell-isolation-interface/src/contract.rs:585, PendingTcpOpen.destination is documented as the original destination the backend captured, but preauthorize_transparent_open now rewrites it in place; a one-line doc note (or canonicalizing at capture) keeps the contract accurate.
How this was reviewed
  • Commit dedaee7a, round 1
  • Deep review, because the change routes supervisor network policy (crates/openshell-supervisor-network/src/proxy.rs), sandbox socket mediation (crates/openshell-sandbox/src/network_broker.rs), and the transparent TCP e2e (e2e/rust/tests/transparent_tcp.rs)
  • Passes: architecture, performance, security, scalability, rust, then correctness
  • Independent skeptics checked each candidate finding (1); 1 of 2 held up
  • Repo rules read from origin/main: AGENTS.md, CLAUDE.md, CONTRIBUTING.md
  • Not covered: the Docker/Podman E2E suite (CI shows test:e2e not applied; see the major finding)

Comment thread e2e/rust/tests/transparent_tcp.rs Resolved
@FrostGod

FrostGod commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator Author

/ok to test 48ac0ec

@FrostGod FrostGod added the test:e2e Requires end-to-end coverage label Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown

Label test:e2e applied for 48ac0ec. Open the existing run and click Re-run all jobs to execute with the label set. The run will execute the standard E2E suite after building the required gateway, sandbox, and supervisor images once. The matching required CI gate status on this PR will flip green automatically once the run finishes.

@pimlock

pimlock commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator

/ok to test d2a2283

@FrostGod
FrostGod enabled auto-merge November 5, 2026 02:19
Signed-off-by: divesh <dgude@nvidia.com>
Signed-off-by: divesh <dgude@nvidia.com>
@FrostGod
FrostGod force-pushed the fix/5093-normalize-mapped-ipv4/FrostGod branch from d2a2283 to bd0ec39 Compare November 5, 2026 06:38
@FrostGod

FrostGod commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator Author

/ok to test bd0ec39

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown

Compatibility review (advisory)

New or updated breaking changes; see the full report for all findings.

1. policy — No explicit risk acceptance found

Transparent TCP destinations previously retained their mapped IPv6 identity but now become IPv4, preventing mapped host and allowed_ips entries from matching.

  • Impact: Existing policies with protocol omitted and entries such as host: &quot;::ffff:203.0.113.7&quot; or hostless allowed_ips: [&quot;::ffff:203.0.113.7/128&quot;] now reject formerly permitted connections.
  • Action: Preserve mapped host and allowed_ips matching in v0.1.8; defer mandatory conversion to a minor release with migration guidance for both fields.
  • PR: fix(network): normalize IPv4-mapped transparent TCP destinations #5101
Review details
  • Execution: complete
  • Candidate: PR #5101 (884052bb8c9a8f2a132f7aae7e2fd42fc217debd)
  • Baseline: f56b12e0c08cc1fc213f1c9adab5b23e31796c6d (f56b12e0c08cc1fc213f1c9adab5b23e31796c6d)
  • Reviewed: rust-sdk, python-sdk, go-sdk, typescript-sdk, api-behavior, cli, configuration, policy, helm, state

Advisory review; publication gates are unchanged.

Branch check run

@FrostGod
FrostGod added this pull request to the merge queue Nov 5, 2026
Merged via the queue into main with commit 7954300 Nov 5, 2026
142 checks passed
@FrostGod
FrostGod deleted the fix/5093-normalize-mapped-ipv4/FrostGod branch November 5, 2026 07:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:e2e Requires end-to-end coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(network): transparent TCP opens to IPv4-mapped destinations are denied even when policy allows the IPv4 endpoint

3 participants