Skip to content

feat(mitm): TPROXY capture-mode manager (decrypt 4a/N) - #4208

Merged
diegosouzapw merged 1 commit into
release/v3.8.29from
feat/mitm-tproxy-capture-manager
Jun 18, 2026
Merged

diegosouzapw merged 1 commit into
release/v3.8.29from
feat/mitm-tproxy-capture-manager

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Summary

Epic A / Fase 3 — decrypt 4a/N. A singleton lifecycle manager around the decrypt-capable transparent listener (#4200), so a local-only route (4b) can drive start / stop / status without re-deriving the orchestration.

src/mitm/tproxy/captureManager.ts:

  • startCaptureMode — rejects when the native addon is unavailable or a session is already running; builds the dynamic CA (DynamicCertStore, feat(mitm): dynamic per-SNI cert authority for TPROXY (TLS decrypt 1/N) #4173); wires the injected installCa / uninstallCa through to the decrypt listener; counts interceptions via onIntercept.
  • stopCaptureMode — stops the running handle (which closes the listener, uninstalls the CA, and reverts the rules); idempotent no-op when nothing runs.
  • getCaptureStatus — { running, available, startedAt, interceptCount, onPort }.

The manager never touches the OS trust store itself — installCa / uninstallCa are injected. This is deliberate: the real Linux installer needs its own trust-store slot so it does not clobber the static MITM server cert (which cert/install.ts::installCert pins to a fixed LINUX_CERT_NAME), and that mechanism is best validated on the VPS. It also keeps the manager unit-testable without root or the native addon.

Test Plan

tests/unit/tproxy-capture-manager.test.ts (7/7) — all seams injected, no root/addon:

  • start rejects when the native addon is unavailable.
  • start wires the injected installCa/uninstallCa through to the decrypt listener (decrypt.installCa === installCa) and reports running + onPort.
  • start refuses a second concurrent session (already running).
  • stop invokes the handle's stop() and clears running state.
  • stop is a no-op when idle.
  • status counts interceptions reported via onIntercept.
  • status reports not-running when idle.

Validation: typecheck:core ✓, lint ✓ (0).

The intercept/decrypt/forward data path was proven e2e-locally in #4179 and unit-wired in #4200. Next (4b): the local-only API route + the real Linux trust-store installer (dedicated slot) + Traffic Inspector UI tab + VPS e2e-with-decrypt (real connectMarked + real CA install on the kernel) + addon prebuilds. startCaptureMode has no caller until that route lands.

🤖 Generated with Claude Code

Singleton lifecycle around the decrypt-capable transparent listener (#4200):
builds the dynamic CA (#4173), gates on native-addon availability, holds the
single running handle, counts interceptions, and exposes start / stop / status
for a local-only route (4b) to drive.

The OS trust-store mechanism is deliberately not baked in: installCa / uninstallCa
are injected by the caller (the route / VPS e2e provides the real installer, which
needs its own trust-store slot so it does not clobber the static MITM cert). The
manager therefore never mutates the trust store itself and stays unit-testable
without root or the native addon.

- startCaptureMode: rejects when unavailable or already running; builds the CA;
  wires the injected installCa/uninstallCa through to the decrypt listener.
- stopCaptureMode: stops the handle (close + uninstall CA + revert), idempotent.
- getCaptureStatus: running / available / startedAt / interceptCount / onPort.

Route + real trust-store installer + Traffic Inspector UI tab + VPS
e2e-with-decrypt + addon prebuilds follow (4b+).
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@diegosouzapw
diegosouzapw merged commit 4c6cb45 into release/v3.8.29 Jun 18, 2026
4 checks passed
@diegosouzapw
diegosouzapw deleted the feat/mitm-tproxy-capture-manager branch June 19, 2026 12:06
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…ence#4208)

Singleton lifecycle around the decrypt-capable transparent listener (cheaper-inference#4200):
builds the dynamic CA (cheaper-inference#4173), gates on native-addon availability, holds the
single running handle, counts interceptions, and exposes start / stop / status
for a local-only route (4b) to drive.

The OS trust-store mechanism is deliberately not baked in: installCa / uninstallCa
are injected by the caller (the route / VPS e2e provides the real installer, which
needs its own trust-store slot so it does not clobber the static MITM cert). The
manager therefore never mutates the trust store itself and stays unit-testable
without root or the native addon.

- startCaptureMode: rejects when unavailable or already running; builds the CA;
  wires the injected installCa/uninstallCa through to the decrypt listener.
- stopCaptureMode: stops the handle (close + uninstall CA + revert), idempotent.
- getCaptureStatus: running / available / startedAt / interceptCount / onPort.

Route + real trust-store installer + Traffic Inspector UI tab + VPS
e2e-with-decrypt + addon prebuilds follow (4b+).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant