elide fwd

Forward HTTP/HTTPS proxy with optional TLS interception (MITM), hostname blocking, client and port-based access control, SNI-routed L4 TCP relay, and traffic recording. Built on the same high-performance event loop as elide serve.

Requires an Elide Pro license. See elide.pro for details.

When to use it

  • Corporate proxy — route all outbound HTTP/HTTPS through a controlled gateway with hostname blocking and client CIDR restrictions
  • Traffic inspection — enable --mitm to decrypt and inspect HTTPS traffic for debugging, security auditing, or compliance
  • Access control — enforce allowlists and denylists on hostnames, ports, and client networks
  • L4 relay — route TLS traffic by SNI hostname without terminating encryption, for backend multiplexing or port consolidation

---

Quick start

Start a forward proxy on the default address (127.0.0.1:8080):

bash
 elide fwd

Configure your browser or system to use http://127.0.0.1:8080 as its HTTP proxy. All traffic flows through Elide.

MITM interception

Decrypt and inspect HTTPS traffic:

bash
 elide fwd --mitm
MITM requires a trusted proxy CA. See MITM setup for the one-time CA generation and trust store installation.

Hostname blocking

Block specific hostnames with glob patterns:

bash
 elide fwd --block '*.ads.example.com,tracker.io'

Allowlist mode

Allow only specific destinations (deny everything else by default):

bash
 elide fwd --allow-hosts '*.example.com,*.internal'

Client restrictions

Restrict which networks can connect:

bash
 elide fwd --allow-clients '10.0.0.0/8,192.168.1.0/24'

Port filtering

Block SMTP, allow only web ports:

bash
 elide fwd --deny-ports 25,587 --allow-ports 80,443,8443

L4 TCP relay

Run an SNI-routed TCP relay alongside the HTTP proxy:

bash
 elide fwd --l4 --l4-listen 0.0.0.0:443

PKL configuration

For complex setups, use a configuration file:

bash
 elide fwd --config proxy.pkl

---

How it works

When a client connects, the flow depends on the request type.

Plain HTTP — The request is parsed, matched against access control rules, forwarded to the origin, and the response is relayed back. HTTPS via CONNECT — The client sends CONNECT host:443 HTTP/1.1. The proxy validates the target against the ACL (deny rules first, then allow rules, then port restrictions). If permitted, it opens a TCP connection to the target, replies 200 Connection Established, and enters bidirectional byte relay. HTTPS via CONNECT with MITM — Instead of a blind relay, the proxy terminates TLS on both sides. It generates a per-host leaf certificate signed by the proxy CA, completes the TLS handshake with the client, opens its own TLS connection to the real server, and relays decrypted traffic. Full HTTP-level inspection of HTTPS traffic becomes possible.

Protocol support

CONNECT tunneling works across all HTTP versions:
ProtocolMechanismStatus
HTTP/1.1CONNECT host:port HTTP/1.1Supported
HTTP/2Extended CONNECT (RFC 9113 section 8.5)Supported
HTTP/3Extended CONNECT (RFC 9220)Supported
---

Access control

Access control evaluates in two stages.

Client ACL (--allow-clients) is checked first. If the client's IP does not fall within any allowed CIDR, the connection is rejected immediately. Destination ACL evaluates the target hostname and port in order:

1. Deny hosts (--block) — if any deny pattern matches the target hostname, the request is rejected with 403 Forbidden. 2. Deny ports (--deny-ports) — if the destination port is in the deny list, the request is rejected. 3. Default deny — if --allow-hosts is set, the target must match at least one allow pattern, and (if --allow-ports is set) the port must be in the allowed list. 4. Default allow — if no rules match and default deny is not active, the request is allowed.

Hostname glob patterns

PatternMatches
tracker.ioExact match only
*.ads.example.comSingle-level wildcard: video.ads.example.com but not a.b.ads.example.com
*.analytics.Multi-level wildcard: foo.bar.analytics.io, deep.nested.analytics.com
Blocked requests receive 403 Forbidden. Blocklist evaluation happens before upstream connection.

PKL proxy rules

When using a configuration file (--config), more granular rules are available. Rules support structured matching on host, path, port, protocol, and HTTP method. Each rule can specify an action (allow, block, record, or modify) and can override the global MITM setting for specific targets. Rules also support request and response header mutations.

Rules are evaluated in order; the first match wins.

---

L4 TCP relay

When --l4 is enabled, the proxy listens on a separate address (default 0.0.0.0:443) and performs SNI-based TCP routing. It reads the TLS ClientHello to extract the Server Name Indication, opens a TCP connection to the target, and relays bytes bidirectionally without terminating TLS.

bash
 elide fwd --l4 --l4-listen 0.0.0.0:443

This routes TLS traffic to different backends by hostname without MITM interception or any access to plaintext.

