egress

package
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package egress is the transparent egress PEP (ADR-0117, FEAT-0007/F81): the enforcement point F80's nftables substrate REDIRECTs remaining external worker TCP into. Per redirected connection the Linux driver recovers the pre-DNAT destination (SO_ORIGINAL_DST), authenticates the caller by source IP via the WorkerIndex, builds the FORWARDER-ATTESTED destination (the B1 invariant — client SNI/Host is never the authorization basis), asks the auth.Authorizer PDP whether that worker's principal (its Function or CatalogService) may egress::connect to that NetDestination, and splices on ALLOW / refuses on DENY — auditing every connection. It is default-deny, fail-closed, opt-in (server.network.egress), and Linux/containerd only. Disabled or on a non-Linux host New returns a no-op Gateway and worker egress stays open exactly as before. The SNI/Host parsers, the forwarder-attested destination build, and the decision flow are pure + unit-tested cross-platform; the SO_ORIGINAL_DST recovery, conn peek/replay, and splice are the Linux driver (Lima e2e verifies behavior).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AuditRecord

type AuditRecord struct {
	Namespace, Function, Domain string
	IP                          netip.Addr
	Port                        uint16
	Allowed                     bool
	Reason                      string
}

AuditRecord is one egress decision (allowed or blocked).

type AuditSink

type AuditSink interface {
	Egress(ctx context.Context, rec AuditRecord)
}

AuditSink records one egress decision to the funclog audit channel.

type Deps

type Deps struct {
	GatewayPort uint16          // F80's REDIRECT target (server.network.egressGatewayPort)
	Workers     WorkerIndex     // src-IP → caller Ref (containerd runtime populates it, §5)
	DNS         DomainResolver  // forwarder-attested (worker, dst-IP) → domains (the trust anchor)
	Authz       auth.Authorizer // the PDP (egress::connect over a NetDestination)
	Audit       AuditSink       // every connection (allowed + blocked) → the funclog channel
	Logger      *slog.Logger    // nil ⇒ slog.Default()
}

Deps wires the gateway. On a non-Linux host or when disabled, New returns a no-op Gateway.

type DomainResolver

type DomainResolver interface {
	DomainsFor(src netip.Addr, dst netip.Addr) []string
}

DomainResolver returns the domains THIS worker resolved to dst via the funcd forwarder — the authoritative domain→IP binding (never client SNI/Host). It includes any namespace wildcard pattern token an attested FQDN matched (so wildcard rules stay exact set-membership). Empty ⇒ only a CIDR rule can permit dst.

type Forwarder

type Forwarder interface {
	Serve(ctx context.Context) error
	DomainResolver
}

Forwarder is the ONLY resolver a worker can reach (F80 redirects worker :53 into it). It forwards to the node resolver and records (src, domain)→resolved-IP set, exposing the reverse DomainsFor the gateway uses to authorize domain rules. It also loads the namespace EgressPolicy domain patterns to inject a matched wildcard token. It satisfies DomainResolver. Serve blocks until ctx is cancelled.

func NewForwarder

func NewForwarder(listen, upstream netip.AddrPort, workers WorkerIndex, patterns WildcardPatterns) Forwarder

NewForwarder builds the forwarder over the node resolver (github.com/miekg/dns; BSD-3-Clause). The correlation map keys on the DNS client's source IP so a worker only inherits the domains IT resolved. workers maps that source IP → its namespace and patterns supplies that namespace's wildcards, so a resolved FQDN also records any "*.x.com" it matched (keeping wildcard authorization an exact set-membership check over a forwarder-derived token). Both may be nil on a deployment with no wildcard rules — then only exact attested FQDNs are recorded.

type Gateway

type Gateway interface {
	Serve(ctx context.Context) error
	Close() error
}

Gateway is the transparent egress PEP: it accepts F80-redirected worker connections on GatewayPort, recovers the original destination, identifies the caller, asks the PDP, and splices or refuses — auditing every connection. Serve blocks until ctx is cancelled or Close is called.

func New

func New(enabled bool, d Deps) Gateway

New returns the Linux driver when enabled on Linux, else a no-op (build-tagged newGateway() dispatch, mirroring internal/network's nftables_linux.go / _other.go split).

type MemoryWorkerIndex

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

MemoryWorkerIndex is the in-memory WorkerIndex (ADR-0117, §5) the containerd runtime populates at worker provisioning: on worker-up it records the assigned funcd0 IP → the worker's principal Ref (its owner kind); on worker-down it removes it. The gateway reads it to authenticate the caller by source IP (never client-asserted). Concurrency-safe.

func NewMemoryWorkerIndex

func NewMemoryWorkerIndex() *MemoryWorkerIndex

NewMemoryWorkerIndex returns an empty index.

func (*MemoryWorkerIndex) Add

func (w *MemoryWorkerIndex) Add(ip netip.Addr, ref auth.EntityRef)

Add records a worker's funcd0 source IP → its principal Ref (worker-up).

func (*MemoryWorkerIndex) Lookup

func (w *MemoryWorkerIndex) Lookup(ip netip.Addr) (auth.EntityRef, bool)

Lookup resolves a source IP to its principal Ref; ok==false ⇒ unknown worker (the gateway denies+audits).

func (*MemoryWorkerIndex) Remove

func (w *MemoryWorkerIndex) Remove(ip netip.Addr)

Remove drops a worker's IP mapping (worker-down); safe if absent.

type WildcardPatterns

type WildcardPatterns interface {
	Wildcards(ns v1.NamespaceName) []string
}

WildcardPatterns supplies a namespace's EgressPolicy wildcard domain patterns (e.g. "*.x.com") so the forwarder can record which pattern an attested FQDN matched — the dependency the wildcard-token injection needs (ADR-0117, judge Major 2). It is derived from the same EgressPolicy set the PDP cache compiles; nil ⇒ no wildcard tokens (exact attested FQDNs only).

type WorkerIndex

type WorkerIndex interface {
	Lookup(ip netip.Addr) (ref auth.EntityRef, ok bool)
}

WorkerIndex resolves a worker's funcd0 source IP to the principal Ref of its owner kind (a Function or a CatalogService).

Jump to

Keyboard shortcuts

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