Endpoints
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.
endpoints[]
Section titled “endpoints[]”Rust: Endpoint
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
type |
string, one of openconnect, openvpn-client, openvpn-server, tailscale, wireguard |
required | Supported | — |
endpoints[wireguard]
Section titled “endpoints[wireguard]”Rust: WireGuardOptions · Build: feature = "wireguard"
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
tag |
string | "" |
Supported | Defaults to the type. |
system |
bool | false |
Supported | A system interface instead of the userspace stack: not supported. |
name |
string | — | Error: Names a system interface, which sail does not create | The system interface’s name, for system only. |
mtu |
number | unset | Supported | — |
address |
listable-string | required | Supported | The endpoint’s own addresses in the tunnel, as prefixes. |
private_key |
string | required | Supported | — |
listen_port |
number | unset | Supported | — |
peers |
array → [] | required | Supported | — |
udp_timeout |
duration | unset | Supported | How long a UDP session coming in through this endpoint lives without traffic; 5m when unset, as for an inbound. |
udp_mapping |
string, one of endpoint_independent, address_dependent, address_and_port_dependent |
— | Warned: How UDP mappings are made and how many are kept: the same traffic | — |
udp_filtering |
string, one of endpoint_independent, address_dependent, address_and_port_dependent |
— | Error: Which remote addresses may answer through a UDP mapping: others would | — |
udp_nat_max |
number | — | Warned: How UDP mappings are made and how many are kept: the same traffic | — |
workers |
number | unset | Supported | sing-box’s worker count; sail has no use for it. |
detour |
string | unset | Supported | The outbound to dial through, in place of a socket of its own. |
bind_interface |
string | unset | Supported | The interface to send through, by name. Loopback destinations still go over loopback, where sing-box applies the bind to them as well. |
inet4_bind_address |
string | unset | Supported | The local address for IPv4 destinations, loopback ones aside: as bind_interface. |
inet6_bind_address |
string | unset | Supported | The local address for IPv6 destinations, loopback ones aside: as bind_interface. |
bind_address_no_port |
bool | false |
Supported | IP_BIND_ADDRESS_NO_PORT on TCP sockets bound to an address, so that the port is picked at connect: Linux only. |
protect_path |
string | unset | Supported | A Unix socket each socket’s descriptor is handed to, with SCM_RIGHTS, before it binds or connects, for the process there to protect it (from its VPN, say); it answers one byte. Besides what the host protects. Unix only. |
routing_mark |
number|string | unset | Supported | SO_MARK, Linux only. |
reuse_addr |
bool | false |
Supported | SO_REUSEADDR, and SO_REUSEPORT on Unix, on UDP sockets. |
netns |
string | — | Error: Linux network namespaces: sockets would leave another way | Not implemented yet. |
connect_timeout |
duration | unset | Supported | How long a TCP connect to one address may take; 5s when unset. |
tcp_fast_open |
bool | false |
Supported | TCP Fast Open: the first data written goes with the SYN. Its addresses are then tried one by one, not raced. |
tcp_multi_path |
bool | — | Warned: Socket tuning: connections go the same way without it | Not implemented yet. |
disable_tcp_keep_alive |
bool | false |
Supported | No TCP keepalive at all. |
tcp_keep_alive |
duration | unset | Supported | How long a TCP connection is idle before keepalive probes it; 5m when unset. |
tcp_keep_alive_interval |
duration | unset | Supported | Between keepalive probes; 75s when unset. |
udp_fragment |
bool | unset | Supported | Whether UDP datagrams may be fragmented on the way; unset, as the place says, see udp_fragment_default. |
domain_resolver |
string|object → object | unset | Supported | The DNS server that resolves the names dialled. |
network_strategy |
string, one of default, fallback, hybrid |
— | Error: Choosing among the host’s networks (Wi-Fi, cellular) here: it would go out as the route’s defaults say | Which of the host’s interfaces a connection goes out of, and how they race; default where only types are given. Only where the host lists its interfaces (NetworkState::interfaces). |
network_type |
listable-string, one of cellular, ethernet, other, wifi |
— | Error: Choosing among the host’s networks (Wi-Fi, cellular) here: it would go out as the route’s defaults say | The types of interface the strategy goes out of first. |
fallback_network_type |
listable-string, one of cellular, ethernet, other, wifi |
— | Error: Choosing among the host’s networks (Wi-Fi, cellular) here: it would go out as the route’s defaults say | The types it falls back to, with fallback. |
fallback_delay |
duration | unset | Supported | How long the addresses of one family are tried before those of the other are raced against them (Happy Eyeballs), and the first interfaces before the fallback ones; 300ms when unset. |
domain_strategy |
string | unset | Supported (deprecated in sing-box) | sing-box’s deprecated field for the families names resolve to, which a resolver’s own strategy goes before. |
skip_default_domain_resolver |
bool | false |
sail extension | A sail extension: without a domain_resolver of its own, the names dialled resolve as the DNS rules say, not as route.default_domain_resolver does; as Mihomo’s DIRECT resolves apart from the proxies’ servers. |
endpoints[wireguard].peers[]
Section titled “endpoints[wireguard].peers[]”Rust: PeerOptions · Build: feature = "wireguard"
| Field | Type | Default | Status | Description |
|---|---|---|---|---|
address |
string | unset | Supported | Where the peer is: an address or a domain. Without it, it is learnt from the peer’s handshake, as a server’s peers are. |
port |
number | unset | Supported | — |
public_key |
string | required | Supported | — |
pre_shared_key |
string | unset | Supported | — |
allowed_ips |
listable-string | required | Supported | — |
persistent_keepalive_interval |
number | unset | Supported | Seconds; 0 or unset is off. |
reserved |
string|array | unset | Supported | Three bytes, or their base64: Cloudflare WARP’s client identifier. |
Types sail does not implement: endpoints
Section titled “Types sail does not implement: endpoints”| Type | Status | Fields |
|---|---|---|
endpoints[openconnect] |
Error: A protocol sail does not implement | 114 |
endpoints[openvpn-client] |
Error: A protocol sail does not implement | 117 |
endpoints[openvpn-server] |
Error: A protocol sail does not implement | 97 |
endpoints[tailscale] |
Error: A protocol sail does not implement | 54 |