Route
Generated by website/scripts/build-config.mjs; do not edit. It reads sail’s configuration types (its Rust source), sing-box’s field registry (sail/src/config/singbox/fields.json, sing-box v1.14.2) and the tiers the registry test measured (fields.tiers.json). Change the source comments or those files, then run npm run docs:config in website/.
- Status: each sing-box field as the registry test measured it: Supported (read and acted on; a value sail cannot take is still an error), Warned (dropped with a warning) or Error (the configuration is refused), with the reason; sail extension marks fields and types sing-box does not have.
- Type: sing-box’s JSON type for its fields; from sail’s Rust definitions for extensions.
- Default: from sail’s serde declarations; unset means the field may be left out, and the description says what applies then. Only fields sail reads have one.
- Description: sail’s source comments, in their source language; for an extension without one, the registry test’s note.
- Build: the
cfgconditions in the Rust source (Cargo features and platforms).
Validate a configuration with sail -c config.json -T. Editors check and complete it by the JSON schema: put "$schema": "https://peakpassvpn.github.io/sail/schema.json" at its top (made by the same generator; a field sail refuses is marked not allowed, one it warns of deprecated). The Clash and Surge support tables are under Compatibility.
Rust: Route
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
rules |
array → [], [action=bypass], [action=direct], [action=reject], [action=resolve], [action=route], [action=route-options], [action=sniff], [logical] | [] |
Supported | — |
rule_set |
array → [], [inline], [local], [remote] | [] |
Supported | The rule-sets rules name, by tag. |
final |
string | unset | Supported | The outbound for connections no rule matches; defaults to the first outbound. |
find_process |
bool | false |
Supported | Looks up who opened every connection (the program, the package, the user), for the connections list, though no rule asks; without it, only when a rule has conditions on it, as in sing-box. |
find_neighbor |
bool | false |
Supported | Looks up the LAN device of each connection’s source even without a rule on it, for the logs (sing-box’s, since 1.14). |
dhcp_lease_files |
listable-string | [] |
Supported | The DHCP lease files the LAN devices’ names are read from; the usual ones of dnsmasq, odhcpd, ISC dhcpd and Kea when none. |
auto_detect_interface |
bool | false |
Supported | Sends outbounds that name no interface of their own through the system’s default interface, found at start. Needed when a TUN inbound routes everything, or outbound traffic would loop back into it. |
override_android_vpn |
bool | — | Warned: Android’s VPN is the host’s to handle | — |
default_interface |
string | unset | Supported | The interface outbounds that name none of their own send through. |
default_mark |
number|string | unset | Supported | The routing mark (SO_MARK, Linux) of outbounds that set none. |
default_domain_resolver |
string|object → object | unset | Supported | The DNS server that resolves the names outbounds dial, for those that name no domain_resolver of their own. Unset, the DNS rules decide. |
default_network_strategy |
string, one of default, fallback, hybrid |
unset | Supported | The network_strategy, network_type, fallback_network_type and fallback_delay of what sets none of the first three, or no delay; the strategy needs auto_detect_interface. |
default_network_type |
listable-string, one of cellular, ethernet, other, wifi |
[] |
Supported | — |
default_fallback_network_type |
listable-string, one of cellular, ethernet, other, wifi |
[] |
Supported | — |
default_fallback_delay |
duration | unset | Supported | — |
default_http_client |
string | unset | Supported | The HTTP client of what names none, by tag; the first of http_clients when unset, or with none, the default outbound. |
geoip |
object | — | Warned: sing-box removed it in 1.12, and ignores it (deprecated in sing-box) | — |
geosite |
object | — | Warned: sing-box removed it in 1.12, and ignores it (deprecated in sing-box) | — |
block_quic |
string or array of string | [] |
sail extension | A sail extension, Surge’s block-quic: the outbounds QUIC is refused to, by tag. A UDP connection sniffing recognized as QUIC that the rules send to one is rejected as a reject rule would, so that the app goes on over TCP. Sniffing is the rules’ to ask for. |
route.rules[]
Section titled “route.rules[]”Rust: Rule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
type |
string, one of default, logical |
default |
Supported | default, or logical. |
inbound |
listable-string | [] |
Supported | Tags of the inbounds a connection came in through. |
ip_version |
number, one of 4, 6 |
unset | Supported | 4 or 6: the family of the destination address. |
network |
listable-string, one of tcp, udp, icmp |
[] |
Supported | tcp, udp. |
auth_user |
listable-string | [] |
Supported | Names of the users an inbound authenticated. |
protocol |
listable-string, one of tls, http, quic, dns, stun, bittorrent, dtls, ssh, rdp, ntp |
[] |
Supported | The protocols a sniff rule found, by sing-box’s names: tls, http, quic, dns, stun, bittorrent, dtls. |
client |
listable-string | — | Error: A condition sail does not match: the rule would match otherwise | — |
domain |
listable-string | [] |
Supported | — |
domain_suffix |
listable-string | [] |
Supported | — |
domain_keyword |
listable-string | [] |
Supported | — |
domain_regex |
listable-string | [] |
Supported | — |
source_ip_cidr |
listable-string | [] |
Supported | — |
source_ip_is_private |
bool | false |
Supported | The source address is not a public one. |
ip_cidr |
listable-string | [] |
Supported | — |
ip_is_private |
bool | false |
Supported | The destination address, or one the domain resolved to, is not a public one. |
source_port |
listable-number | [] |
Supported | — |
source_port_range |
listable-string | [] |
Supported | Inclusive port ranges, as port_range writes them. |
port |
listable-number | [] |
Supported | — |
port_range |
listable-string | [] |
Supported | Inclusive port ranges, as sing-box writes them: 1000:2000, :1024, 8000:. |
process_name |
listable-string | [] |
Supported | The name of the program a connection comes from, its path’s last part. |
process_path |
listable-string | [] |
Supported | — |
process_path_regex |
listable-string | [] |
Supported | — |
package_name |
listable-string | [] |
Supported | Android packages: the app the host says opened the connection (find_connection_owner); an error without a host that tells. |
package_name_regex |
listable-string | [] |
Supported | — |
user |
listable-string | [] |
Supported | The user a connection’s app runs as, by name and by id, as the host tells it; an error without a host that tells. |
user_id |
listable-number | [] |
Supported | — |
clash_mode |
string | unset | Supported | The mode of Clash’s API: matches while it is that, whatever the case; never without an API. |
network_type |
listable-string, one of cellular, ethernet, other, wifi |
[] |
Supported | The kind of network: wifi, cellular, ethernet, other. |
network_is_expensive |
bool | false |
Supported | The network is metered, as the system says. |
network_is_constrained |
bool | false |
Supported | The network is in a low data mode, as the system says. |
wifi_ssid |
listable-string | [] |
Supported | The name of the Wi-Fi network the host is on, whole and with case. This and the other conditions on the network match the network as the host tells it or sail detects it at the time; one on something not known of it does not match. |
wifi_bssid |
listable-string | [] |
Supported | The address of the Wi-Fi access point, aa:bb:cc:dd:ee:ff, in any case, with : or -, or as 12 hex digits. |
interface_address |
map | — | Error: A condition sail does not match: the rule would match otherwise | — |
network_interface_address |
map | — | Error: A condition sail does not match: the rule would match otherwise | — |
default_interface_address |
listable-string | — | Error: A condition sail does not match: the rule would match otherwise | — |
source_mac_address |
listable-string | [] |
Supported | MAC addresses of the LAN device the connection comes from, as the neighbor table and DHCP leases know it (sing-box’s, since 1.14). |
source_hostname |
listable-string | [] |
Supported | Host names of the LAN device the connection comes from, as its DHCP lease has it. |
preferred_by |
listable-string | — | Error: A condition sail does not match: the rule would match otherwise | Tags of DNS servers, one of which prefers the name: of a DNS query, and so never of a connection. |
rule_set |
listable-string | [] |
Supported | Tags of rule-sets, any of whose rules matching matches. |
rule_set_ip_cidr_match_source |
bool | false |
Supported | The rule-sets’ ip_cidr match the source address, not the destination. |
invert |
bool | false |
Supported | — |
action |
string, one of route, route-options, direct, bypass, reject, hijack-dns, sniff, resolve |
unset | Supported | route when unset. |
geoip |
string or array of string | [] |
sail extension | Country codes, looked up in geo.mmdb in the asset directory; a sail extension, as geosite is. |
geosite |
string or array of string | [] |
sail extension | Site groups, looked up in site.dat in the asset directory. A sail extension: sing-box has dropped its GeoIP and GeoSite databases. |
external |
string or array of string | [] |
sail extension | A sail extension: mmdb:<file>:<code> or site:<file>:<code>, for data files other than the default ones. |
http_user_agent |
string or array of string | [] |
sail extension | A sail extension, for Surge’s USER-AGENT: patterns the User-Agent of a plain HTTP request a sniff rule read matches, whole and with case, * any run of characters and ? any one. |
url_regex |
string or array of string | [] |
sail extension | A sail extension, for Surge’s URL-REGEX: regular expressions found in the URL of a plain HTTP request a sniff rule read, http://host/path?query. |
ip_asn |
number or array of number | [] |
sail extension | A sail extension, for Surge’s IP-ASN: the autonomous systems the destination address, or one the domain resolved to, belongs to, as asn.mmdb in the asset directory (GeoLite2-ASN’s format, or ipinfo’s) has them. |
process_name_regex |
string or array of string | [] |
sail extension | A sail extension, as Mihomo’s PROCESS-NAME-REGEX: regular expressions the program’s name, its path’s last part, matches. |
wifi_ssid_regex |
string or array of string | [] |
sail extension | A sail extension, for Surge’s SSID:: regular expressions found in the Wi-Fi network’s name, with case. |
wifi_bssid_regex |
string or array of string | [] |
sail extension | A sail extension, for Surge’s BSSID:: regular expressions found in the access point’s address as aa:bb:cc:dd:ee:ff, whatever the case. |
network_gateway |
string or array of string | [] |
sail extension | A sail extension, for Surge’s ROUTER:: the address of the default gateway. |
network_mcc_mnc |
string or array of string | [] |
sail extension | A sail extension, for Surge’s MCCMNC: and CELLULAR-CARRIER: the cellular carrier, its MCC and MNC as 5 or 6 digits; only off Wi-Fi. |
no_resolve |
bool | false |
sail extension | A sail extension, Surge’s and Clash’s no-resolve: the rule’s conditions on the destination’s addresses (ip_cidr, ip_is_private, ip_asn, geoip, those of its rule-sets and of the rules within) match only addresses already known, and never have an on_demand resolve resolve the domain for them. Only for a rule with such conditions. |
route.rules[action=bypass]
Section titled “route.rules[action=bypass]”Rust: Rule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
outbound |
string | unset | Supported | route: where a matching connection goes. |
override_address |
string | unset | Supported | route, route-options: connects to this address, an IP or a domain, instead of the one asked for, on the same port. |
override_port |
number | unset | Supported | route, route-options: connects to this port instead. |
network_strategy |
string, one of default, fallback, hybrid |
unset | Supported | route, route-options: how a direct outbound the connection goes out of chooses among the host’s interfaces, instead of as its own says; not where it binds its sockets itself. A later rule’s goes before. As in sing-box, only where the destination is an address (for UDP, a connected one) or a resolve rule resolved it; other outbounds, a group whose pick is a direct one among them, take no notice of it. direct: checked only. |
fallback_delay |
number | unset | Supported | route, route-options: how long a direct outbound the connection goes out of tries one family’s addresses, and its first interfaces, before the others race them, instead of its own fallback_delay, where network_strategy would apply. A later rule’s goes before. A duration string, as sing-box’s documentation writes it, or a number of nanoseconds, as sing-box 1.14.1 reads it here. direct: checked only. |
udp_disable_domain_unmapping |
bool | false |
Supported | route, route-options: answers to UDP sent to a domain come back from the address it resolved to, not from the domain. |
udp_connect |
bool | false |
Supported | route, route-options: a direct outbound sends UDP from a connected socket. |
udp_timeout |
duration | unset | Supported | route, route-options: how long a UDP session lasts idle, instead of its inbound’s udp_timeout. |
tls_fragment |
bool | false |
Supported | route, route-options: sends the TLS ClientHello in pieces, cut in the server name, each in a TCP segment of its own. |
tls_fragment_fallback_delay |
duration | unset | Supported | route, route-options: how long to wait between the pieces; 500ms when unset. |
tls_record_fragment |
bool | false |
Supported | route, route-options: sends the TLS ClientHello as several TLS records, cut in the server name. |
tls_spoof |
string | — | Error: Fragmenting or spoofing the TLS handshake against censorship | — |
tls_spoof_method |
string, one of wrong-sequence, wrong-checksum, wrong-ack, wrong-md5, wrong-timestamp |
— | Error: Fragmenting or spoofing the TLS handshake against censorship | — |
route.rules[action=direct]
Section titled “route.rules[action=direct]”Rust: Rule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
bind_interface |
string | — | Warned: Accepted, no effect (as sing-box) | direct: the interface to send through, by name. |
inet4_bind_address |
string | — | Warned: Accepted, no effect (as sing-box) | direct: the local address for IPv4 destinations. |
inet6_bind_address |
string | — | Warned: Accepted, no effect (as sing-box) | direct: the local address for IPv6 destinations. |
bind_address_no_port |
bool | — | Warned: Accepted, no effect (as sing-box) | direct: IP_BIND_ADDRESS_NO_PORT on TCP sockets bound to an address: Linux only. |
protect_path |
string | — | Warned: Accepted, no effect (as sing-box) | direct: the Unix socket each socket’s descriptor is handed to, to be protected: Unix only. |
routing_mark |
number|string | — | Warned: Accepted, no effect (as sing-box) | direct: SO_MARK, Linux only. |
reuse_addr |
bool | — | Warned: Accepted, no effect (as sing-box) | direct: SO_REUSEADDR, and SO_REUSEPORT on Unix, on UDP sockets. |
netns |
string | — | Error: Linux network namespaces: sockets would leave another way | — |
connect_timeout |
duration | — | Warned: Accepted, no effect (as sing-box) | direct: how long a TCP connect to one address may take; 5s when unset. |
tcp_fast_open |
bool | — | Warned: Accepted, no effect (as sing-box) | direct: TCP Fast Open. |
tcp_multi_path |
bool | — | Warned: Socket tuning: connections go the same way without it | — |
disable_tcp_keep_alive |
bool | — | Warned: Accepted, no effect (as sing-box) | direct: no TCP keepalive at all. |
tcp_keep_alive |
duration | — | Warned: Accepted, no effect (as sing-box) | direct: how long a TCP connection is idle before keepalive probes it; 5m when unset. |
tcp_keep_alive_interval |
duration | — | Warned: Accepted, no effect (as sing-box) | direct: between keepalive probes; 75s when unset. |
udp_fragment |
bool | — | Warned: Accepted, no effect (as sing-box) | direct: whether UDP datagrams may be fragmented on the way; not when unset, as sing-box’s direct action has it. |
domain_resolver |
string|object → object | — | Warned: Accepted, no effect (as sing-box) | direct: the DNS server that resolves the names it dials. |
network_strategy |
string, one of default, fallback, hybrid |
— | Warned: Accepted, no effect (as sing-box) | route, route-options: how a direct outbound the connection goes out of chooses among the host’s interfaces, instead of as its own says; not where it binds its sockets itself. A later rule’s goes before. As in sing-box, only where the destination is an address (for UDP, a connected one) or a resolve rule resolved it; other outbounds, a group whose pick is a direct one among them, take no notice of it. direct: checked only. |
network_type |
listable-string, one of cellular, ethernet, other, wifi |
— | Warned: Accepted, no effect (as sing-box) | The kind of network: wifi, cellular, ethernet, other. |
fallback_network_type |
listable-string, one of cellular, ethernet, other, wifi |
— | Warned: Accepted, no effect (as sing-box) | direct: the types of interface its fallback strategy falls back to. Its network_type is not one: a rule’s network_type is its condition, as in sing-box. |
fallback_delay |
duration | — | Warned: Accepted, no effect (as sing-box) | route, route-options: how long a direct outbound the connection goes out of tries one family’s addresses, and its first interfaces, before the others race them, instead of its own fallback_delay, where network_strategy would apply. A later rule’s goes before. A duration string, as sing-box’s documentation writes it, or a number of nanoseconds, as sing-box 1.14.1 reads it here. direct: checked only. |
domain_strategy |
string | — | Warned: Accepted, no effect (as sing-box) (deprecated in sing-box) | direct: sing-box’s deprecated field for the families names resolve to. |
route.rules[action=direct].domain_resolver
Section titled “route.rules[action=direct].domain_resolver”Rust: DomainResolver
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
server |
string | required | Warned: Accepted, no effect (as sing-box) | — |
timeout |
duration | — | Warned: Accepted, no effect (as sing-box) | — |
strategy |
string, one of as_is, prefer_ipv4, prefer_ipv6, ipv4_only, ipv6_only |
— | Warned: Accepted, no effect (as sing-box) | — |
disable_cache |
bool | — | Warned: Accepted, no effect (as sing-box) | — |
disable_optimistic_cache |
bool | — | Warned: Accepted, no effect (as sing-box) | — |
rewrite_ttl |
number | — | Warned: Accepted, no effect (as sing-box) | — |
client_subnet |
string | — | Warned: Accepted, no effect (as sing-box) | — |
route.rules[action=reject]
Section titled “route.rules[action=reject]”Rust: Rule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
method |
string, one of default, drop, reply |
unset | Supported | reject: how. |
no_drop |
bool | false |
Supported | reject: never drops, however many connections the rule rejects. |
route.rules[action=resolve]
Section titled “route.rules[action=resolve]”Rust: Rule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
server |
string | unset | Supported | resolve: the DNS server to ask, rather than the one the DNS rules pick. |
timeout |
duration | unset | Supported | sniff: how long to wait for the first bytes; 300ms when unset. resolve: how long to wait for the answer; dns.timeout when unset. |
strategy |
string, one of as_is, prefer_ipv4, prefer_ipv6, ipv4_only, ipv6_only |
unset | Supported | resolve: the address families, instead of dns.strategy. |
disable_cache |
bool | false |
Supported | resolve: the answers neither come from the DNS cache nor go into it. |
disable_optimistic_cache |
bool | false |
Supported | resolve: an expired answer is not given while it is asked for again, though dns.optimistic is enabled. |
rewrite_ttl |
number | unset | Supported | resolve: the TTL the answers’ records carry, in seconds. |
client_subnet |
string | unset | Supported | resolve: the EDNS Client Subnet the queries carry, instead of dns.client_subnet. |
ignore_failure |
bool | false |
sail extension | resolve, a sail extension: a domain that does not resolve, or not in time, has no addresses, and matching goes on, as Mihomo’s IP rules have it; rather than the connection failing, as in sing-box. |
on_demand |
bool | false |
sail extension | resolve, sniff, a sail extension: the rule does not act where it stands but arms its action, with its options, and matching goes on. The action is taken the first time a later rule needs what it learns, just before that rule is matched: a resolve for a rule with conditions on the destination’s addresses, while the destination is a domain; a sniff for one on the protocol, the plain HTTP request, or a domain while the destination is an address. A connection no later rule needs it for is never resolved or sniffed, as Surge and Mihomo have it. A later rule arming the same action replaces its options. |
route.rules[action=route]
Section titled “route.rules[action=route]”Rust: Rule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
outbound |
string | unset | Supported | route: where a matching connection goes. |
override_address |
string | unset | Supported | route, route-options: connects to this address, an IP or a domain, instead of the one asked for, on the same port. |
override_port |
number | unset | Supported | route, route-options: connects to this port instead. |
network_strategy |
string, one of default, fallback, hybrid |
unset | Supported | route, route-options: how a direct outbound the connection goes out of chooses among the host’s interfaces, instead of as its own says; not where it binds its sockets itself. A later rule’s goes before. As in sing-box, only where the destination is an address (for UDP, a connected one) or a resolve rule resolved it; other outbounds, a group whose pick is a direct one among them, take no notice of it. direct: checked only. |
fallback_delay |
number | unset | Supported | route, route-options: how long a direct outbound the connection goes out of tries one family’s addresses, and its first interfaces, before the others race them, instead of its own fallback_delay, where network_strategy would apply. A later rule’s goes before. A duration string, as sing-box’s documentation writes it, or a number of nanoseconds, as sing-box 1.14.1 reads it here. direct: checked only. |
udp_disable_domain_unmapping |
bool | false |
Supported | route, route-options: answers to UDP sent to a domain come back from the address it resolved to, not from the domain. |
udp_connect |
bool | false |
Supported | route, route-options: a direct outbound sends UDP from a connected socket. |
udp_timeout |
duration | unset | Supported | route, route-options: how long a UDP session lasts idle, instead of its inbound’s udp_timeout. |
tls_fragment |
bool | false |
Supported | route, route-options: sends the TLS ClientHello in pieces, cut in the server name, each in a TCP segment of its own. |
tls_fragment_fallback_delay |
duration | unset | Supported | route, route-options: how long to wait between the pieces; 500ms when unset. |
tls_record_fragment |
bool | false |
Supported | route, route-options: sends the TLS ClientHello as several TLS records, cut in the server name. |
tls_spoof |
string | — | Error: Fragmenting or spoofing the TLS handshake against censorship | — |
tls_spoof_method |
string, one of wrong-sequence, wrong-checksum, wrong-ack, wrong-md5, wrong-timestamp |
— | Error: Fragmenting or spoofing the TLS handshake against censorship | — |
override_destination |
bool or string, one of proxy, proxy_and_direct, at_sniff |
unset | sail extension | route, route-options, sniff, a sail extension: a connection to an address is dialled by the name known for it, the sniffed domain or else the one dns.reverse_mapping keeps, where its last hop dials a proxy’s server (true or "proxy"), or a direct dial too ("proxy_and_direct"). The rules still match the address. On a sniff rule, "at_sniff" instead makes the sniffed domain the destination there, for the rules after, as Mihomo’s sniffer does. |
route.rules[action=route-options]
Section titled “route.rules[action=route-options]”Rust: Rule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
override_address |
string | unset | Supported | route, route-options: connects to this address, an IP or a domain, instead of the one asked for, on the same port. |
override_port |
number | unset | Supported | route, route-options: connects to this port instead. |
network_strategy |
string, one of default, fallback, hybrid |
unset | Supported | route, route-options: how a direct outbound the connection goes out of chooses among the host’s interfaces, instead of as its own says; not where it binds its sockets itself. A later rule’s goes before. As in sing-box, only where the destination is an address (for UDP, a connected one) or a resolve rule resolved it; other outbounds, a group whose pick is a direct one among them, take no notice of it. direct: checked only. |
fallback_delay |
number | unset | Supported | route, route-options: how long a direct outbound the connection goes out of tries one family’s addresses, and its first interfaces, before the others race them, instead of its own fallback_delay, where network_strategy would apply. A later rule’s goes before. A duration string, as sing-box’s documentation writes it, or a number of nanoseconds, as sing-box 1.14.1 reads it here. direct: checked only. |
udp_disable_domain_unmapping |
bool | false |
Supported | route, route-options: answers to UDP sent to a domain come back from the address it resolved to, not from the domain. |
udp_connect |
bool | false |
Supported | route, route-options: a direct outbound sends UDP from a connected socket. |
udp_timeout |
duration | unset | Supported | route, route-options: how long a UDP session lasts idle, instead of its inbound’s udp_timeout. |
tls_fragment |
bool | false |
Supported | route, route-options: sends the TLS ClientHello in pieces, cut in the server name, each in a TCP segment of its own. |
tls_fragment_fallback_delay |
duration | unset | Supported | route, route-options: how long to wait between the pieces; 500ms when unset. |
tls_record_fragment |
bool | false |
Supported | route, route-options: sends the TLS ClientHello as several TLS records, cut in the server name. |
tls_spoof |
string | — | Error: Fragmenting or spoofing the TLS handshake against censorship | — |
tls_spoof_method |
string, one of wrong-sequence, wrong-checksum, wrong-ack, wrong-md5, wrong-timestamp |
— | Error: Fragmenting or spoofing the TLS handshake against censorship | — |
override_destination |
bool or string, one of proxy, proxy_and_direct, at_sniff |
unset | sail extension | route, route-options, sniff, a sail extension: a connection to an address is dialled by the name known for it, the sniffed domain or else the one dns.reverse_mapping keeps, where its last hop dials a proxy’s server (true or "proxy"), or a direct dial too ("proxy_and_direct"). The rules still match the address. On a sniff rule, "at_sniff" instead makes the sniffed domain the destination there, for the rules after, as Mihomo’s sniffer does. |
route.rules[action=sniff]
Section titled “route.rules[action=sniff]”Rust: Rule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
sniffer |
listable-string, one of tls, http, quic, dns, stun, bittorrent, dtls, ssh, rdp, ntp |
[] |
Supported | sniff: the protocols to look for; all of them when empty. |
timeout |
duration | unset | Supported | sniff: how long to wait for the first bytes; 300ms when unset. resolve: how long to wait for the answer; dns.timeout when unset. |
override_destination |
bool or string, one of proxy, proxy_and_direct, at_sniff |
unset | sail extension | route, route-options, sniff, a sail extension: a connection to an address is dialled by the name known for it, the sniffed domain or else the one dns.reverse_mapping keeps, where its last hop dials a proxy’s server (true or "proxy"), or a direct dial too ("proxy_and_direct"). The rules still match the address. On a sniff rule, "at_sniff" instead makes the sniffed domain the destination there, for the rules after, as Mihomo’s sniffer does. |
skip_rule_set |
string or array of string | [] |
sail extension | sniff, a sail extension: a domain found that one of these rule-sets matches is not taken, neither matched nor connected to, as Mihomo’s sniffer skip-domain has it. |
route.rules[logical]
Section titled “route.rules[logical]”Rust: Rule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
mode |
string, one of and, or |
unset | Supported | logical: and or or. |
rules |
array | [] |
Supported | logical: the rules combined. They take no action of their own. |
invert |
bool | false |
Supported | — |
route.rule_set[]
Section titled “route.rule_set[]”Rust: RuleSet
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
type |
string, one of inline, local, remote |
inline |
Supported | — |
route.rule_set[inline]
Section titled “route.rule_set[inline]”Rust: RuleSet
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
tag |
listable-string | required | Supported | One tag, or several, each put in place of {tag} in the path or URL. |
rules |
array → [], [logical] | [] |
Supported | inline: the rules. |
route.rule_set[inline].rules[]
Section titled “route.rule_set[inline].rules[]”Rust: HeadlessRule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
type |
string, one of default, logical |
unset | Supported | default, or logical. |
query_type |
listable-number|string | [] |
Supported | — |
network |
listable-string, one of tcp, udp, icmp |
[] |
Supported | — |
domain |
listable-string | [] |
Supported | — |
domain_suffix |
listable-string | [] |
Supported | — |
domain_keyword |
listable-string | [] |
Supported | — |
domain_regex |
listable-string | [] |
Supported | — |
source_ip_cidr |
listable-string | [] |
Supported | — |
ip_cidr |
listable-string | [] |
Supported | — |
source_port |
listable-number | [] |
Supported | — |
source_port_range |
listable-string | [] |
Supported | — |
port |
listable-number | [] |
Supported | — |
port_range |
listable-string | [] |
Supported | — |
process_name |
listable-string | [] |
Supported | — |
process_path |
listable-string | [] |
Supported | — |
process_path_regex |
listable-string | [] |
Supported | — |
package_name |
listable-string | [] |
Supported | As a routing rule’s: the app the host says opened the connection, an error without a host that tells. |
package_name_regex |
listable-string | [] |
Supported | — |
network_type |
listable-string, one of cellular, ethernet, other, wifi |
[] |
Supported | Conditions on the network the host is on, as a routing rule’s: wifi|cellular|ethernet|other. |
network_is_expensive |
bool | false |
Supported | — |
network_is_constrained |
bool | false |
Supported | — |
wifi_ssid |
listable-string | [] |
Supported | — |
wifi_bssid |
listable-string | [] |
Supported | — |
network_interface_address |
map | — | Error: sail does not match it yet | Conditions sail does not match yet; a rule that sets one is refused when the rule-set is read. |
default_interface_address |
listable-string | — | Error: sail does not match it yet | — |
invert |
bool | false |
Supported | — |
ip_asn |
number or array of number | [] |
sail extension | A sail extension, as a routing rule’s: autonomous systems, of asn.mmdb in the asset directory. |
http_user_agent |
string or array of string | [] |
sail extension | Sail extensions, as a routing rule’s: of a plain HTTP request. |
process_name_regex |
string or array of string | [] |
sail extension | A sail extension, as Mihomo’s PROCESS-NAME-REGEX: regular expressions the program’s name, its path’s last part, matches. |
wifi_ssid_regex |
string or array of string | [] |
sail extension | Sail extensions, as a routing rule’s: the Wi-Fi name and access point by pattern, the gateway, the cellular carrier. |
no_resolve |
bool | false |
sail extension | A sail extension, as a routing rule’s, and Surge’s and Clash’s no-resolve on a line of a set: the rule’s ip_cidr and ip_asn, and those of the rules within, match only addresses already known, and never have an on_demand resolve resolve the domain for them. Only for a rule with such conditions. |
route.rule_set[inline].rules[logical]
Section titled “route.rule_set[inline].rules[logical]”Rust: HeadlessRule
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
mode |
string, one of and, or |
unset | Supported | logical: and or or. |
rules |
array | [] |
Supported | logical: the rules combined. |
invert |
bool | false |
Supported | — |
route.rule_set[local]
Section titled “route.rule_set[local]”Rust: RuleSet
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
tag |
listable-string | required | Supported | One tag, or several, each put in place of {tag} in the path or URL. |
format |
string, one of source, binary |
unset | Supported | source (JSON) or binary (.srs); from the extension of the path or URL when unset. A sail extension, for Clash’s rule-providers: mrs (Mihomo’s binary), clash-yaml or clash-text, which take a behavior. |
path |
string | unset | Supported | local: the file. |
route.rule_set[remote]
Section titled “route.rule_set[remote]”Rust: RuleSet
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
tag |
listable-string | required | Supported | One tag, or several, each put in place of {tag} in the path or URL. |
format |
string, one of source, binary |
unset | Supported | source (JSON) or binary (.srs); from the extension of the path or URL when unset. A sail extension, for Clash’s rule-providers: mrs (Mihomo’s binary), clash-yaml or clash-text, which take a behavior. |
url |
string | unset | Supported | remote: where it is downloaded from. |
initial_path |
string | unset | Supported | remote: a file to start from before the first download. |
http_client |
string|object → object | unset | Supported | remote: the HTTP client it is downloaded with, by tag or in place. With neither this nor download_detour, the default one of http_clients (route.default_http_client, or else the first), or else the default outbound. |
update_interval |
duration | unset | Supported | remote: how often it is downloaded again; 1d when unset. |
download_detour |
string | unset | Supported (deprecated in sing-box) | remote: the outbound it is downloaded through; deprecated in sing-box for http_client. |
behavior |
string, one of domain, ipcidr, classical |
unset | sail extension | A sail extension, for the Clash formats: what each line is, domain, ipcidr or classical (a Clash rule without its target). |
size_limit |
number | unset | sail extension | remote, a sail extension (Mihomo’s size-limit): the most a download of it may be, in bytes; past it the download fails and the copy in use is kept. Unset, the download client’s own cap. |
route.rule_set[remote].http_client
Section titled “route.rule_set[remote].http_client”| Field | Type | Default | Status | Description |
|---|---|---|---|---|
engine |
string, one of go, apple |
— | Supported | — |
version |
number, one of 0, 1, 2, 3 |
— | Supported | — |
disable_version_fallback |
bool | — | Supported | — |
headers |
map | — | Supported | — |
tls |
object → object | — | Error: TLS options of an HTTP client’s own: its downloads would be checked otherwise | — |
detour |
string | — | Supported | — |
bind_interface |
string | — | Supported | — |
inet4_bind_address |
string | — | Supported | — |
inet6_bind_address |
string | — | Supported | — |
bind_address_no_port |
bool | — | Supported | — |
protect_path |
string | — | Supported | — |
routing_mark |
number|string | — | Supported | — |
reuse_addr |
bool | — | Supported | — |
netns |
string | — | Error: Linux network namespaces: sockets would leave another way | — |
connect_timeout |
duration | — | Supported | — |
tcp_fast_open |
bool | — | Supported | — |
tcp_multi_path |
bool | — | Warned: Socket tuning: connections go the same way without it | — |
disable_tcp_keep_alive |
bool | — | Supported | — |
tcp_keep_alive |
duration | — | Supported | — |
tcp_keep_alive_interval |
duration | — | Supported | — |
udp_fragment |
bool | — | Supported | — |
domain_resolver |
string|object → object | — | Supported | — |
network_strategy |
string, one of default, fallback, hybrid |
— | Supported | — |
network_type |
listable-string, one of cellular, ethernet, other, wifi |
— | Supported | — |
fallback_network_type |
listable-string, one of cellular, ethernet, other, wifi |
— | Supported | — |
fallback_delay |
duration | — | Supported | — |
idle_timeout |
duration | — | Warned: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download | — |
keep_alive_period |
duration | — | Warned: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download | — |
stream_receive_window |
number|string | — | Warned: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download | — |
connection_receive_window |
number|string | — | Warned: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download | — |
max_concurrent_streams |
number | — | Warned: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download | — |
initial_packet_size |
number | — | Warned: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download | — |
disable_path_mtu_discovery |
bool | — | Warned: HTTP/2 and HTTP/3 tuning: a download over HTTP/1.1 is the same download | — |
domain_strategy |
string | — | Supported (deprecated in sing-box) | — |