Live Capture

Capture traffic in real time with mitmdump and tshark.

Instead of importing a finished file, Traffic Jam can record a session as it happens: the backend spawns tshark to write a pcapng, records TLS session keys to an NSS keylog while traffic flows, and parses the result into the capture library when you stop. Capture only traffic from systems you own or have written permission to test.

Requirements

ToolNeeded forNotes
tshark on PATHEvery live captureWrites the pcapng and enumerates interfaces (tshark -D). Not required for file import.
mitmdump on PATHProxy capture modeRuns as a TLS-intercepting proxy; keys are logged via SSLKEYLOGFILE.
Chrome or ChromiumBrowser capture modeFound on PATH (google-chrome, google-chrome-stable, chrome, chromium, chromium-browser) or at the macOS .app locations.

The capture panel shows a readiness grid (tshark, mitmdump, Chrome, Interfaces) and keeps the start button disabled until all four are ready. The packaged macOS app adds common Homebrew paths such as /opt/homebrew/bin when it starts the backend.

How a session is recorded

Every live capture runs tshark -i <interface> -w <name>.pcapng, plus your BPF filter (-f) if set. TLS key material comes from one of two sources, both written to a <name>.sslkeylog file beside the pcap:

  • Browser mode — Traffic Jam launches Chrome with a throwaway profile (--user-data-dir=<workspace>/chrome-profile --no-first-run --no-default-browser-check --new-window about:blank) and SSLKEYLOGFILE pointing at the keylog.
  • Proxy mode — Traffic Jam runs mitmdump --listen-host <host> --listen-port <port> with MITMPROXY_SSLKEYLOGFILE and SSLKEYLOGFILE set. You point the test device or browser at the proxy; every TLS connection through it has its keys logged.

Only one live capture can run at a time — starting a second fails with live capture already running (HTTP 409).

Start a browser capture

Open the Browser tab in the workspace, then use the Browser capture panel:

  1. Pick the capture Interface. Interfaces come from tshark -D; any or the first non-loopback interface is preselected.
  2. Optionally set Save to collection (default Browser captures) and a Capture name (default Chrome YYYY-MM-DD HH:MM:SS).
  3. Optionally narrow the BPF filter (default tcp port 443).
  4. Click Launch Chrome and capture. A fresh Chrome window opens — drive the target application there.
  5. Click Stop and import when you are done.

While a capture runs, the panel polls status every 2 seconds and shows elapsed time, pcap and keylog sizes, and per-process state for tshark, Chrome, and the proxy.

Capture through the mitmdump proxy

Use proxy mode when the traffic originates from another device or a browser Traffic Jam did not launch. It is exposed through the start endpoint (omit launchBrowser):

POST /api/live-capture/start
Content-Type: application/json

{
  "name": "android-app",
  "interface": "en0",
  "proxyHost": "127.0.0.1",
  "proxyPort": 8080,
  "bpf": "tcp port 8080",
  "folderPath": "Proxy captures"
}

Then configure the test device or browser to use 127.0.0.1:8080 (or your chosen host and port) as its HTTP proxy.

[!NOTE] mitmproxy terminates TLS with its own certificate authority, so the test device must trust mitmproxy’s CA for connections to succeed (mitmproxy serves it at http://mitm.it through the proxy). Decryption inside Traffic Jam comes from the recorded keylog, not from the CA.

Because proxy traffic arrives on a non-standard port, the import step tells the parser to decode the proxy port as TLS (-d tcp.port==<proxyPort>,tls); browser mode needs no such hint.

[!WARNING] Intercepting traffic you are not authorized to access is unlawful in most jurisdictions. Route only your own test devices through the proxy, and treat the resulting artifacts — which contain decrypted request and response bodies — with the same controls as any other evidence.

Artifacts and storage

Each session gets a directory <capture-dir>/<session-id>/ containing:

FileContents
<name>.pcapngRaw packets written by tshark
<name>.sslkeylogNSS TLS key log
chrome-profile/Throwaway Chrome profile (browser mode only)

<name> is the capture name sanitized to lowercase letters, digits, ., _, and - (anything else becomes -, capped at 80 characters); an empty name falls back to the session ID.

The capture directory resolves as follows:

ConditionDirectory
Default.traffic-jam/live-captures relative to the API working directory
TRAFFIC_JAM_DB_PATH set (desktop builds)live-captures beside the database file
TRAFFIC_JAM_CAPTURE_DIR setThat directory, always
export TRAFFIC_JAM_CAPTURE_DIR=/path/to/live-captures

Stop and import

Stopping sends SIGINT to each process, waits up to 3 seconds, then kills any survivor. The backend then parses the pcapng in-process with gopacket (tshark is not needed at import time), decrypts supported TLS 1.2/1.3 sessions with the recorded keylog, and saves the session to the SQLite capture library under the folder you chose. The UI switches to the Captures tab and reports N requests, M complete. The pcap and keylog stay on disk, so you can re-import the session or open the same files in Wireshark.

Stopping the API server also stops a running capture.

Limits and API reference

ItemValue
Concurrent captures1 (409 live capture already running)
Proxy defaultshost 127.0.0.1, port 8080 (port must be 1–65535)
BrowserChrome only (only Chrome browser capture is supported)
InterfaceRequired; enumerated via tshark -D (5 s timeout)
Process stop grace3 s SIGINT, then kill
Error reportingLast 8 KiB of each process’s output is retained and surfaced in status

Backend endpoints:

EndpointMethodPurpose
/api/live-capture/interfacesGETList capture interfaces from tshark -D
/api/live-capture/statusGETRunning state, artifact sizes, process health, tool paths
/api/live-capture/startPOSTStart a session (fields shown above)
/api/live-capture/stopPOSTStop, parse, and import the session

For file import, TLS decryption with external keylogs, and what happens to sessions once they land in the library, see /docs/en/capture/ and /docs/en/getting-started/.

Traffic Jam documentation. Built with Hugo.