HTTP Rule
There are 4 HTTP-level rule types. USER-AGENT and URL-REGEX read the request a client sends to Chute's HTTP proxy listener, so they only match connections that arrive there; a connection through TUN or SOCKS5 has no HTTP request to read. They are decided once per client connection, from its first request. MitM decryption starts after a connection's policy has been chosen, so the requests it decrypts are not matched against the rules again. PROTOCOL,TCP and PROTOCOL,UDP read the transport and match on every inbound; PROTOCOL's application-protocol values come from the TUN inbound's protocol sniffing, and from a plain request on the HTTP proxy inbound. SCRIPT is evaluated for any connection.
USER-AGENT
USER-AGENT,Instagram*,DIRECT
Rule matches if the user agent of the request matches. Wildcard characters * and ? are supported. The header is read from the first request of each client connection to the HTTP proxy listener; for HTTPS that request is the CONNECT the client opens its tunnel with, so the rule sees the User-Agent the client puts on the CONNECT, if it sends one.
URL-REGEX
URL-REGEX,^http://google\.com.*,DIRECT
Rule matches if the URL of a plain HTTP request that arrives on the HTTP proxy listener matches the regular expression. The URL is written out in full — http://host[:port]/path?query, with the port left out when it is 80 — and the regular expression must match the complete URL, not just a substring: ^http://google\.com alone does not match http://google.com/, because the path is part of the URL. A CONNECT tunnel (HTTPS, or anything else a client tunnels) and a TUN connection have no URL, so URL-REGEX never matches them, and decrypting an HTTPS connection with MitM does not change that. The rule-match dry run, POST /api/rules/match on the HTTP Control API, matches URL-REGEX against its url field exactly as it is sent, so give it the full URL.
PROTOCOL
PROTOCOL,TLS,Proxy
Rule matches if the detected protocol of the connection matches. Use in combination with sniffing-enabled for best results. NETWORK is accepted as an alias of PROTOCOL.
Accepted protocol values: HTTP, HTTPS, TLS, TCP, UDP, QUIC, STUN, MTPROTO, DNS, DOH, DOH3, DOQ, DOT.
Notice: The detected protocol is populated in these places. For TUN inbound sessions, with
sniffing-enabledon, a TCP connection is sniffed asHTTPorTLS(any TLS connection, including HTTPS) only when Chute does not already know its host name: a connection opened to a fake IP, or to an address Chute DNS resolved, keeps that name and is not sniffed, soPROTOCOL,HTTPandPROTOCOL,TLSseldom match TUN traffic whose names were resolved by Chute. A UDP flow is detected asQUICfrom the shape of its packets — through TUN and through the SOCKS5 inbound's UDP relay alike — with no need forsniffing-enabled. Withsniffing-enabledon, Chute also reads the server name out of a QUIC flow's Initial packet, so DOMAIN-type rules can match that flow too (seesniffing-enabledin Misc Options). On the HTTP proxy inbound a plain (non-CONNECT) request isHTTPwith no sniffing at all, because its request header has just been parsed off the connection; a CONNECT leaves the protocol unset, and a TCP connection on the SOCKS5 inbound never gets one — butPROTOCOL,TCPandPROTOCOL,UDPread the session's transport, which every inbound fills in, so those two match there as well. Withencrypted-dns-follow-outbound-mode = true(see DNS Server), Chute's own encrypted DNS upstream connections are matched asDOH,DOT,DOQandDOH3: all four then use the policy the rule names — DoQ and DoH3 through its UDP relay, withudp-policy-not-supported-behaviourdeciding when it carries none — and a REJECT verdict skips any of the four.HTTPSis an accepted spelling of a sniffed TLS handshake, soPROTOCOL,HTTPSandPROTOCOL,TLSmatch the same traffic.STUN,MTPROTOandDNSare accepted for compatibility, but no detector produces them yet.
SCRIPT
SCRIPT,MyRuleScript,DIRECT
Rule evaluates a JavaScript script for custom matching logic. The script name must match a script defined in the [Script] section with type=rule.
[Rule]
SCRIPT,CheckInternal,PROXY
[Script]
CheckInternal = type=rule, script-path=internal-check.js
The rule script receives $request and must call $done({matched: true}) or $done({matched: false}). Note that $request.dnsResult is only available when the session has already been resolved (for example, requests made directly to an IP address, or the second matching pass after DNS resolution).