# How OmniRoute Captures CLI Traffic Using MITM/TPROXY: A Technical Deep Dive

> Discover how OmniRoute captures CLI traffic using MITM TPROXY. Learn to redirect packets, decrypt TLS, and record requests with this technical deep dive.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: deep-dive
- Published: 2026-08-09

---

**OmniRoute captures command-line interface (CLI) network traffic by leveraging Linux TPROXY rules to redirect packets, terminating TLS with dynamically generated certificates, and recording decrypted requests before securely forwarding them to upstream services.**

OmniRoute is an open-source traffic inspection platform that enables developers to monitor HTTPS calls from local CLI tools without modifying application code. By implementing a layered **MITM/TPROXY** (Man-in-the-Middle/Transparent Proxy) architecture, the system intercepts encrypted traffic at the kernel level while preserving end-to-end behavior for the originating process.

## The Three-Stage MITM/TPROXY Architecture

OmniRoute’s capture mechanism operates through three distinct stages: traffic redirection, TLS decryption, and request recording.

### Stage 1: Kernel-Level Traffic Redirection via iptables

When **TPROXY mode** is enabled, OmniRoute constructs an iptables rule in the `mangle` table that intercepts outgoing TCP packets—typically targeting port 443 for HTTPS traffic. The rule generation logic resides in [`src/mitm/tproxy/commands.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/commands.ts), which produces a command similar to:

```bash
iptables -t mangle -A PREROUTING -p tcp --dport <port> \
  -m mark --mark <mark> -j TPROXY \
  --on-port <local-proxy-port> --tproxy-mark <mark>

```

The `applyTproxy` function in [`src/mitm/tproxy/setup.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/setup.ts) executes this rule, marking packets and redirecting them to OmniRoute’s local proxy listener. To prevent remote exploitation, [`src/server/authz/routeGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/routeGuard.ts) enforces that these rules can only be applied on the local host where OmniRoute is running.

### Stage 2: TLS Termination and Dynamic Certificate Generation

Once redirected, traffic reaches the TLS capture engine defined in [`src/mitm/tproxy/tlsCapture.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/tlsCapture.ts). Here, OmniRoute performs a full TLS handshake with the CLI client using **dynamically generated certificates**. For each intercepted domain, [`src/mitm/tproxy/dynamicCert.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/dynamicCert.ts) issues a leaf certificate signed by the MITM root CA located at [`src/mitm/cert/rootCa.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/cert/rootCa.ts).

The dedicated trust store implementation in [`src/mitm/tproxy/caTrust.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/caTrust.ts) manages these temporary credentials, ensuring the CLI tool receives a certificate it trusts (once the root CA is installed) while allowing OmniRoute to decrypt the payload.

### Stage 3: Recording and Re-encryption

After decryption, the request is structured as an `InterceptedRequest` object with `source: "tproxy"`, as defined in [`src/shared/schemas/inspector.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/schemas/inspector.ts). The capture API in [`src/lib/inspector/tproxyCaptureApi.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/inspector/tproxyCaptureApi.ts) records the sanitized headers and masked request bodies according to configured guardrails.

Crucially, OmniRoute **re-encrypts** the request before forwarding it to the real upstream service. This maintains the original CLI’s expected behavior while providing full visibility into the plaintext request/response cycle. The native addon in [`src/mitm/tproxy/transparentSocket.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/transparentSocket.ts) enables efficient transparent socket handling during this process.

## Capture Lifecycle Management and Cleanup

The [`src/mitm/tproxy/captureManager.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/captureManager.ts) module tracks active capture sessions, monitoring their status and associated process IDs. When a CLI process terminates or the user disables capture, the `revertTproxy` function in [`src/mitm/tproxy/setup.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/setup.ts) removes the iptables rules and deletes temporary certificate files, restoring the host’s original network configuration.

