配置模型
Sail 的原生配置就是 sing-box 的 JSON(sing-box 1.14),外加少量 Sail 扩展。与 sing-box 一样,允许注释和尾随逗号。Sail 也能直接读取 Clash / Mihomo 的 YAML 和 Surge 配置:由文件扩展名(.json、.yaml 或 .yml、.conf)或文本内容决定格式,三者都会转换为同一个配置模型。格式如何识别见协议与兼容性。
Sail 不认识的字段会报错。Sail 尚未实现的 sing-box 字段,如果忽略它不影响路由和安全,就丢弃并给出警告,否则报错。启动时会逐条记录这些警告。
逐字段查阅请使用自动生成的参考:顶层与通用、DNS、入站、出站与策略组、端点、路由及共用对象,并标明每个字段相对 sing-box 的状态;Clash 与 Surge 的支持表见兼容性。
| 字段 | 用途 | 默认值 |
|---|---|---|
log |
日志级别、格式和文件输出 | info、完整格式、控制台 |
dns |
DNS 服务器、DNS 规则、策略与缓存 | 系统解析器,prefer_ipv4 |
inbounds |
接收流量的监听器或数据源 | 空 |
outbounds |
直连、代理与策略组 | 空 |
endpoints |
同一标签下既是入站也是出站(WireGuard) | 空 |
route |
有序规则、规则集与最终出站 | 第一个出站 |
certificate |
校验服务器所用的根证书 | 系统证书库 |
http_clients |
按标签定义 Sail 下载规则集和提供者的方式 | 经默认出站 |
experimental |
cache_file 与 Clash API |
关闭 |
api |
Sail 的控制 API,在 Unix socket 或回环地址上(扩展) | 关闭 |
clash_api |
Clash API,也可写在 experimental 下(扩展) |
关闭 |
outbound_providers |
下载或集中给出、供策略组使用的出站(扩展) | 空 |
user_limits |
跨入站的按用户限制(扩展) | 空 |
sing-box 的 ntp 段会被读取:测得的时间用于各协议的时间校验以及 TLS 与 QUIC 的证书有效期校验,系统时钟不会被修改。server 请填 IP 地址,或让它的域名经明文 DNS 解析:第一次测得时间之前用的仍是系统时间,若域名经 DoH、DoT 或 DoQ 解析,该 DNS 服务器的证书会按未校正的时间校验,在时钟偏差很大的设备上会失败。sing-box 的 services、certificate_providers 和 network_namespaces 大多会报错。
每个入站、出站和端点都有 type,并可设置 tag。省略标签时默认使用协议类型;配置中有多个条目后,建议显式命名。
网络类入站共用以下字段:
{ "type": "socks", "tag": "lan-socks", "listen": "127.0.0.1", "listen_port": 1080, "udp_timeout": "30s"}listen 默认为 127.0.0.1。没有 listen_port 的入站不会打开监听,只在被其他入站组合使用时有意义。udp_timeout 默认 5 分钟。协议专属字段(如 SOCKS 用户、Shadowsocks 凭据)与这些通用字段并列。
出站字段与模块
Section titled “出站字段与模块”出站从协议及其连接信息开始:
{ "type": "trojan", "tag": "edge", "server": "edge.example.com", "server_port": 443, "password": "replace-me", "tls": { "enabled": true, "server_name": "edge.example.com" }}流式代理协议可以在协议外层组合通用模块:
| 模块 | 控制内容 |
|---|---|
tls |
TLS、证书、ALPN、ECH、REALITY 与浏览器 ClientHello |
transport |
WebSocket、HTTP Upgrade、gRPC 或 QUIC |
multiplex |
在共享连接上运行 sing-mux(smux、yamux、h2mux) |
detour |
经另一个出站连接本出站的服务器 |
| 拨号字段 | 网卡、本地地址、Linux 标记、超时、keepalive 与域名解析 |
支持哪些模块取决于协议。TUIC、Hysteria2 等原生 QUIC 协议自行管理 TLS 配置,并不接受所有流式传输模块。各层说明见协议与兼容性。
{ "type": "socks", "tag": "upstream", "server": "192.0.2.10", "server_port": 1080, "bind_interface": "en0", "connect_timeout": "5s"}拨号字段与 sing-box 相同:bind_interface、inet4_bind_address、inet6_bind_address、routing_mark(Linux)、reuse_addr、connect_timeout、tcp_fast_open、TCP keepalive 相关字段、udp_fragment、domain_resolver,以及 network_strategy 及其 network_type、fallback_network_type、fallback_delay。route.default_interface、route.default_mark、route.default_domain_resolver 和 route.default_network_strategy 为没有自行设置的出站提供默认值。哪些字段在哪里受支持,见共用对象参考。
{ "dns": { "servers": [ { "type": "local", "tag": "system" }, { "type": "https", "tag": "cloudflare", "server": "1.1.1.1" } ], "rules": [ { "domain_suffix": ["internal.example"], "server": "system" } ], "final": "cloudflare", "strategy": "prefer_ipv4", "cache_capacity": 4096, "timeout": "4s", "reverse_mapping": true }}服务器类型有 local、hosts、udp、tcp、tls、quic、https、h3、fakeip 和 mdns,另有 Sail 的 race:同时询问所有成员,采用第一个有效应答。sing-box 的 dhcp、resolved、tailscale、openvpn 和 openconnect 服务器会报错。没有配置服务器时由系统解析器应答。DNS 规则按顺序选择服务器,其余查询交给 final,未设置时交给第一个服务器。
strategy 可取 prefer_ipv4(默认)、prefer_ipv6、ipv4_only 或 ipv6_only。缓存容量为 1024 条,cache_capacity 更大时以其为准;对单个服务器的一次查询最长 10 秒,可用 timeout 修改。反向映射记住 DNS 应答对应的域名,让后续仅携带 IP 的连接仍能命中域名规则。Sail 的 client_strategy 限制返回给客户端查询的地址族,不影响 Sail 自身的解析。
本地链路上的名字(mDNS)
Section titled “本地链路上的名字(mDNS)”mdns 服务器({ "type": "mdns", "tag": "lan", "interface": ["en0"] },interface 为空时用所有支持组播的网卡)以组播 DNS 解析 .local 名字和链路本地的反向区。非 Apple 系统上,local 服务器遇到这些名字也会自己走 mDNS;Apple 系统上交给系统解析器。DNS 规则的 preferred_by 列出服务器,匹配它们自己能回答的名字:hosts 服务器的条目,local 的 hosts 文件与 mDNS 名字,mdns 的 mDNS 名字。
与 sing-box 不同,sail 的查询要求单播回复(RFC 6762 的 QU 位):Windows 只回答这种查询,所以 sing-box 解析不到 Windows 机器的 .local 名字,sail 可以。另外,任一网卡答到就立即返回,不必等满一秒。
日志与控制 API
Section titled “日志与控制 API”{ "log": { "level": "debug", "format": "compact", "output": "sail.log" }, "api": {}}日志级别有 trace、debug、info、warn(或 warning)和 error;fatal 与 panic 也接受,效果同 error。disabled 关闭全部日志,timestamp 在每行开头加时间。format: compact 是 Sail 扩展,只输出消息本身。不设置 output 时输出到控制台。控制台是终端时才带颜色,管道或 systemd journal 不带;设置环境变量 NO_COLOR 后终端也不带颜色(对应 sing-box 的 --disable-color)。
设置了 api 才会提供 API。默认在 Unix socket 上,即数据目录下的 api.sock(用 path 指定别处),只有运行 Sail 的用户能打开。listen 让它同时在回环地址上提供,例如 127.0.0.1:9091,此时必须设置 secret:用 sail generate secret 生成,每次调用以 Authorization: Bearer <secret> 携带,缺少或错误时返回 401。本机任何进程都能连上回环端口,而经网络发送的密钥是明文,所以 listen 只接受回环地址;要从别处访问,请用 SSH 隧道或反向代理。Unix socket 上设置了 secret 时也会校验。错误以 JSON 返回,形如 {"error": {"code": "invalid", "message": "..."}};重载失败时也这样返回原因,原来的配置继续运行。
管理 API:GET /api/v1 返回本构建的版本和特性。/api/v1 之内只增不减,客户端应忽略不认识的路由和字段;去掉或改动它们的改动放到 /api/v2 下。以下路由都在 /api/v1/runtime 之下:
| 路由 | 作用 |
|---|---|
GET /users、GET /users/{name} |
按名字列出用户:所在入站、能否连接(active、over_quota、expired)、限制、流量、活动连接数和已用配额 |
PUT /users/{name}/limits |
按请求体限制该用户,到下次重载为止。请求体可以是 GET 返回的 limits,原样 PUT 回去即可(时间为 expire_at_ms,Unix 毫秒);也可以按 user_limits 中一个用户的写法(expire_at 为 RFC 3339)。返回 204 |
DELETE /users/{name}/limits |
恢复为配置文件中的限制;返回 204 |
POST /users/{name}/quota/reset |
已用流量不再计入配额;返回 204 |
POST /users/{name}/disconnect |
断开该用户的连接,返回 {"closed": n};之后它仍可重新连接 |
GET /stats |
按用户、入站、出站给出流量;?clear=true 表示自上次这样读取以来的增量,不影响配额 |
GET /status |
总流量、连接数和内存 |
GET /events |
以 Server-Sent Events 推送用户的变化:shut(超额或到期,已断开)与 removed(被移出入站),数据为该事件的 JSON;订阅方落后太多时收到 lagged,带漏掉的条数 |
GET /connections、DELETE /connections、DELETE /connections/{id} |
列出进行中的连接,关闭全部或其中一条 |
POST /reload、POST /shutdown |
重载配置文件,或停止。重载的响应给出每个入站的结果:{"inbounds": [{"tag", "change"}]},change 为 untouched、reloaded(换了用户或证书)、added、removed、replaced 之一;只有被移除和被替换的入站的连接会断开。配置文件增加、移除或修改了 TUN 时返回 409(needs_restart),此时什么都没有变 |
GET /inbounds |
列出入站:tag、类型、监听地址,以及运行中能否修改用户(reloadable) |
POST /inbounds、DELETE /inbounds/{tag}、POST /outbounds、DELETE /outbounds/{tag} |
增删一个入站或出站,格式同配置文件 |
PUT /inbounds/{tag} |
用请求体(完整的入站配置)替换一个可热更新入站的用户和证书,不重新绑定端口;返回 204 |
GET /inbounds/{tag}/users |
该入站的用户名列表,从不返回凭据 |
POST /inbounds/{tag}/users |
增加一个用户,格式同该入站的 users,必须有名字;返回 201,同名已存在时返回 409 |
PUT /inbounds/{tag}/users/{name} |
替换该用户的凭据,例如改密码;已有连接不断开,与 sing-box 一致;返回 204 |
DELETE /inbounds/{tag}/users/{name} |
把该用户移出入站,并断开它经这个入站的连接;返回 204 |
对不可热更新的入站修改用户,返回 422(unsupported):请改配置文件后重载。
经 API 做的修改不写回配置文件:重载或重启以文件为准。经 API 增加、而配置文件里没有的入站,会在下一次重载时被移除,所以要同时写进配置文件。没有入站包含的用户返回 404。
供面板使用的 Clash API 写在 clash_api 或 sing-box 的 experimental.clash_api 中,二者只能选一。
Sail 扩展
Section titled “Sail 扩展”以下字段是 Sail 自有的,sing-box 不接受。完整列表在兼容性页面所链接的 sing-box 支持表末尾。
outbound_providers:下载(remote)、从文件读取(local)或直接写在配置中(inline)的一组出站,对应 Mihomo 的 proxy-providers。下载内容或文件可以是带proxies的 Clash YAML,也可以是分享链接。selector、urltest、fallback、load-balance和smart组通过providers使用它们,详见路由规则。user_limits:按用户名设置,作用于该用户所在的所有入站:max_connections、quota_bytes(上下行合计;需要experimental.cache_file)、expire_at(RFC 3339),以及up_mbps和down_mbps。未写的字段不限制;任何字段都不能为 0。api,以及顶层的clash_api。- 路由方面的扩展,如
geoip、geosite、external、ip_asn和no_resolve,以及fallback、load-balance、smart、network、tryall和pass出站。详见路由规则与协议与兼容性。
重要验证规则
Section titled “重要验证规则”route.final、路由规则、策略组和 detour 引用的标签必须存在;规则和解析器引用的 DNS 服务器也必须存在。- 对所有连接都会结束匹配的规则(
route、reject,或带出站的bypass)至少需要一个条件;全量兜底应使用route.final。 - 动作字段只属于对应动作:
sniffer、skip_rule_set属于sniff;server、strategy属于resolve;timeout属于两者之一;method属于reject。override_destination属于sniff、route和route-options,其中"at_sniff"只能用于sniff。 route.auto_detect_interface与route.default_interface不能同时设置。route.default_network_strategy需要开启route.auto_detect_interface。- DNS、UDP、嗅探等超时必须大于零。
开了 auto_route 的 TUN 入站会自动开启网卡检测,详见防止 TUN 回环。
每次修改后运行 sail -c config.json -T。连通性测试与运行时设置见 CLI 参考。
Clash 与 Surge 文件
Section titled “Clash 与 Surge 文件”sail -c config.yaml 读取 Clash / Mihomo 配置,sail -c profile.conf 读取 Surge 配置,都转换为上面的模型。Surge 配置引用的文件从其所在目录读取,若由宿主下载,则从宿主的缓存中读取。各格式中 Sail 忽略或拒绝的设置列在兼容性表中。leaf 旧的 .conf 格式已不再支持:.conf 文件一律按 Surge 配置读取。