Repository navigation
fix(mitm): forward anti-loop — bypass-marked socket on the Agent (decrypt 4d, VPS-validated) - #4229
Merged
Conversation
…ent (decrypt 4d) The TPROXY decrypt forward (#4179/#4200) opened its upstream socket via https.request({ agent: false, createConnection }). But https.request SILENTLY IGNORES the createConnection request option whenever an agent is present -- and agent: false still installs a fresh default Agent -- so createConnection (and thus connectMarked) never ran. The forward opened its own UNMARKED socket. On a real TPROXY host that re-intercepts the proxy's own forward, an unmarked forward is re-intercepted -> decrypted -> forwarded -> re-intercepted -> infinite loop. The local unit test could not catch it: with no kernel interception an unmarked forward reaches the upstream just the same. Fix: move the bypass-marked socket onto a dedicated https.Agent's createConnection (where Node actually honors it; keepAlive:false so no socket lingers). Validated on the production VPS (kernel 6.8.0, TEST port 18443, never 443): - before: createConnection invoked 0 times, 1298-capture loop, client timeout; - after: exactly 1 interception, full decrypt round-trip (client received the upstream body), the decrypted request captured as source "tproxy" with the bearer token masked; rules + route + CA cleanly reverted. The new unit test asserts the forward dials through connectRaw (the marked seam) -- it fails against the pre-fix code (createConnection never invoked) and is the permanent regression guard.
Contributor
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This was referenced Jun 19, 2026
Merged
tkgo11
pushed a commit
to tkgo11/OmniRoute
that referenced
this pull request
Sep 23, 2026
…ent (decrypt 4d) (cheaper-inference#4229) Integrated into release/v3.8.29 (MITM TPROXY decrypt 4d — forward anti-loop: bypass-marked socket on the Agent; VPS-validated).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Epic A / Fase 3 — decrypt 4d: the VPS e2e validation of the decrypt capture mode, which caught and fixed a real anti-loop bug in the merged forward path.
The bug. The decrypt forward (#4179/#4200) opened its upstream socket via
https.request({ agent: false, createConnection }). Buthttps.requestsilently ignores thecreateConnectionrequest option whenever an agent is present — andagent: falsestill installs a fresh default Agent — socreateConnection(and thusconnectMarked) never ran. The forward opened its own unmarked socket. On a real TPROXY host the OUTPUT rule re-intercepts the proxy's own forward → decrypt → forward → re-intercept → infinite loop. The local unit test in #4179 couldn't catch this: with no kernel interception, an unmarked forward reaches the upstream just the same.The fix. Move the bypass-marked socket onto a dedicated
https.Agent'screateConnection, where Node actually honors it (keepAlive:false, so no socket lingers).VPS validation (Hard Rule #18 — documented live test)
Real merged code bundled (esbuild, only the buffer/DB sink stubbed) + the prebuilt native addon, run as root on the production VPS (kernel
6.8.0-124), on a TEST port18443(never 443), with sysctls saved/restored and rules/route/CA force-cleaned on exit:createConnectioninvokedHTTP 200 PONG-DECRYPTEDin-flightsource:"tproxy",GET /decrypt-probe,status:200, secret maskedA control run of the raw tunnel (no decrypt, same
connectMarked) round-tripped cleanly (rawIntercepts:1), isolating the defect to the decrypt forward — not loopback. Post-run state:0rules, table empty, CA removed.Test Plan
tests/unit/tproxy-tls-capture.test.ts(6/6) — adds "the forward dials its upstream through connectRaw (the bypass-marked seam)": spies onconnectRawand asserts it is invoked. It fails against the pre-fix code (createConnection never runs →connectRawnever called) and is the permanent regression guard. The existing decrypt round-trip + masking + 502 tests still pass.Validation:
typecheck:core✓,lint✓ (0),tproxy-tls-capture6/6,tproxy-capture-mode+tproxy-capture-manager16/16.🤖 Generated with Claude Code