feat(egress): use native nftables for DNS and transparent redirects (gVisor support) [DO NOT MERGE YET]#1374
Conversation
Replace the iptables/iptables-nft shell-outs for the DNS redirect and the transparent-HTTP (MITM) redirect with native nftables rulesets, matching the style of the existing filter-policy manager. The egress sidecar's dataplane is now 100% native nftables, with no dependency on iptables/xt-compat. - pkg/nftables/redirect.go: DNS redirect (nat/output, meta mark bypass, exempt-dst RETURN, redirect to :15353) in ip/ip6 tables. - pkg/nftables/transparent.go: MITM redirect (loopback RETURN, meta skuid != <mitm uid>, tcp dport 80/443, redirect to :port). - pkg/nftables/nat_common.go: idempotent table cleanup helper. - Remove pkg/iptables (redirect.go, transparent.go and tests). - Dockerfile: drop the iptables package (nftables only). - scripts/cleanup.sh: tear down the native-nft redirect tables on crash recovery instead of iptables rules; leave the inet filter table in place. - Update call sites, comments and docs. This makes the egress sidecar compatible with gVisor (runsc), whose netstack implements native nftables but not the iptables nat table. It depends on the upstream gVisor nftables PRs (see the PR description) being merged first.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d7bcf72f92
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The egress sidecar no longer uses the iptables nat table (it programs its dataplane with native nftables), so gVisor is no longer incompatible with networkPolicy. Remove the now-dead runtime gate and its startup warning instead of repurposing them: - validators.py: remove ensure_egress_runtime_compatible and the _GVISOR_NAT_INCOMPATIBLE_RUNTIMES set (and its now-unused import). - runtime_resolver.py: remove the gVisor egress-incompatibility warning. - docker/k8s providers: drop the call sites and imports. - tests: remove the runtime-compatibility test class. Docs: update the canonical egress / secure-container / network-isolation pages to describe the native-nftables dataplane and gVisor support on a runsc build that includes native nftables (google/gvisor#13796). Addresses the review on opensandbox-group#1374 (P1: server validator, P2: canonical docs).
|
Addressed the review: P1 (validator) — The gVisor–egress incompatibility no longer exists: the egress sidecar's dataplane is now native nftables (no iptables
P2 (docs) — Updated the canonical docs: Still draft / DO NOT MERGE until the gVisor PRs land and a runsc release ships them. |
|
@Pangjiping — would you mind sharing your opinion on this PR when you have a moment? Quick summary of what it does:
I'd especially value your view on two points:
Thanks! |
Thanks, great jobs |
Why
The egress sidecar programs its dataplane with nftables, but the two NAT redirects — the DNS redirect (→ local DNS proxy) and the transparent-HTTP MITM redirect — were still shelling out to
iptables/iptables-nft. Under gVisor (runsc) the iptablesnattable is unavailable (gvisor#170), so the egress sidecar could not run under GKE Sandbox at all. These two redirects were the last part of the egress that was not native nftables.What
Rewrite both redirects to emit native nftables (a
nat/outputchain withredirect to :port), consolidated intopkg/nftablesalongside the existing filter-policy manager. The egress dataplane is now 100% native nftables — noiptables/xt-compat dependency.pkg/nftables/redirect.go— DNS redirect:OUTPUT :53 (udp/tcp) → :15353, with ameta mark 0x1bypass for the proxy's own SO_MARK'd upstream queries and per-destinationRETURNfor the exempt nameserver list (ip+ip6).pkg/nftables/transparent.go— MITM transparent redirect: loopbackRETURN, thenmeta skuid != <mitm uid> tcp dport 80/443 redirect to :<port>(IPv4, mirroring the previous behavior).pkg/nftables/nat_common.go— idempotent per-table cleanup helper.pkg/iptables/(redirect + transparent + tests).Dockerfile— drop theiptablespackage (keepnftables).scripts/cleanup.sh— crash recovery now deletes the native-nft redirect tables (opensandbox_dns_redirect,opensandbox_transparent) instead of iptables rules; leaves theinet opensandboxfilter table in place so filtering stays fail-closed across restarts.main.go,shutdown.go,mitmproxy_transparent.go), comments and docs.No behavior change on
runc/Kata: the rendered rules are equivalent to the previous iptables REDIRECT rules.Dependency: gVisor nftables support
The native-nft rulesets use nftables features runsc did not implement. These upstream gVisor PRs add them (tracking issue google/gvisor#13796, which also documents this OpenSandbox use case):
meta markload (SO_MARK bypass)redir/ REDIRECT (this PR's DNS + MITM redirect)This PR must not be merged until those are merged and a runsc release includes them.
Testing
go build ./...,go vet,gofmt— clean.go test ./...) — pass. New unit tests inpkg/nftablescover both redirect script builders, the missing-table cleanup path, and the apply-error path.--TESTONLY-nftables): the exact rulesets this code emits install cleanly andnft list rulesetrenders them correctly —redirect to :port,meta mark,meta skuid !=, and exacttcp dportall evaluate under gVisor's netstack.rendered ruleset under runsc