e2b-dev / e2b-dev/runtime

RFC: move non-80/443 TCP CIDR egress enforcement into the per-sandbox netns firewall (stop steering it)

Open
#3,088 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
1.6k
Forks
438
PR merge metrics
No merged PRs in 30d

Description

Problem

Egress CIDR policy is split by L4 protocol. Non-TCP CIDR is enforced in the netns nftables firewall; TCP CIDR is enforced in the userspace proxy (isEgressAllowed via cidrOnlyHandler). Same policy, two engines. For non-80/443 TCP the proxy adds nothing a kernel firewall can't do: there's no hostname to inspect, so only the dst IP matters.

Change

Enforce non-80/443 TCP CIDR in the netns firewall and stop steering it. Keep 80/443 steered (the proxy still does domain + CIDR; only it can read SNI/Host).

  • firewall.go: add tcp dport 80 accept / tcp dport 443 accept bypass rules, and promote the user allow/deny rules from non-TCP-only to all protocols.
  • proxy.go: drop the other-ports listener and its REDIRECT/steer rule. Only 80/443 steer. 80/443 proxy logic (domain + CIDR + no-SNI fallback) is unchanged.

The netns filter runs before the packet leaves the netns, so denied non-80/443 TCP is dropped before steering/MASQUERADE.

Why

  • Non-80/443 has no inspectable hostname, so CIDR is the only policy — it belongs in-kernel. Removes a proxy hop and the per-slot nat REDIRECT for that traffic.
  • Stateless per-packet match survives snapshot/resume. After resume the netns conntrack is empty; proxy-held TCP state is gone. Kernel CIDR re-applies cleanly; proxy-based TCP enforcement does not.

Status

Implemented and validated end-to-end (eBPF steering path): 80/443 reach the internet via the proxy; non-80/443 egresses directly; deny-all + allow-domain works on 443; an allowed non-80/443 CIDR connects while a denied one is dropped in the firewall. PR-ready.

Notes / questions

  1. Acceptable to move non-80/443 TCP CIDR into the firewall, or is the TCP-in-proxy split intentional?
  2. Non-80/443 TCP no longer hits the proxy's per-sandbox connection cap. Want an in-kernel equivalent (nftables ct count) in the same PR, or out of scope?

Related to #3085.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading firewall.go and proxy.go, then trace the existing netns nftables rules and proxy steering path. Confirm the requested split: only ports 80/443 are steered, while non-80/443 TCP CIDR enforcement occurs in the firewall. Re-run the end-to-end checks described in the issue, including deny-all, allowed-domain, and allowed-versus-denied CIDR cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
networking, security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.