How SNI routing works

1. Client opens a TCP connection to the relay. 2. The relay reads just enough of the TLS ClientHello to extract the SNI hostname (typically the first 200-300 bytes). 3. The relay resolves the hostname and opens a TCP connection to the real server. 4. Buffered ClientHello bytes are forwarded, and the relay enters bidirectional byte relay.

SNI routes can be configured via PKL with per-route upstream targets and load balancing (round-robin or random).

L4 modes

ModeDescriptionStatus
TlsPassthroughSNI peek + blind relayImplemented
TcpPlain TCP relay (no TLS awareness)Implemented
TlsTerminateTerminate TLS at proxyPlanned
UdpUDP datagram forwardingPlanned
L4 relay does not decrypt traffic. When recording is configured via PKL, only metadata (timestamps, hostnames, byte counts) is captured for L4 connections — not request/response bodies.

---

CONNECT tunnel lifecycle

Each CONNECT tunnel tracks:

  • Target host and port
  • Client and upstream file descriptors
  • Bytes relayed in each direction
  • Last activity timestamp (for idle timeout enforcement)
  • Whether MITM is active for this tunnel

Default timeouts: 10 seconds for the outbound TCP connection, 5 minutes for idle tunnels (configurable via PKL). A max_tunnels limit in PKL config caps concurrent CONNECT tunnels — when reached, new connections receive 503 Service Unavailable.

---

Interactive TUI

By default, elide fwd launches an interactive terminal UI showing:

  • Status bar — listen address, MITM/passthrough mode, proxy state, uptime, L4 indicator
  • Requests table — scrollable list of proxied requests with method, URL/host, status code, and latency
  • Metrics panel — live RPS, active connections, tunnel count, blocked count, bytes relayed, p50/p99 latency
  • RPS sparkline — 60-second rolling throughput graph
  • Logs panel — structured log output with severity filtering
KeyAction
qQuit
TabToggle focus between Requests and Logs panels
j/k or arrow keysScroll requests
PgUp/PgDnPage through requests
EscReset focus to Requests
Use --no-tui for plain log output, or --json for structured JSON lines (one object per proxy event), suitable for jq or log aggregators.

---

Traffic recording and HAR export

Traffic recording is available through PKL configuration. The recording subsystem captures request/response metadata, with optional body capture filtered by content type.

Configure in the recording PKL section:

  • Max entries (ring buffer size)
  • Header and body capture toggles
  • Max body capture size
  • Content type filters
  • Host exclusion patterns
  • HAR export path and periodic flush interval

Recorded traffic can be exported via the admin API (GET /proxy/recording) or written to disk as a HAR 1.2 JSON file.

Recording is not yet exposed as CLI flags (—record, —har). Use a PKL configuration file or the admin API for live inspection.

---

Upstream proxy chaining

When configured via PKL, the proxy forwards all outbound connections through a specified upstream proxy instead of connecting directly.

The upstream proxy configuration supports:

  • Upstream URL (e.g. http://gateway:3128)
  • Bypass patterns (hostnames that skip the upstream)
  • Optional username/password authentication
Upstream proxy chaining is not yet exposed as a CLI flag (—upstream). Use PKL configuration.

---

CLI reference

elide fwd [OPTIONS]
FlagDefaultDescription
-l, —listen127.0.0.1:8080Proxy listen address. Accepts host:port or just port (binds 127.0.0.1).
-c, —confignonePKL configuration file. CLI flags override individual config settings.
—mitmfalseEnable MITM TLS interception for HTTPS traffic.
—ca-certauto-generatedCA certificate PEM for MITM. Requires —mitm.
—ca-keyauto-generatedCA private key PEM for MITM. Requires —mitm.
—blocknoneComma-separated hostname globs to deny.
—allow-hostsnone (all)Comma-separated hostname globs to allow. Enables default-deny.
—allow-clientsnone (all)Comma-separated CIDRs of allowed client networks. IPv4 and IPv6.
—allow-portsnone (all)Comma-separated destination ports to allow.
—deny-portsnoneComma-separated destination ports to deny.
—l4falseEnable L4 TCP relay alongside the HTTP proxy.
—l4-listen0.0.0.0:443L4 relay listen address.
—reactors1Number of reactor (event loop) threads.
—workers0 (auto)Total worker threads. 0 selects based on available parallelism.
—admin-portnoneAdmin API port (tunnel stats, active connections, recording).
—no-tuifalseDisable interactive TUI; use plain log output.
—jsonfalseStructured JSON lines to stdout. Disables the TUI.
---

See also

  • MITM interception — CA setup, per-host certificate generation, security considerations
  • elide serve — HTTP server
  • elide orb — full network orchestrator with reverse proxy, Tailscale, and more