Web Console

Chute serves a management console over HTTP from inside the running kernel. It is the only interface that is the same on every platform, so it is where this manual points whenever something needs to be looked at rather than configured — a request's routing, a rewrite that is not firing, why a connection was refused.

This is not Chute Dashboard. Dashboard is a separate macOS application that connects to a Chute instance; the console described here is served by the kernel itself and is reached with a browser.

Turning it on and getting in

The console needs external-http-controller in the [General] section. It is disabled by default:

[General]
external-http-controller = 127.0.0.1:9090
external-http-ui = true

Access is authenticated. If you do not set external-http-secret, Chute generates a token and keeps it in a control-token file, so the same token is reused across restarts — the practical way in is to let the app hand you the address with the token already attached. The page consumes the token from that address on load and keeps it in the browser's localStorage, so a browser signs in once. Every platform has an entry point for this; see Opening the web console.

Overview

Whether the service is running, how long it has been up, its memory use, the addresses and ports of the HTTP and SOCKS listeners, and the file paths this run is using. When you are unsure which instance a browser tab is pointed at, this page identifies it.

Traffic

Cumulative bytes and current speed for the whole engine, a speed history graph, and a per-adapter breakdown. Use it to answer "is anything moving at all", and to see which outbound is carrying the load when a policy group is choosing between several.

Connections

The page you will spend the most time on. Two tabs:

  • Current — connections that are open right now.
  • History — connections that have closed, newest first, read back from this run's records.

Each row carries the host, port, type, chosen policy, matched rule, duration and byte counts. The duration is counted from the moment this browser tab first saw the connection, not from when the connection was opened, so it means something on the Current tab only. Inspect expands the row in place and answers why this request went where it went:

Field What it tells you
Matched rule / Rule source The rule line that decided this connection, and which section it came from
Selected policy / Adapter The policy the rule chose, and the outbound that actually carried it
DNS source Which resolver answered, and whether it was a cache hit
Rewrites applied The rewrite or mock rules that changed this message, in the rule's own words — at most 16 hits are kept per connection, and the row then says how many more are not shown
Close reason / Notice Why it ended, and anything the kernel wanted to say about it

Below the table the expanded row shows the captured request and response — headers and body, as they went over the wire (decrypted, for hosts covered by HTTPS decryption).

Traffic recording is a prerequisite

Bodies are only there if Chute captured them. Turn recording on before reproducing the problem:

  • replica = true in [General], or
  • Chute Mac: menu bar → Traffic Capture, or
  • the API: PUT /api/features/record-traffic with {"enabled": true}.

Without it, connections still appear with their full routing attribution and timings — only the payloads are missing. The [Replica] section further limits what is captured — every filter there, hide-crashlytics-request included, is honoured — so a request that is filtered out there will show no body either.

Export HAR

Export HAR on the Connections page downloads the current tab as a HAR 1.2 file — capped at 100 entries, the endpoint's default (limit on the endpoint raises it to at most 300), while the History tab itself shows up to 200. HAR is a standard format: open it in a browser's developer tools (Network panel → import), or in tools such as Charles or Proxyman.

The export carries what those tools expect — request and response headers, timings, and bodies when recording was on — plus a _kl object per entry holding what HAR has no field for: the chosen policy, the matched rule, and the rewrites that fired. Timings for send and receive come from the capture's own timestamps rather than being inferred, so they mean something. The apps have exits of their own: Chute iOS's Dashboard offers Export as HAR and Export All as HAR, generated by the kernel in the same format, and a connection's detail window in Chute Mac has a Requests & History button that opens the console — its home page, not that particular connection. An entry is a connection: on a keep-alive connection that carried several requests, the export describes the first message and notes how many bytes of later messages it left out.

DNS

The resolver's cache with the answering server per record, the entries that came from [Host], and the system hosts file. Clear Cache purges the dynamic records; there is no per-record removal here — that exists only as DELETE /api/dns/records/:domain on the API.

Policies

The outbound mode (Rule / Global / Direct) and every policy group with its current selection. Changing a selection here takes effect immediately on the running kernel — it is the same action as switching a group in the apps.

Rules

Two different things share this page, and they behave differently.

Routing rules — the [Rule] section, listed in evaluation order. Read-only: they come from the configuration file.

Rewrite and mock rules — URL rewrite, header rewrite, body rewrite and Mock, plus the MitM host list. These can be added and removed here:

  • Paste a rule exactly as you would write it in the configuration file and press Add. A line that does not parse is refused with the parser's complaint rather than stored — a rule that can never match has no symptom, so it is better to hear about it now.
  • Remove deletes one rule; Clear empties a family.
  • Changes live in the running kernel only. They are not written back to the configuration file, and a reload or restart brings back what the file says. Use this to try a rule out, then write the one that worked into the file.

Rewrite & mock hits — every rewrite or mock rule that has fired during this run, with a count and the time it last matched; the table tracks up to 512 distinct rules and says how many more fired beyond that. This table is the answer to "my rewrite does nothing": a rule that never appears here has never matched, which is a different problem from a rule that matched and did nothing visible. See Why doesn't my rewrite do anything? for how to tell them apart.

Diagnostics

What the engine is holding, how the last run ended, and a set of probes you can fire at it.

  • Footprint / CPU / Uptime / Live flows / Superseded flows / Engine generation — the run's current shape. A footprint that climbs while flows stay flat is worth investigating; on iOS and tvOS it is also what the system watches before reclaiming the extension.
  • Previous exitClean, Terminated unexpectedly, or Killed for memory, with the previous run's id, uptime and peak footprint. Read this first when Chute "crashed": Killed for memory means the system reclaimed Chute rather than Chute failing, and that changes what to look for.
  • Refusals — a table of what the engine has declined and why, counted by resource and reason. When a connection was dropped and nothing else explains it, the reason is usually here.
  • Run a probe — reachability (ICMP, or TCP when you give a port), a DNS query through the running resolver, an egress-IP check, and a policy's latency test. Each is bounded and answers once. A policy name that is not defined is rejected rather than measured, so a typo comes back as a typo.
  • Events — the notable moments of this run: mass failures, egress changes, and similar.
  • Tailscale — the live engine state when a [Tailscale] section is configured; idle when there is none, which is a normal answer.
  • Download diagnostic bundle — one redacted archive to attach to a support message. See Sending a diagnostic bundle for what is in it.

Config

The running configuration, shown in an editable box, with Reload to apply what is in the box.

The configuration shown here has its secrets removed. Passwords, the control secret, the CA passphrase, WireGuard keys and similar appear as <redacted>. Pressing Reload applies exactly what is in the box, so reloading the text as-shown replaces those secrets with the literal word <redacted> in the running kernel — policies that need them will start failing. The configuration file is not touched, so selecting the configuration again restores it.

Use this page to read the configuration and to apply a change you have typed in full. To edit the file itself, use the editor in the apps.

Logs

A live tail of the kernel's log, coloured by level, with Pause while you read something. The verbosity is set by loglevel, not by this page — if the lines you need are not here, raise it and reproduce.

What the console can hand out

Treat access to the console as access to everything the run has seen. It can serve connection records carrying URLs, headers and process names, the captured request and response bodies, the configuration, and the log. That is why an unauthenticated controller is not the default, and why binding it anywhere other than loopback requires a secret you set yourself — see external-http-secret.

S. Smart Rabbit LLC © All Rights Reserved            updated 2026-09-01 13:16:36

results matching ""

    No results matching ""