Programmatic control is exposed through the REST endpoint at [`src/app/api/tools/agent-bridge/tproxy/route.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/app/api/tools/agent-bridge/tproxy/route.ts), which handles the complete lifecycle:

- **POST**: Creates iptables rules, installs the dedicated CA, and starts the TLS capture engine
- **GET**: Returns the current `CaptureManagerStatus` and active configuration
- **DELETE**: Triggers cleanup via `revertTproxy`, removing rules and CA files

## Implementing TPROXY Capture in Practice

To enable MITM/TPROXY capture for a local CLI tool, interact with the agent-bridge API:

```typescript
// Enable TPROXY capture on port 8443 with mark 9011
await fetch('/api/tools/agent-bridge/tproxy', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ onPort: 8443, mark: 9011 })
});

```

Monitor active captures by querying the status endpoint:

```typescript
// Retrieve current capture status
const status = await fetch('/api/tools/agent-bridge/tproxy')
  .then(r => r.json()) as CaptureManagerStatus;

```

When finished, clean up the environment:

```typescript
// Disable capture and restore network state
await fetch('/api/tools/agent-bridge/tproxy', { method: 'DELETE' });

```

## Summary

- OmniRoute uses **Linux TPROXY** via iptables rules in [`src/mitm/tproxy/commands.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/commands.ts) to transparently redirect CLI traffic without application configuration.
- **Dynamic certificates** are generated per-host by [`src/mitm/tproxy/dynamicCert.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/dynamicCert.ts) and signed by the root CA in [`src/mitm/cert/rootCa.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/cert/rootCa.ts) to enable TLS decryption.
- Captured requests are stored as `InterceptedRequest` objects with `source: "tproxy"` via [`src/lib/inspector/tproxyCaptureApi.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/inspector/tproxyCaptureApi.ts) before being re-encrypted to upstream services.
- The [`captureManager.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/captureManager.ts) and `revertTproxy` functions ensure secure cleanup of iptables rules and certificates when sessions end.
- All capture operations are **local-only**, enforced by [`src/server/authz/routeGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/routeGuard.ts) to prevent unauthorized remote manipulation.

## Frequently Asked Questions

### What is TPROXY and why does OmniRoute use it for CLI traffic?

**TPROXY** is a Linux netfilter target that enables transparent proxying of TCP traffic without requiring the client application to configure a proxy explicitly. OmniRoute leverages TPROXY in [`src/mitm/tproxy/setup.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/setup.ts) because CLI tools often lack built-in proxy support; TPROXY intercepts packets at the kernel level before they leave the network stack, allowing OmniRoute to capture traffic from hardcoded HTTPS clients without code modifications.

### How does OmniRoute handle TLS certificates for HTTPS CLI tools?

OmniRoute maintains a dedicated MITM root CA in [`src/mitm/cert/rootCa.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/cert/rootCa.ts). When a TLS connection is intercepted by [`src/mitm/tproxy/tlsCapture.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/tlsCapture.ts), the [`src/mitm/tproxy/dynamicCert.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/dynamicCert.ts) module generates a domain-specific leaf certificate signed by this root. The CLI tool trusts this certificate once the root CA is installed in the system trust store, while OmniRoute maintains separate encrypted channels to the upstream service.

### Is the TPROXY capture mode secure for production environments?

According to the source code in [`src/server/authz/routeGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/routeGuard.ts), the TPROXY implementation is **strictly local-only** and guarded by route-level authorization. The architecture requires local host execution permissions to apply iptables rules, and cleanup routines in [`src/mitm/tproxy/setup.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/setup.ts) remove all network modifications and temporary certificates when captures end. However, as with any MITM tool, it should only be used in controlled development or testing environments with proper access controls.

### How do I programmatically start and stop TPROXY captures?

Send HTTP requests to the Next.js API route at `/api/tools/agent-bridge/tproxy` defined in [`src/app/api/tools/agent-bridge/tproxy/route.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/app/api/tools/agent-bridge/tproxy/route.ts). Use a **POST** request with JSON body `{"onPort": <port>, "mark": <mark>}` to initiate capture, a **GET** request to check `CaptureManagerStatus`, and a **DELETE** request to trigger the `revertTproxy` cleanup function and restore original network settings.