Skip to content

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 cfg conditions 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: Endpoint

Field Type Default Status Description
type string, one of openconnect, openvpn-client, openvpn-server, tailscale, wireguard required Supported —

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.

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.

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