Skip to content

feat(linux-sandbox): route DNS through managed proxy#31644

Open
viyatb-oai wants to merge 8 commits into
codex/viyatb/linux-managed-dns-policyfrom
codex/viyatb/linux-managed-dns-routing
Open

feat(linux-sandbox): route DNS through managed proxy#31644
viyatb-oai wants to merge 8 commits into
codex/viyatb/linux-managed-dns-policyfrom
codex/viyatb/linux-managed-dns-routing

Conversation

@viyatb-oai

@viyatb-oai viyatb-oai commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Native DNS clients do not honor HTTP or SOCKS proxy variables, so Linux needs a DNS-speaking adapter inside the bubblewrap network namespace when managed DNS is enabled.

  • add an opt-in enable_dns managed proxy setting; DNS listeners and private DNS endpoint env are not created by default
  • add a Linux-only DNS adapter that binds 127.0.0.1:53 for UDP and TCP when the managed proxy provides a DNS endpoint
  • forward DNS wire messages through the existing managed proxy route bridge so policy and auditing stay in the proxy layer
  • mount a sandbox-local resolver configuration pointing at 127.0.0.1 and remove the private DNS endpoint variable before the user command runs
  • use temporary bind capabilities only for setup, drop and verify all capabilities before applying seccomp and execing the user command
  • avoid --cap-add with setuid system bubblewrap by selecting a capable bundled launcher when available; otherwise DNS routing is disabled while HTTP/SOCKS routing remains unchanged

Testing

  • just test -p codex-network-proxy (passed outside the filesystem sandbox; the sandboxed run could not write test CA files under the local proxy state directory)
  • just test -p codex-linux-sandbox (builds on macOS, then exits with no tests to run because the crate tests are Linux-gated)
  • cargo check -q -p codex-network-proxy -p codex-core -p codex-linux-sandbox
  • cargo check -q --target x86_64-unknown-linux-gnu -p codex-linux-sandbox (blocked locally: missing x86_64-linux-gnu-gcc and Linux OpenSSL sysroot)
  • just write-config-schema
  • just fix -p codex-network-proxy
  • just fix -p codex-linux-sandbox
  • just fix -p codex-config
  • just fix -p codex-features
  • just fix -p codex-core

Stack: 2 of 2. Previous: #31642.

@viyatb-oai viyatb-oai force-pushed the codex/viyatb/linux-managed-dns-routing branch from a44b6fe to d7aae07 Compare July 8, 2026 21:59
@viyatb-oai viyatb-oai changed the title feat(linux-sandbox): plumb managed DNS routes feat(linux-sandbox): add policy-checked DNS resolution Jul 8, 2026
@viyatb-oai viyatb-oai changed the base branch from codex/viyatb/linux-managed-dns-relay to codex/viyatb/linux-managed-dns-policy July 8, 2026 22:03
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/linux-managed-dns-routing branch from d7aae07 to 3a15264 Compare July 8, 2026 22:06
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/linux-managed-dns-policy branch from 9f584f0 to a5ea367 Compare July 8, 2026 23:06
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/linux-managed-dns-routing branch from d7aae07 to f3c3920 Compare July 9, 2026 01:42
@viyatb-oai viyatb-oai changed the title feat(linux-sandbox): add policy-checked DNS resolution feat(linux-sandbox): route DNS through managed proxy Jul 9, 2026
@viyatb-oai viyatb-oai marked this pull request as ready for review July 9, 2026 19:12
@viyatb-oai viyatb-oai requested a review from a team as a code owner July 9, 2026 19:12
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/linux-managed-dns-policy branch from e0b5dc2 to 83d864e Compare July 9, 2026 19:18

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 816e07cbd9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +63 to +65
if [logical_path, target_path].into_iter().any(|path| {
!policy.can_read_path_with_cwd(path, cwd)
|| deny_matcher

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.

P2 Badge Honor minimal read defaults when mounting DNS config

When managed DNS is enabled with a :minimal/split filesystem profile, this check rejects /etc/resolv.conf before bwrap starts because can_read_path_with_cwd() does not include the Linux platform-default read roots that bwrap later adds for :minimal (including /etc). Those launches will panic in DNS setup with PermissionDenied even though the sandbox would otherwise mount the resolver path; account for the same platform defaults here while still honoring explicit deny rules.

Useful? React with 👍 / 👎.

Comment on lines +207 to +210
if bound_dns.is_some() {
drop_and_verify_capabilities().unwrap_or_else(|err| {
panic!("error dropping Linux DNS setup capabilities: {err}")
});

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.

P1 Badge Keep route setup capabilities until bridges are active

When network.enable_dns is enabled, this drops every capability before activate_proxy_routes_in_netns() runs. That routing path may need to initialize the fresh bwrap network namespace’s loopback device before binding the local proxy bridge (bind_local_loopback_listener() retries via ensure_loopback_interface_up() on EADDRNOTAVAIL/ENETUNREACH), which requires the namespace’s network-admin capability. On those Linux environments the DNS-enabled managed proxy path will fail during bridge activation, or leave loopback unusable, before the user command starts; bind/start the proxy routes while the setup capabilities are still available and only then drop them before exec.

Useful? React with 👍 / 👎.

Comment on lines +85 to +88
BubblewrapLauncher::System(_) | BubblewrapLauncher::Unavailable => {
match bundled_bwrap::launcher() {
Some(launcher) => BubblewrapLauncher::Bundled(launcher),
None => BubblewrapLauncher::Unavailable,

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.

P2 Badge Don’t force bundled bwrap on setuid-only hosts

On hosts where the system bwrap is setuid because unprivileged user namespaces are disabled, this branch treats DNS support as available by falling back to the bundled bwrap whenever the system launcher cannot use --cap-add. The vendored bwrap itself rejects --cap-add in setuid mode for non-root (vendor/bubblewrap/bubblewrap.c lines 2958-2959), but the bundled binary also cannot create the user namespace on those hosts, so enabling DNS turns an otherwise working system-bwrap sandbox into a startup failure. In that environment this should disable the DNS bridge and keep using the working system launcher rather than selecting bundled bwrap solely for --cap-add.

Useful? React with 👍 / 👎.

Comment on lines +197 to +200
let bound_dns = if std::env::var_os(DNS_PROXY_ENV_KEY).is_some() {
Some(
bind_netns_dns_stub()
.unwrap_or_else(|err| panic!("error binding Linux DNS bridge: {err}")),

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.

P1 Badge Bring loopback up before binding the DNS stub

When network.enable_dns is enabled in a fresh --unshare-net namespace, this binds 127.0.0.1:53 before any code has initialized the namespace loopback device. The existing proxy bridge path only brings lo up later when its own bind sees EADDRNOTAVAIL/ENETUNREACH, so on those Linux hosts the DNS-enabled sandbox aborts here with error binding Linux DNS bridge before route setup can recover. Initialize loopback before this bind, or defer the DNS bind until after the proxy route setup has done so.

Useful? React with 👍 / 👎.

@viyatb-oai viyatb-oai force-pushed the codex/viyatb/linux-managed-dns-routing branch from 816e07c to 9ad7318 Compare July 9, 2026 19:31
Co-authored-by: Codex noreply@openai.com
Add enable_dns to the managed network proxy config so DNS listener reservation and endpoint export are opt-in. Keep the Linux DNS bridge driven solely by the endpoint env, and simplify the Linux integration test by using the DNS wire-format parser instead of hand-rolled packet bytes.\n\nCo-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/linux-managed-dns-routing branch from 9ad7318 to 3a5d83f Compare July 9, 2026 19:38
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant