Proxy Server
A proxy server forwards requests to an upstream proxy. Chute supports HTTP/HTTPS/SOCKS5/SOCKS5-TLS/SS/SSR/Trojan/VMess/VLESS/AnyTLS/TUIC/Hysteria2/WireGuard/AmneziaWG/ShadowTLS/MASQUE/SSH proxy protocols.
Section [Proxy] declares proxy servers. You can create multiple proxy servers for different rules.
Example:
[Proxy]
ProxyHTTP = http, 1.2.3.4, 443, username, password
ProxyHTTPS = https, 1.2.3.4, 443, username, password, sni=example.com
ProxySOCKS5 = socks5, 1.2.3.4, 443, username, password
ProxySOCKS5TLS = socks5-tls, 1.2.3.4, 443, username, password, sni=example.com
SS = ss, 1.2.3.4, 443, method, password, obfs=http
SSR = ssr, 1.2.3.4, 443, method, password, protocol=auth_chain_f, protocol_param=user:pass, obfs=http_post, obfs_param=example.com
Trojan = trojan, 1.2.3.4, 443, password=password, tls=true, sni=example.com, skip-cert-verify=false, ws=true
VMess = vmess, 1.2.3.4, 443, uuid=uuid, sni=example.com, tls=true, ws=true
VLESS = vless, 1.2.3.4, 443, uuid=uuid, sni=example.com, xtls=true
AnyTLS = anytls, 1.2.3.4, 443, password, sni=example.com
TUIC = tuic, 1.2.3.4, 443, uuid=uuid, password=password, sni=example.com
Hysteria2 = hysteria2, 1.2.3.4, 443, auth=password, sni=example.com, up=10, down=100
WireGuard = wireguard, private-key=base64key, peer-public-key=base64key, section-name=wg0, self-ip=10.0.0.2
AmneziaWG = amneziawg, section-name=awg0
ShadowTLS = shadowtls, 1.2.3.4, 443, password=password, sni=example.com, skip-cert-verify=false, fingerprint=chrome
ProxyMASQUE = masque, 1.2.3.4, 443, token=auth-token, mode=connect-udp, sni=example.com, alpn=h3, skip-cert-verify=false
SSH = ssh, 1.2.3.4, 22, root, password=pw
SCHEME = scheme, ssr://....
Notice: A Trojan policy needs an explicit
tls=true— TLS is not implied. Without it (and withoutgrpc=true, which always runs over TLS) the policy connects in plaintext, and the log says so when the configuration loads:Trojan policy <name> has no tls=true; it connects without TLS. Importing a Clash/mihomo profile writestls=trueon every Trojan node.Notice:
schemetakes a share link of one of these kinds:ss://,ssr://,anytls://,tuic://,hysteria2://andshadowtls://. A link of any other kind makes the line a configuration error.
Parameters
| Type | Username | Password | Method | TLS | XTLS | Websocket | QUIC |
|---|---|---|---|---|---|---|---|
| HTTP | √ | √ | |||||
| HTTPS | √ | √ | TLS | ||||
| Socks | √ | √ | |||||
| SOCKS5-TLS | √ | √ | TLS | ||||
| Shadowsocks | √ | Method, OBFS | TLS, Fingerprint, ECH | WS | |||
| ShadowsocksR | √ | Method, Protocol, OBFS | TLS, Fingerprint, ECH | WS | |||
| Trojan | √ | TLS, Fingerprint, ECH | WS, gRPC, XHTTP | ||||
| VMess | uuid | TLS, Fingerprint, ECH | WS, gRPC, XHTTP | ||||
| VLESS | uuid | TLS, Fingerprint, ECH | XTLS | WS, gRPC, XHTTP | |||
| AnyTLS | √ | TLS | |||||
| TUIC | uuid | √ | TLS | √ | |||
| Hysteria2 | auth | TLS | √ | ||||
| WireGuard | private-key | Native WireGuard | |||||
| AmneziaWG | private-key | Native WireGuard | |||||
| ShadowTLS | √ | TLS, Fingerprint | |||||
| MASQUE | token | TLS, Mode, Mux | √ | ||||
| SSH | √ | Auth | |
Parameter for proxy with TLS
tls: Optional.
tls=true
Enable TLS transportation.
skip-cert-verify: Optional
skip-cert-verify=true
If this option is enabled, Chute will not verify the server's certificate. true, 1 and yes all enable it, so share links that write insecure=1 work. skip-common-name-verify=true, Shadowrocket's spelling on socks5-tls lines, is read as the same option.
sni (Default: hostname)
sni=exmaple.com
You may customize Server Name Indication (SNI) during TLS handshake. By default Chute will send SNI with hostname like most browsers.
fingerprint: Optional.
fingerprint=chrome
Present a browser's TLS ClientHello instead of the system one, so the handshake
does not stand out as belonging to a proxy client. Supported values are
chrome, firefox, safari and ios, plus edge, 360, qq, android and
random, which are all handled as Chrome. The names mihomo, sing-box and Xray
use are accepted too and map onto the same four presets: randomized,
chrome_pq and hellochrome_131, for instance, are handled as Chrome,
hellofirefox_120 as Firefox, hellosafari_16_0 as Safari and helloios_14
as iOS. Xray's hellogolang has no preset.
This applies to Trojan, VMess and VLESS over TLS, including their WebSocket and
gRPC transports, and to Shadowsocks and ShadowsocksR over
WebSocket with TLS. REALITY and
ShadowTLS take the same option in their own sections. To set one fingerprint for
every policy that does not name its own, use
global-client-fingerprint.
It always reaches ShadowTLS policies, and reaches VLESS ones that set tls=true
or reality=true, Trojan and VMess ones that set tls=true, and Shadowsocks
ones that set both ws=true and tls=true; a policy on the gRPC transport
needs tls=true written as well. ShadowsocksR policies never take it.
On these protocols fingerprint=none — or unsafe, which means the same —
selects the system TLS stack, and it wins over global-client-fingerprint.
REALITY and ShadowTLS cannot do without the browser handshake, so there none
refuses the connection. A value Chute does not recognise refuses the policy's
connections instead of falling back, on every protocol: nothing is sent to the
server, the connection fails — a url-test or fallback group counts it like any
other failure — and loading the configuration logs
Policy <name>: fingerprint '<value>' is not supported; connections through this policy are refused.
An unrecognised global-client-fingerprint, by contrast, is only ignored.
Setting a fingerprint also turns on post-quantum key exchange: Chute then offers the X25519MLKEM768 hybrid group alongside X25519, so the session cannot be decrypted later by an attacker who records it today and gains a quantum computer tomorrow. A server that does not understand the group simply picks X25519, so nothing breaks. Without a fingerprint the connection uses the system TLS stack, which does not offer it — the same reason ECH needs a fingerprint.
Parameter for proxy with Shadowsocks
method: Required.
Current support:
rc4-md5
aes-128-cfb
aes-192-cfb
aes-256-cfb
aes-128-ctr
aes-192-ctr
aes-256-ctr
bf-cfb
camellia-128-cfb
camellia-192-cfb
camellia-256-cfb
salsa20
chacha20
chacha20-ietf
aes-128-gcm
aes-192-gcm
aes-256-gcm
chacha20-ietf-poly1305
xchacha20-ietf-poly1305
Shadowsocks 2022 Methods
Chute supports the Shadowsocks 2022 protocol, which uses BLAKE3-based key derivation and AEAD ciphers. The method name determines the cipher suite:
2022-blake3-aes-128-gcm
2022-blake3-aes-256-gcm
2022-blake3-chacha20-poly1305
Password format:
The password field for SS2022 consists of one or two base64-encoded keys, separated by : (colon).
Single-user mode (one key):
SS2022 = ss, 1.2.3.4, 443, 2022-blake3-aes-256-gcm, "base64-key"
Multi-user mode with identity headers (two keys):
For 2022-blake3-aes-128-gcm and 2022-blake3-aes-256-gcm, you can provide an identity header key and a user key, separated by ::
SS2022 = ss, 1.2.3.4, 443, 2022-blake3-aes-256-gcm, "header-base64-key:user-base64-key"
Each key is a base64-encoded string (supports both standard and URL-safe base64). The key lengths required:
| Method | User Key Length | Header Key Length |
|---|---|---|
2022-blake3-aes-128-gcm |
16 bytes | 16 bytes |
2022-blake3-aes-256-gcm |
32 bytes | 32 bytes |
2022-blake3-chacha20-poly1305 |
32 bytes | N/A (no identity header support) |
Generate a key:
openssl rand -base64 32
Note: SS2022 methods do not support the
obfsparameter. The2022-blake3-chacha20-poly1305method does not support multi-user mode.
Shadowsocks AEGIS Methods
Chute also supports the AEGIS family of AEAD ciphers. They are built on the AES round function and are markedly faster than AES-GCM or ChaCha20-Poly1305 on any processor with hardware AES, which includes every recent iPhone, iPad, Apple TV and Mac:
aegis-128l
aegis-256
They are configured like the classic AEAD methods above — the password is an ordinary passphrase, not a base64 key:
AEGIS = ss, 1.2.3.4, 443, aegis-128l, your-password
| Method | Key | Nonce | Tag |
|---|---|---|---|
aegis-128l |
16 bytes | 16 bytes | 16 bytes |
aegis-256 |
32 bytes | 32 bytes | 16 bytes |
Everything else follows SIP004 unchanged: the salt is as long as the key, the session subkey is HKDF-SHA1(key, salt, "ss-subkey"), TCP payload is carried in length-prefixed AEAD chunks with the nonce incremented after each operation, and UDP uses an all-zero nonce.
You have to run the server yourself. AEGIS is not part of the Shadowsocks specification — no SIP defines it, and no mainstream Shadowsocks server implements it, including shadowsocks-rust, shadowsocks-libev, shadowsocks-go, sing-box and Xray. Choosing one of these methods only works against a server you operate that has been built to support them. If you are pointing Chute at a commercial or shared node, use one of the interoperable methods above instead.
obfs: Optional.
Current support:
tls
http
obfs_param: Optional.
obfs_param=example.com
Sets the Host used by the obfs layer. Defaults to cloudfront.net when unset.
WebSocket (v2ray-plugin): Optional.
ws=true, ws-path=/path, ws-headers=Host:example.com, tls=true, sni=example.com, skip-cert-verify=false
Carries the Shadowsocks stream inside a WebSocket, the way the websocket mode of v2ray-plugin does, so the policy reaches a Shadowsocks server that runs behind v2ray-plugin, a CDN in front of it included. The options are those of the WebSocket transport and of TLS. Shadowsocks 2022 methods work over it, and ShadowsocksR policies take the same options while keeping their own protocol and obfs.
ws-pathdefaults to/, and a path written without its leading slash gets one.- The
Hostof the upgrade request is the Host inws-headers, used as written. Without one it is thesni— or the server address when there is nosni— followed by:<port>. tls=trueruns TLS underneath the WebSocket.sni,skip-cert-verify, fingerprint and the ECH options work as they do for Trojan. Withoutws=true,tls=truedoes nothing: the policy connects without TLS, and the line gets the advisoryShadowsocks tls=true only applies with ws=true (the v2ray-plugin transport); this policy connects without TLS.ws-mux(defaulttrue) opens one mux.cool session on each WebSocket, which is what a v2ray-plugin server started with its defaultmux=1expects. For a server started withmux=0, writews-mux=false.- With
obfs=on the same line the WebSocket is used and simple-obfs is not applied; loading the configuration logsPolicy <name> ignored unsupported option(s): obfs. - UDP does not go through the plugin: it is plain Shadowsocks UDP, sent straight to
host:port, which does not get through a CDN. Writeudp-relay=falsefor a server you reach through one. When the Shadowsocks server behind the plugin speaks UoT,udp-over-tcp=truecarries UDP inside the policy's streams instead, and so through the WebSocket as well. - The quic mode of v2ray-plugin is not supported.
Shadowrocket's spelling is read as well: obfs=websocket (or obfs=ws), with the Host in obfsParam or obfs-host and the path in path or obfs-uri. The policy is saved as ws=true. Any other obfs value the Shadowsocks stack cannot read — Quantumult X's wss, or a typo — is named in an advisory, and the policy connects as plain Shadowsocks: Shadowsocks over WebSocket (the v2ray-plugin transport) is written ws=true, with ws-path= and ws-headers=; obfs=<value> is not read, so this policy would connect as plain Shadowsocks.
SS = ss, 1.2.3.4, 443, aes-256-gcm, password, ws=true, ws-path=/ws, ws-headers=Host:cdn.example.com, tls=true, sni=cdn.example.com
udp-over-tcp: Optional.
udp-over-tcp=true, udp-over-tcp-version=2
Carries the policy's UDP inside TCP connections of the policy instead of the server's UDP relay — sing-box's UDP over TCP (UoT). Each UDP flow gets a connection of its own to the rendezvous address the server recognises (sp.v2.udp-over-tcp.arpa, or sp.udp-over-tcp.arpa for version 1). These are ordinary connections of the policy, so they follow its underlying-proxy like any other: UDP then works through an upstream that carries no UDP, such as an HTTP proxy, and through the WebSocket transport. The server has to support UoT, as sing-box and mihomo servers do. Shadowsocks 2022 methods work with it.
udp-over-tcp-version(default2): version 2 opens each connection with a request naming the destination, then frames every datagram by its length; version 1 has no request and puts the address in front of every datagram. mihomo's default is version 1, so a profile imported from mihomo writes the version out. Any other value is reported, used as2, and kept as written when the profile is saved.udp-relay=falsestill turns UDP off for the policy.- In the app's Shadowsocks editor these are the UDP over TCP switch and the UoT Version choice.
SS = ss, 1.2.3.4, 8388, aes-256-gcm, password, udp-over-tcp=true
Parameter for proxy with ShadowsocksR/ShadowsocksRR/ShadowsocksR-Akarin
method: Required.
Current support:
rc4
rc4-md5-6
rc4-md5
aes-128-cfb
aes-192-cfb
aes-256-cfb
aes-128-ctr
aes-192-ctr
aes-256-ctr
bf-cfb
camellia-128-cfb
camellia-192-cfb
camellia-256-cfb
cast5-cfb
des-cfb
idea-cfb
rc2-cfb
seed-cfb
salsa20
chacha20
chacha20-ietf
protocol: Optional.
Current support:
origin
auth_sha1
auth_sha1_v2
auth_sha1_v4
auth_aes128_md5
auth_aes128_sha1
auth_chain_a
auth_chain_b
auth_chain_c
auth_chain_d
auth_chain_e
auth_chain_f
auth_akarin_rand
auth_akarin_spec_a
protocol_param: Optional.
obfs: Optional.
Current support:
plain
http_simple
http_post
tls1.2_ticket_auth
obfs_param: Optional.
Parameter for proxy with WebSocket
WebSocket transport is available for Trojan, VMess and VLESS, and for Shadowsocks and ShadowsocksR, where it is the websocket mode of v2ray-plugin — see WebSocket (v2ray-plugin) for what differs there.
ws: Optional.
ws=true
Enable WebSocket transportation.
ws-path: Optional.
ws-path=/exmaple
Change the path of the WebSocket HTTP request.
ws-headers: Optional.
ws-headers=Header1:Value1|Header2:Value2
Modify the HTTP header of WebSocket HTTP request.
Parameter for proxy with gRPC
gRPC transport is available for Trojan, VMess, and VLESS protocols. It uses HTTP/2-based gRPC framing over TLS, which can help bypass certain network restrictions.
grpc: Optional.
grpc=true
Enable gRPC transportation. The transport always runs over TLS, whatever the policy's tls value is. Write tls=true anyway if the policy should take global-client-fingerprint, which reaches a gRPC policy only when it sets it.
grpc-service-name: Required when grpc=true.
grpc-service-name=MyService
Specify the gRPC service name/path for multiplexing. It must match the service name configured on the server; there is no default.
grpc-multi-mode: Optional.
grpc-multi-mode=true
Use Xray's multi mode: the tunnel calls /<service>/TunMulti instead of /<service>/Tun, and several writes travel in one gRPC message. The server has to support multi mode. Each tunnel still has a connection of its own.
Example with VMess and gRPC:
VMess = vmess, 1.2.3.4, 443, uuid=uuid, tls=true, grpc=true, grpc-service-name=GunService, sni=example.com
Parameter for proxy with XHTTP
XHTTP transport is available for Trojan, VMess, and VLESS protocols. Instead of holding one connection open, it carries the tunnel inside ordinary HTTP requests: the download arrives as one long-lived response, and the upload goes out either as a series of POSTs or as one long-lived POST. That makes it usable through a CDN, which is the main reason to choose it over WebSocket or gRPC.
The HTTP version is not configured directly. Without TLS it is HTTP/1.1; with
TLS it is HTTP/2, unless alpn says exactly http/1.1 (HTTP/1.1) or exactly
h3 (HTTP/3). REALITY always uses HTTP/2.
xhttp: Optional.
xhttp=true
Enable XHTTP transportation.
xhttp-mode: Optional.
xhttp-mode=packet-up
How the upload is carried. auto (the default) means packet-up, or
stream-one when REALITY is in use.
packet-up— the upload is a series of numbered POSTs. The most compatible choice, and the one CDNs handle best.stream-up— the upload is one long-lived POST, with the download on a separate request.stream-one— one request carries both directions. Needs a server and any middlebox in between to support full-duplex HTTP.
The server usually pins a mode; a mismatch is answered with 400.
xhttp-path: Optional.
xhttp-path=/yourpath
The request path. Defaults to /. It must match the path the server serves
XHTTP on.
xhttp-host: Optional.
xhttp-host=example.com
The authority used in the Host header and the request URL. Defaults to sni,
and to the server address when that is unset.
xhttp-headers: Optional.
xhttp-headers=Header1:Value1|Header2:Value2
Extra HTTP headers, in the same format as ws-headers.
xhttp-padding: Optional.
xhttp-padding=100-1000
Length range of the padding every request carries, as MIN-MAX or a single
number. Defaults to 100-1000. The server requires padding and validates its
length, so this has to stay inside the range the server accepts — a request
with none, or with the wrong amount, is answered 400.
xhttp-max-post-bytes: Optional.
xhttp-max-post-bytes=1000000
Largest upload POST, in bytes. Defaults to 1000000. Larger writes are split
across several POSTs.
xhttp-min-post-interval: Optional.
xhttp-min-post-interval=30
Minimum gap between consecutive upload POSTs, in milliseconds. Defaults to 30.
xhttp-xmux-max-concurrency, xhttp-xmux-max-connections, xhttp-xmux-max-reuse-times, xhttp-xmux-max-lifetime: Optional.
xhttp-xmux-max-concurrency=4
XMUX pools the underlying HTTP/2 connections so several tunnels share one, which
looks like an ordinary browser session rather than a connection per tunnel. All
four default to 0, which leaves pooling off.
xhttp-xmux-max-concurrency— tunnels allowed to share one connection.xhttp-xmux-max-connections— connections allowed per server.xhttp-xmux-max-reuse-times— tunnels a connection serves before it stops taking new ones.xhttp-xmux-max-lifetime— seconds after which a connection stops taking new tunnels.
Note that mux=true is refused for an XHTTP policy, whatever its protocol, and
loading the configuration logs Policy <name> ignored unsupported option(s): mux:
XHTTP brings its own multiplexing, and stacking the generic one on top would
double it.
xhttp-download-server, xhttp-download-port: Optional.
xhttp-download-server=cdn.example.com
Route the download through a different address — a CDN in front of the same server, typically — while the upload keeps using the main one. Both must reach the same server: the session is server-side state, so a second route is fine but a second server is not.
Example with VLESS and XHTTP:
VLESS = vless, 1.2.3.4, 443, uuid=uuid, tls=true, xhttp=true, xhttp-mode=packet-up, xhttp-path=/yourpath, sni=example.com
Parameter for proxy with XTLS
xtls: Optional.
xtls=true
Wrap the transport in XTLS. On its own it announces no flow: the VLESS request carries an empty addons block, so no flow is negotiated. Use flow=xtls-rprx-vision below to announce one; xtls-rprx-direct is not implemented.
flow: Optional.
flow = xtls-rprx-vision
Select the XTLS flow control. The only supported value is xtls-rprx-vision, which enables Vision framing; the flow value is sent to the server in the VLESS addons.
skip-cert-verify: Optional
skip-cert-verify=true
Same as TLS.
sni (Default: hostname)
sni=exmaple.com
Same as TLS.
Parameter for proxy with REALITY
REALITY is a TLS-based obfuscation technique that makes proxy traffic indistinguishable from regular TLS traffic to a real website. It can be used with the VLESS protocol.
reality: Optional.
reality=true
Enable REALITY obfuscation. Requires a target server that will act as the camouflage destination.
public-key: Required.
public-key=BASE64KEY
The server's X25519 public key (base64). The REALITY handshake cannot be constructed without it.
short-id: Optional.
short-id=abcd1234
A short identifier used for REALITY authentication. Typically a hex string.
server-name: Optional.
server-name=www.microsoft.com
The SNI (Server Name Indication) to present during the TLS handshake. This should be a real, commonly-accessed website for best camouflage effect. The target server's certificate must match this name.
fingerprint: Optional.
fingerprint=chrome
TLS client fingerprint to mimic. Supported values include chrome, firefox, safari, ios, edge, 360, qq, android, random, and the other names listed under fingerprint. Using a common browser fingerprint helps avoid detection. Note that android and random are not distinct here — they are treated as chrome. none and any value Chute does not recognise refuse the connection, because the system TLS stack cannot do this handshake.
spiderx: Optional.
spiderx=/path
Custom path for REALITY spider camouflage.
Example with VLESS:
VLESS = vless, 1.2.3.4, 443, uuid=uuid, reality=true, public-key=BASE64KEY, server-name=www.microsoft.com, short-id=abcd, fingerprint=chrome
Note: REALITY does not use a traditional certificate. The connection uses the camouflage server's real certificate.
Parameter for proxy with ECH
Encrypted Client Hello hides the server name from anyone watching the
connection. The real name travels encrypted inside the handshake, while the
name on the wire is the public_name published by the server's ECHConfig.
ECH is built on the same stack as the client fingerprint, so a policy must set
fingerprint as well — without one, ech=true does
nothing and the real name is sent in the clear. It applies to Trojan, VMess and
VLESS over plain TLS, including their WebSocket transports, and to Shadowsocks
and ShadowsocksR over WebSocket with TLS.
Notice: The gRPC and XHTTP transports do not support ECH. With
grpc=trueorxhttp=true,ech=trueis silently ignored and the real server name is sent in the clear. (The client fingerprint and post-quantum key exchange do apply to gRPC and XHTTP.)
ech: Optional.
ech=true
Enable ECH. Unless ech-config is set, Chute looks the ECHConfig up in the
server name's DNS HTTPS record, the same way a browser does.
ech-config: Optional.
ech-config=AEX+DQBBAAAgACD...
A base64 ECHConfigList, used instead of the DNS lookup. Set this when the
server publishes no HTTPS record, or to pin a specific config. Setting it turns
ECH on by itself; ech=true is not needed as well.
ech-public-name: Optional.
ech-public-name=cover.example.com
Overrides the cover name sent in the clear. By default it is the public_name
inside the ECHConfig, which is what the server expects; only set this for a
deployment that fronts the config with a different host.
Example with Trojan:
Trojan = trojan, 1.2.3.4, 443, password=pw, tls=true, sni=secret.example.com, fingerprint=chrome, ech=true
If the server rejects ECH — most often because the config went stale — it answers under the cover name and presents that name's certificate, and the handshake falls back to the outer TLS. As long as certificate verification is on, the connection then fails to authenticate rather than quietly continuing; with
skip-cert-verify=truenothing checks that name and the session silently continues under the cover name. Refreshech-config, or remove it to go back to the DNS lookup.
TCP Fast Open (Experimental)
tfo: Optional
tfo=true
More information of TCP fast open could be read in Wikipedia. Enable TCP fast open may could unexpected connection fail. Chute Android ignores tfo.
Common Parameters
udp-relay: Optional (Default: true)
udp-relay=false
Marks the policy TCP-only. UDP relay is on by default where the protocol supports it; set udp-relay=false to exclude the policy from relaying UDP traffic. Trojan relays UDP over a plain TLS connection to the server port — without WebSocket, gRPC or XHTTP, and without ECH, though with the policy's fingerprint — so against a server that only serves one of those transports, set udp-relay=false.
mux: Optional
mux=true
Enable connection reuse / multiplexing. Aliases multiplex and reuse are also accepted. Supported by HTTP/HTTPS, SOCKS5/SOCKS5-TLS, Trojan, VMess, VLESS, Hysteria2, Shadowsocks(R), ShadowTLS and MASQUE. AnyTLS, TUIC and SSH are not multiplexed on any platform. For these, mux=true is not applied, and the log says so when the configuration loads: Policy <name>: mux=true is not applied: <reason>.
Hysteria2 and MASQUE multiplex over one shared QUIC connection. Every other protocol carries the multiplexed connections in a framing of Chute's own, which only a server that understands it can take apart: standard Xray, sing-box and Shadowsocks servers cannot, so do not turn mux on for them.
cert-fingerprint-sha256: Optional
cert-fingerprint-sha256=<hex>
Pin the server certificate by its SHA-256 fingerprint. The alias cert-fp is also accepted. Currently only effective for MASQUE.
encrypt-method (VMess): Optional (Default: auto)
encrypt-method=aes-128-gcm
VMess payload encryption. Supported values: aes-128-gcm, chacha20-poly1305, aes-128-cfb (alias legacy), none.
alpn: Optional
alpn=h2|http/1.1
Multiple ALPN values are separated with |. Only TUIC, Hysteria2 and MASQUE read it — each defaults to h3 when it is unset — together with XHTTP, where it selects the HTTP version the transport speaks. Every other protocol ignores this option and offers the ALPN its transport decides: h2 for gRPC; with a fingerprint, http/1.1 for WebSocket and h2,http/1.1 for plain TLS; without one, none for either, since the system TLS stack then does the handshake.
underlying-proxy: Optional.
underlying-proxy=OtherProxy
Proxy chaining: the value names another policy or policy group that carries this policy's traffic. The upstream is selected before the policy opens its own server connection, so A = ..., underlying-proxy=B sends A's connection through B. B may name another upstream for multiple hops. Leave it empty, or write DIRECT, to connect directly. Quote a name that contains a space or a comma, as in underlying-proxy="HK 01". A missing name fails closed and is logged; the policy does not fall back to DIRECT.
A loop made of fixed references — including one that comes back through the own underlying-proxy of a relay group's first member — is refused when the configuration loads. A loop that exists only because of what a policy group has chosen right now is not refused for good: once the group chooses otherwise the policy works, but while the loop holds, every connection through it is refused. Whatever the shape of the chain, a connection that would nest more than 16 upstream levels deep is refused rather than unfolded without end.
The upstream also resolves this policy's server name: a chained server is never looked up by the local resolver, and Chute does not ping it directly — nor any policy after the first member of a relay group. Its latency comes from group health checks and the latency test, which both reach it through the chain — url-test, fallback and load-balance groups probe a chained member the way a connection reaches it.
Every protocol can be chained except Tailscale (the built-in TAILSCALE policy), whose engine makes its own connections. A policy that reaches its server over a stream — HTTP, SOCKS5, Shadowsocks, VMess, VLESS, Trojan, AnyTLS, SSH, XHTTP over HTTP/1.1 or HTTP/2 and the rest — opens that stream through the upstream. Hysteria2, TUIC, MASQUE and XHTTP over HTTP/3 (TLS with alpn=h3) speak QUIC, and WireGuard and AmneziaWG send datagrams of their own, so they go through the upstream's UDP relay: the upstream — for a group, its current pick — must carry UDP, as Shadowsocks, SOCKS5, VMess, VLESS, Trojan and Hysteria2 do and an HTTP or HTTPS proxy does not. Over an upstream that carries no UDP, every connection through them is refused and logged, never sent directly. Once chained, a QUIC policy sends datagrams of at most 1200 bytes, and a WireGuard or AmneziaWG tunnel uses an inner MTU of 1280 unless one is written (mtu, or wg-mtu in its section), so the wrapped datagrams still fit a 1500-byte path. WireGuard, AmneziaWG and SSH keep one connection for all their traffic, over their own upstream, so none of them can be a later member of a relay group.
UDP goes through the chain as well. VMess, VLESS, Trojan and AnyTLS carry UDP inside a stream, so their UDP works over any upstream. Shadowsocks (ShadowsocksR and Shadowsocks 2022 included) and SOCKS5 relay UDP as datagrams, as do the QUIC protocols and WireGuard: their UDP works only while the upstream carries UDP — unless a Shadowsocks node uses udp-over-tcp, which carries its UDP inside streams and so works over any upstream. SSH, HTTP and HTTPS policies carry no UDP at all. UDP that a chained policy cannot carry follows udp-policy-not-supported-behaviour (REJECT by default).
dialer-proxy (mihomo) and detour (sing-box) import into this option, and a proxy provider's override: dialer-proxy into the provider's underlying-proxy. A Clash or mihomo relay group is kept as a relay group, with its members in the same order. To send every member of a policy group through one upstream, set underlying-proxy on the group. To send every proxy policy through one upstream, set global-underlying-proxy in [General].
test-url: Optional.
test-url=http://www.gstatic.com/generate_204
The latency test URL for this policy when it is a member of a url-test or fallback group: the group probes this member at this URL instead of the group's url. Without it, the group's URL is used.
interface: Optional
interface=en0
Sends the TCP connections this policy makes to its server out of the named network interface — en0 on a Mac, wlan0 on Android, say — instead of the one the default route picks. When that interface is not available the connection fails rather than leaving another way; allow-other-interface=true lets it follow the default route instead. It works on Chute Mac and Chute Android, and iOS and tvOS ignore it. UDP relay is not bound, and neither are the QUIC-based protocols (TUIC, Hysteria2, MASQUE), WireGuard or Tailscale.
Parameter for proxy with AnyTLS
AnyTLS is a TLS-based proxy protocol with padding obfuscation.
AnyTLS = anytls, 1.2.3.4, 443, password, sni=example.com, skip-cert-verify=false
password: Required.
The password/passphrase used for authentication.
sni (Default: hostname)
sni=exmaple.com
Same as TLS.
skip-cert-verify: Optional
skip-cert-verify=true
Same as TLS.
Padding scheme: Optional
Padding is configured with stop=N plus numeric per-packet keys:
AnyTLS = anytls, 1.2.3.4, 443, password, sni=example.com, stop=2, 0=30-30, 1=100-400+c
| Parameter | Description |
|---|---|
stop |
Number of padded packets |
0, 1, 2, ... |
Padding scheme for each packet (numeric keys) |
Each scheme is a list of segments joined by +, where a segment is either c (check) or a min-max byte range (max 16384), e.g. stop=2, 0=30-30, 1=100-400+c. A , works as the separator too, but only when the value is quoted — 1="100-400,c" — because an unquoted comma ends the field and breaks the line. Prefer +.
Parameter for proxy with TUIC
TUIC is a QUIC-based proxy protocol offering multiplexed TCP and UDP relay. The keyword tuic-v5 (Surge's spelling) is accepted too; the policy is saved as tuic.
TUIC = tuic, 1.2.3.4, 443, uuid=uuid, password=password, sni=example.com, skip-cert-verify=false, alpn=h3
uuid: Required.
The UUID for authentication.
password: Required.
The password for authentication.
sni (Default: hostname)
sni=exmaple.com
Same as TLS.
skip-cert-verify: Optional
skip-cert-verify=true
Same as TLS.
alpn: Optional
alpn=h3
Specify the ALPN string for QUIC connection.
Parameter for proxy with Hysteria2
Hysteria2 is a QUIC-based proxy protocol for high-throughput scenarios.
Hysteria2 = hysteria2, 1.2.3.4, 443, auth=password, sni=example.com, skip-cert-verify=false, up=10, down=100, alpn=h3
auth: Required.
The authentication password/token.
sni (Default: hostname)
sni=exmaple.com
Same as TLS.
skip-cert-verify: Optional
skip-cert-verify=true
Same as TLS.
up: Optional (Mbps)
up=10
Upload bandwidth in Mbps. Accepted and kept, but not used: it feeds Hysteria2's Brutal congestion controller, which this engine does not run. A notice is logged for each policy that sets it. down= is the one that reaches the wire, as the rate the client declares at authentication.
down: Optional (Mbps)
down=100
Download bandwidth in Mbps.
alpn: Optional
alpn=h3
Specify the ALPN string for QUIC connection.
obfs: Optional
obfs=salamander
Enable Salamander obfuscation for the QUIC traffic. Salamander uses BLAKE2b-256 XOR to obfuscate QUIC packets, making them resistant to DPI (Deep Packet Inspection).
obfs-password: Optional
obfs-password=your-obfuscation-key
The password/key used for Salamander obfuscation. Required when obfs=salamander is set.
Parameter for proxy with WireGuard
WireGuard is a modern VPN protocol. Chute supports WireGuard as an outbound proxy server, either inline or by referencing a named [WireGuard] section.
Inline configuration:
WireGuard = wireguard, private-key=base64key, peer-public-key=base64key, self-ip=10.0.0.2, server=1.2.3.4, port=51820
Section reference (recommended):
WireGuard = wireguard, section-name=wg0
See WireGuard Configuration for [WireGuard] section syntax.
private-key: Required (inline only).
Base64-encoded WireGuard private key.
peer-public-key: Required (inline only).
Base64-encoded WireGuard peer public key.
self-ip: Optional (inline).
Local IP address assigned to the WireGuard interface (e.g. 10.0.0.2).
self-ip-v6: Optional (inline).
Local IPv6 address assigned to the WireGuard interface.
server: Required.
Remote WireGuard server address (may come from the referenced [WireGuard] section instead of the policy line).
port: Required.
Remote WireGuard server port (may come from the referenced [WireGuard] section instead of the policy line).
preshared-key: Optional.
Base64-encoded pre-shared key for post-quantum resistance.
allowed-ips: Optional (inline).
allowed-ips="10.0.0.0/8, 192.168.0.0/16"
The destinations the peer carries, as comma-separated CIDRs; quote the value, since it contains commas. A destination outside them is refused or dropped, because the peer cannot route it back. Without it, everything is carried. See WireGuard Configuration for the section form.
keepalive: Optional (seconds).
keepalive=25
Persistent keepalive interval for NAT traversal. Without it, no keepalive is sent.
mtu: Optional.
mtu=1420
MTU for the WireGuard interface.
reserved: Optional.
reserved=0,1,2
Reserved bytes for the WireGuard packet header. Parsed but not effective in the current engine — the value is unsupported by the BoringTun FFI and is ignored with a warning logged.
Parameter for proxy with ShadowTLS
ShadowTLS is a TLS-based proxy protocol that encapsulates traffic within a standard TLS 1.3 session. Chute speaks ShadowTLS v3: the password is carried as an HMAC in the ClientHello session_id, so the authentication happens inside the handshake rather than after it.
Inside the established tunnel Chute sends a no-auth SOCKS5 greeting and a SOCKS5 CONNECT, so the server behind ShadowTLS must be an unauthenticated SOCKS5 proxy. A shadow-tls deployment that forwards to a Shadowsocks port instead of a SOCKS5 one completes the TLS handshake and then fails.
ShadowTLS = shadowtls, 1.2.3.4, 443, password=password, sni=example.com, skip-cert-verify=false, fingerprint=chrome
password: Required.
The password used for the ShadowTLS handshake authentication.
sni (Default: hostname)
sni=example.com
Same as TLS. Writing it is also what turns on verification of the cover certificate — see below.
skip-cert-verify: Optional
skip-cert-verify=true
What turns verification on is sni=. With sni= written and skip-cert-verify absent or false, the chain and the host name of the certificate the fronted site presents are verified against that name, and a failure fails the connection. Without sni= the certificate is not verified and a warning is logged once per policy on first use, because the only name at hand is the relay's, which is not the cover site's. skip-cert-verify=true skips verification in either case.
fingerprint: Optional
fingerprint=chrome
TLS client fingerprint to mimic. Supported values include chrome, firefox, safari, ios, edge, 360, qq, android, random, and the other names listed under fingerprint. Using a common browser fingerprint helps avoid detection. Note that android and random are not distinct here — they are treated as chrome. none and any value Chute does not recognise refuse the connection, because the system TLS stack cannot do this handshake.
Parameter for proxy with MASQUE
MASQUE is an HTTP/3-based proxy protocol that tunnels traffic over QUIC. A MASQUE policy requires type, host, and port. An authentication token is optional.
ProxyMASQUE = masque, 1.2.3.4, 443, token=auth-token, mode=connect-udp, sni=example.com, alpn=h3, skip-cert-verify=false, mux=true
token: Optional
token=auth-token
Optional Bearer authentication token for the MASQUE server. The alias masque-token= is also accepted.
mode: Optional
mode=connect-udp
Accepted for compatibility but does not change tunneling behavior: TCP flows always use a plain CONNECT tunnel and UDP flows always use connect-udp. The alias masque-mode= is also accepted.
mux: Optional
mux=true
Enable multiplexing over a shared QUIC connection.
sni / alpn / skip-cert-verify: Optional
Same as TLS. Since MASQUE runs over QUIC, alpn=h3 is typically used.
Parameter for proxy with SSH
See SSH Proxy for full documentation.