Skip to content

netfilter: add iptables MASQUERADE target with strict hook validation and tests - #14606

Open
hugelgupf wants to merge 1 commit into
google:masterfrom
hugelgupf:pr/iptables-masquerade
Open

netfilter: add iptables MASQUERADE target with strict hook validation and tests#14606
hugelgupf wants to merge 1 commit into
google:masterfrom
hugelgupf:pr/iptables-masquerade

Conversation

@hugelgupf

@hugelgupf hugelgupf commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Implements masqueradeTargetMaker in pkg/sentry/socket/netfilter/masquerade.go for IPv4 and IPv6, translating the iptables target to stack.MasqueradeTarget.
  • Validates network protocols and target buffer size during unmarshal.
  • Strictly validates tables and hooks: enforces that MASQUERADE is only installed in the nat table on the POSTROUTING hook. Any rule placing MASQUERADE in other tables (filter/mangle/raw) or other hooks (PREROUTING, INPUT, FORWARD, OUTPUT) is rejected with EINVAL.
  • Adds unit tests in pkg/sentry/socket/netfilter/netfilter_test.go and integration tests in test/iptables/nat.go (including NATMasqueradeInvalidHookReject).

Motivation & Context

Kubernetes kube-proxy configures MASQUERADE in KUBE-POSTROUTING for traffic leaving the node or traversing virtual bridge hairpin paths. Although netstack had stack.MasqueradeTarget, netfilter had no targetMaker for "MASQUERADE", causing iptables-restore to fail ("MASQUERADE revision 0 not supported") and aborting ruleset synchronization.

Test Plan

  • Unit tests: bazel test //pkg/sentry/socket/netfilter:netfilter_test //pkg/tcpip/stack:stack_test
  • Integration tests: test/iptables:iptables_test (NATPostMasquerade*, NATMasqueradeInvalidHookReject)

@google-cla

google-cla Bot commented Sep 3, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

… and tests

The `MASQUERADE` target (xt_nat) is a specialized Source NAT (SNAT)
target valid in the nat table's POSTROUTING chain. It dynamically
rewrites a packet's source IP address to the primary IP address of the
outgoing network interface and establishes a connection-tracking entry so
that return traffic is automatically de-masqueraded back to the original
client.

Kubernetes `kube-proxy` configures MASQUERADE in the KUBE-POSTROUTING
chain for traffic leaving the node or traversing virtual bridge hairpin
paths. Although gVisor's netstack already provided stack.MasqueradeTarget,
netfilter lacked a targetMaker for "MASQUERADE", causing `iptables-restore`
to fail ("MASQUERADE revision 0 not supported") and abort the entire
sync transaction.

### What is implemented:
- Protocol and layout validation: Translates iptables MASQUERADE target
  (revisions 0, 1, 2) to stack.MasqueradeTarget for IPv4 and IPv6.
- Strict table and hook validation: Enforces that the MASQUERADE target
  is only installed in the `nat` table on the `POSTROUTING` hook. Any
  attempt to install MASQUERADE in other tables (filter/mangle/raw) or
  other hooks (PREROUTING, INPUT, FORWARD, OUTPUT) is explicitly rejected
  during ruleset loading.
- Dynamic egress source translation: stack.MasqueradeTarget queries the
  outgoing AddressableEndpoint at action time and executes SNAT.
- Round-trip fidelity: Retains raw target bytes for faithful
  iptables-save round-tripping.
- Unit and integration tests:
  * Unit test in netfilter_test.go verifying checkLoopsAndChains rejects
    MASQUERADE in non-POSTROUTING hooks.
  * Integration tests in test/iptables/nat.go verifying UDP and TCP
    masquerade rewrites as well as rejection of MASQUERADE in PREROUTING/filter.

### What is still missing / diverges vs. Linux:
- Interface DOWN flushes: Linux instantly deletes all conntrack entries
  associated with an interface when the link drops its IP or goes DOWN;
  gVisor relies on standard conntrack timeout reaping.
- Port range constraints: Specific port ranges passed via `--to-ports`
  are preserved for iptables-save but port selection currently uses
  netstack's standard ephemeral port allocator.
@hugelgupf
hugelgupf force-pushed the pr/iptables-masquerade branch from 6c91c6f to c028adb Compare September 4, 2026 00:17
@hugelgupf hugelgupf changed the title netfilter: add iptables MASQUERADE target with validation and tests netfilter: add iptables MASQUERADE target with strict hook validation and tests Sep 4, 2026
@hugelgupf hugelgupf closed this Sep 4, 2026
@hugelgupf hugelgupf reopened this Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants