egressproxy

package
v0.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 15, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package egressproxy implements the transparent sandbox egress filter: a userspace proxy that all sandbox TCP is iptables-REDIRECT'd through, plus the redirect installer and the on-disk policy contract the control plane writes.

The enforcement model mirrors e2b-dev/infra's tcpfirewall, adapted for a Kubernetes Pod (init container installs the redirect, a sidecar runs the proxy) and hardened for the eval anti-cheat use case: the default action is deny (allowlist), not allow.

Index

Constants

View Source
const (
	// DefaultProxyUID is the uid the sidecar runs as; the redirect exempts it so
	// the proxy's own upstream connections are not looped back.
	DefaultProxyUID = 1337

	DefaultHTTPPort  = 15001
	DefaultTLSPort   = 15002
	DefaultOtherPort = 15003

	// DefaultPolicyPath is the emptyDir file the control plane writes (exec) and
	// the proxy reads (fsnotify). Mounted only in the sidecar.
	DefaultPolicyPath = "/var/run/egress/policy.json"
)

Fixed wiring shared by the redirect installer, the proxy, and the control plane. These are container-internal (the sidecar owns the whole netns view), so constants rather than config keep init and sidecar in lockstep.

Variables

This section is empty.

Functions

func InstallRedirect

func InstallRedirect(cfg RedirectConfig) error

InstallRedirect programs nat OUTPUT so all sandbox TCP is transparently redirected to the local proxy, while the proxy's own traffic, DNS, and loopback are exempted. Idempotent: the chain is flushed and rebuilt, and the OUTPUT jump is added only if absent.

Runs in the Pod netns (shared by all containers); requires CAP_NET_ADMIN.

func WritePolicy

func WritePolicy(path string, p Policy) error

WritePolicy atomically writes the policy to path (write temp + rename) so a reader (fsnotify reload) never observes a half-written file.

Types

type Decision

type Decision struct {
	Allow bool
	Match MatchType
}

Decision is the outcome of an egress check.

type MatchType

type MatchType string

MatchType records why a connection was allowed/denied, for metrics and logs.

const (
	MatchNone   MatchType = "none"
	MatchDomain MatchType = "domain"
	MatchCIDR   MatchType = "cidr"
	MatchSSRF   MatchType = "ssrf"
)

type Policy

type Policy struct {
	// SandboxID records which sandbox this policy was pushed for. Informational
	// (surfaced in logs/metrics); the proxy enforces whatever is present.
	SandboxID string `json:"sandboxId,omitempty"`

	// Enforce gates the whole filter. When false the policy is treated as
	// fail-closed (deny all). The control plane sets it true only after a
	// concrete ruleset has been resolved for a claimed sandbox.
	Enforce bool `json:"enforce"`

	// DisableEgress blocks all outbound traffic regardless of the allow lists
	// (DNS is still permitted so name resolution does not hang). Equivalent to
	// an empty allowlist.
	DisableEgress bool `json:"disableEgress,omitempty"`

	// AllowedDomains permits egress to matching hostnames (exact, "*", or
	// "*.example.com"). Domains only ever allow; there is no domain deny.
	AllowedDomains []string `json:"allowedDomains,omitempty"`

	// AllowedCIDRs / DeniedCIDRs are IP/CIDR allow/deny for traffic without a
	// usable hostname (non-80/443 TCP, or bare-IP connections).
	AllowedCIDRs []string `json:"allowedCIDRs,omitempty"`
	DeniedCIDRs  []string `json:"deniedCIDRs,omitempty"`

	// AllowPrivateNetworks disables the built-in anti-SSRF deny of private /
	// link-local / cloud-metadata ranges. Default false (baseline stays on).
	AllowPrivateNetworks bool `json:"allowPrivateNetworks,omitempty"`
}

Policy is the on-disk egress ruleset the control plane pushes to the proxy. It is the single source of truth read by the sidecar; an absent, empty, or unparseable file means fail-closed (deny all egress except DNS).

func FailClosed

func FailClosed() Policy

FailClosed is the policy applied when no valid policy file is present: deny everything. DNS egress is permitted separately by the iptables rules, not by this policy, so resolution keeps working even while fail-closed.

func LoadPolicy

func LoadPolicy(path string) (Policy, error)

LoadPolicy reads and parses the policy file. A missing file yields FailClosed with no error (that is the expected steady state before the first push). A present-but-corrupt file yields FailClosed WITH an error so the caller can log it — but enforcement still fails closed.

func (Policy) Evaluate

func (p Policy) Evaluate(hostname string, ip net.IP) Decision

Evaluate applies the policy to a connection. hostname is the peeked HTTP Host or TLS SNI ("" when unavailable); ip is the original destination IP.

Semantics (allowlist / default-deny, hardened vs e2b's default-allow):

  1. Not enforcing -> allow (feature effectively off).
  2. Anti-SSRF baseline -> deny private ranges unless AllowPrivateNetworks.
  3. DisableEgress -> deny (allowlist empty by construction).
  4. Allowed domain match -> allow.
  5. Allowed CIDR match -> allow.
  6. Denied CIDR match -> deny.
  7. Default -> DENY (this is the key hardening).

type Proxy

type Proxy struct {
	// contains filtered or unexported fields
}

Proxy is the running egress filter.

func NewProxy

func NewProxy(cfg ServeConfig) *Proxy

NewProxy builds a Proxy, loading the initial policy (fail-closed if absent).

func (*Proxy) Serve

func (p *Proxy) Serve(ctx context.Context) error

Serve starts the three listeners and the policy hot-reload watcher, blocking until ctx is cancelled.

type RedirectConfig

type RedirectConfig struct {
	ProxyUID  int // sidecar runs as this uid; its own egress is exempted (no loop)
	HTTPPort  int
	TLSPort   int
	OtherPort int
}

RedirectConfig parameterizes the iptables nat rules the init container installs in the Pod network namespace.

type ServeConfig

type ServeConfig struct {
	PolicyPath string
	HTTPPort   int
	TLSPort    int
	OtherPort  int
	Logger     *slog.Logger
}

ServeConfig configures the proxy listeners and policy source.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL