sing-box 配置文件怎么写?最小 JSON、版本迁移与报错排查
简答:sing-box 配置文件本质是 JSON。若旧教程出现 unknown field,先核对版本迁移:1.12.0 改用新的 DNS server 格式,1.11.0 将特殊出站和 WireGuard 出站迁移到规则动作与 endpoints。下面的 Trojan 客户端示例适用于 1.14.0 及以上,替换节点认证字段后先执行 check。
定义:sing-box 配置文件是用 JSON 描述 DNS、入站、出站、端点、路由和实验功能的文件,可由命令行程序或图形客户端读取。
先试这一步:用 1.14.0 及以上版本校验一个 Trojan 客户端配置
如果你从旧教程复制配置后出现 unknown field,先不要继续删字段。最常见的迁移点包括:1.12.0 的 DNS server 格式变化、1.11.0 的特殊出站改为规则动作,以及 WireGuard 从 outbounds 迁移到 endpoints。先确认核心版本,再使用下面这个仅用于 Trojan 的客户端示例。
速查结论:本示例按 1.14.0 及以上配置;必须替换 REPLACE_SERVER、REPLACE_PORT、REPLACE_PASSWORD 和 REPLACE_SERVER_NAME 四项;保存文件名直接使用 config.json;命令行校验使用 sing-box check -c config.json。
{
"$schema": "https://sing-box.sagernet.org/schema.json",
"log": {
"level": "info"
},
"dns": {
"servers": [
{
"type": "local",
"tag": "local"
}
],
"final": "local"
},
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 7890
}
],
"outbounds": [
{
"type": "trojan",
"tag": "proxy",
"server": "REPLACE_SERVER",
"server_port": REPLACE_PORT,
"password": "REPLACE_PASSWORD",
"tls": {
"enabled": true,
"server_name": "REPLACE_SERVER_NAME"
},
"domain_resolver": "local"
},
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"auto_detect_interface": true,
"default_domain_resolver": "local",
"final": "proxy"
}
}
这里的 REPLACE_PORT 必须替换成数字,例如 443,不能保留引号。其余占位符是字符串。端口由 inbounds.listen_port 决定,本示例使用 7890;它不是 sing-box 固定默认值。
在配置文件所在目录执行:
sing-box check -c config.json
sing-box format -w -c config.json
check 主要检查配置结构和字段,不能证明远端节点可达;启动后仍要查看连接日志中的 DNS、TCP、TLS 和认证结果。官方配置页列出了 JSON 结构、check、format 和 merge 命令,可参考 sing-box 配置文件结构。
截至 2026-10-24,Releases 标记为 Latest 的是 1.14.3;1.15.0 处于预发布(alpha)阶段,实际使用时以 Releases 页面为准。
配置文件的顶层结构:WireGuard 不再写进 outbounds
sing-box 配置文件不是把所有内容都放在一个节点列表里,而是按功能划分顶层区域。当前官方结构包含 $schema、log、dns、ntp、certificate、certificate_providers、http_clients、network_namespaces、endpoints、inbounds、outbounds、route、services 和 experimental。$schema 由官方 JSON Schema 页面说明,兼容的编辑器可用它提供补全和校验。
| 区域 | 用途 | 常见检查点 |
|---|---|---|
log | 控制日志等级和输出 | 连接失败时先提高日志可见性 |
dns | 定义 DNS server、默认解析器和 DNS 策略 | 服务器标签是否存在,域名出站是否指定解析器 |
endpoints | 承载 WireGuard、Tailscale 等端点 | WireGuard 不应再按旧教程写成 outbounds 类型 |
inbounds | 定义本机接收流量的方式 | mixed、socks、http、tun 的监听地址和端口 |
outbounds | 定义 direct、Trojan、VLESS、VMess、Shadowsocks、Hysteria2、TUIC 等出站 | type、认证字段、TLS 和传输参数是否匹配 |
route | 决定流量进入哪个出站,并定义规则、默认网卡和最终出站 | final 或规则引用的 tag 是否已声明 |
官方端点文档明确列出 wireguard 类型,并说明端点自 1.11.0 起提供入站与出站行为。迁移表中也说明旧 WireGuard outbound 已迁移到 endpoint,旧写法不应继续用于新配置。可查看 Endpoint 配置 和 迁移指南。
配置中所有引用关系都要对得上。例如 route.final 写成 proxy,就必须在 outbounds 或对应可引用对象中存在同名 tag。Trojan 示例中的四个替换字段只适用于 Trojan;VLESS、VMess、Hysteria2、TUIC、Shadowsocks 和 WireGuard 的认证字段不能只靠改 type 完成。
旧写法到新写法:DNS、特殊出站、sniff 和 WireGuard 迁移速查
| 旧写法或旧思路 | 适用迁移节点 | 新配置方向 |
|---|---|---|
dns.servers[].address | 1.12.0 | 使用 type,例如 {"type":"local"} 或 {"type":"udp","server":"1.1.1.1"} |
| 依赖隐式域名解析器 | 1.12.0 起应改用新解析器字段 | 在 DNS 中声明 server,并通过 route.default_domain_resolver 或出站的 domain_resolver 指定 |
type: block 特殊出站 | 1.11.0 起迁移 | 按匹配条件使用规则动作,例如 action: reject |
type: dns 特殊出站 | 1.11.0 起迁移 | 使用带匹配条件的 hijack-dns 规则动作 |
WireGuard 写在 outbounds | 1.11.0 起迁移 | 使用顶层 endpoints 中的 wireguard 端点 |
| 入站直接使用旧式 sniff 字段 | 1.11.0 起规则动作增加 | 按当前官方规则文档使用 sniff 动作;域名规则依赖 sniff 结果时,应先让 sniff 产生可匹配信息 |
inet4_address、inet6_address | 1.10.0 | 合并到 TUN 的 address |
DNS 劫持规则不能无条件匹配所有流量。示例应至少带有 DNS 协议匹配:
"route": {
"rules": [
{
"action": "sniff"
},
{
"protocol": "dns",
"action": "hijack-dns"
}
],
"final": "proxy"
}
官方迁移页分别标注了 1.10.0、1.11.0 和 1.12.0 的迁移内容;DNS server 格式、domain resolver、特殊出站、WireGuard endpoint 和 TUN 地址字段不要混用不同版本教程中的写法。可对照 官方迁移指南 和 DNS 配置参考。
服务器入站、客户端出站与 VLESS 链接字段怎么对应
客户端配置和服务器配置不是同一份文件。客户端通常需要本地 inbounds、远端节点 outbounds 和 route;服务器则需要监听远端端口的入站、认证信息、TLS 证书以及直连或转发出站。下面的结构只适合自有服务器或已获授权的环境,证书路径、密码和端口必须替换为真实值。
{
"log": {
"level": "info"
},
"inbounds": [
{
"type": "trojan",
"tag": "trojan-in",
"listen": "0.0.0.0",
"listen_port": 443,
"users": [
{
"name": "user-1",
"password": "REPLACE_PASSWORD"
}
],
"tls": {
"enabled": true,
"certificate_path": "/path/to/certificate.crt",
"key_path": "/path/to/private.key"
}
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"final": "direct"
}
}
服务器模板不能与客户端 Trojan 模板互换:客户端使用远端服务器地址和密码,服务器使用监听地址、用户列表和证书。证书文件、私钥和密码不要公开,也不要把包含这些信息的日志提交到公共平台。
如果手里只有 VLESS 链接,先把链接字段拆成下表,再按官方 VLESS outbound 页面组成 JSON。链接本身不是完整 sing-box 配置,不能只把文件后缀改成 .json。
| 链接信息 | JSON 中通常对应的位置 | 检查重点 |
|---|---|---|
| 服务器主机和端口 | server、server_port | 端口是数字,主机名可解析 |
| UUID | uuid | 必须是节点提供的认证值,不要写成密码 |
| 传输方式 | transport 或对应传输字段 | TCP、WebSocket、gRPC 等必须与服务端一致 |
| TLS 开关和 SNI | tls.enabled、tls.server_name | SNI 不一定等于连接地址 |
| Reality 参数 | Reality 对应 TLS 字段 | 公钥、短 ID 等字段必须按当前官方出站文档填写 |
VLESS、Reality 及其他协议的完整字段应以对应出站文档为准,不能用 Trojan 的“服务器、端口、密码、TLS”四项替代。官方出站索引见 Outbound 配置参考。
JSON Schema、命令行与图形客户端的导入方法
从 1.14.0 起,sing-box 提供 JSON Schema。编辑器若支持 JSON Schema,可在文件顶部写入 "$schema": "https://sing-box.sagernet.org/schema.json",获得字段补全和部分校验。也可以用已安装核心生成与当前构建匹配的本地 schema:
sing-box schema -o schema.json
如果编辑器无法访问远程地址,可以把配置中的 schema 改为相对路径 "$schema": "./schema.json",并确保两个文件位于同一目录。官方 JSON Schema 页面说明了远程 schema 和本地生成方式,见 JSON Schema。
命令行基本流程如下:
- 将配置保存为
config.json,避免把带尖括号的占位文件名直接复制到 shell。 - 在配置所在目录执行
sing-box check -c config.json。 - 校验通过后执行
sing-box format -w -c config.json,再检查变更内容。 - 启动后查看连接日志,确认命中的策略和实际错误。
- 如需确认是否经过代理,对比启用前后的出口 IP,并结合日志判断。
| 平台 | 导入方式 | 权限与路径注意事项 |
|---|---|---|
| Windows | 可使用官方客户端页面列出的 sing-box for Desktop,导入本地或远程配置 | 启用 TUN 或服务模式时按系统提示授权;端口以配置的 listen_port 为准 |
| macOS | 使用 Apple 平台客户端导入配置,或运行命令行核心 | 网络扩展、TUN 和隔离放行在“隐私与安全性”中处理;端口排查使用 lsof |
| Linux | 使用命令行、官方包管理方式、systemd 或 Docker | 服务用户需要读取配置、证书和订阅文件;systemd 可用 sudo systemctl 和 sudo journalctl |
| Android | 使用 sing-box for Android 导入本地或远程配置 | 检查 VPN 权限、电池后台限制以及 TUN 与系统 VPN 的关系 |
| iOS | 使用 sing-box for Apple platforms 对应客户端 | 系统 VPN 配置由客户端申请,没有统一命令行配置目录 |
官方客户端列表显示,Android 使用 sing-box for Android,iOS、macOS 和 Apple tvOS 使用 sing-box for Apple platforms,Windows 和 Linux 使用 sing-box for Desktop。Windows 与 Linux 桌面客户端的具体要求和功能以 官方客户端列表及 Desktop 客户端说明为准。
Linux 使用 systemd 时,可先确认服务文件和实际配置路径:
sudo systemctl cat sing-box
sudo systemctl enable sing-box
sudo systemctl restart sing-box
sudo journalctl -u sing-box --output cat -e
不要假定所有发行版都使用同一个默认配置路径;以服务文件中的 -c 参数为准。Docker 场景还要检查宿主机目录挂载和容器用户的读取权限。
TUN、DNS 和端口问题:按顺序缩小范围
TUN 会创建虚拟网卡并接管系统流量,不能把它当作普通 mixed 端口。官方 TUN 文档标明,dns_mode 和 dns_address 自 sing-box 1.14.0 起提供;dns_mode 可选 disabled、native 和 hijack,dns_address 用于指定该模式使用的 DNS 地址。旧教程如果没有版本说明,不要直接照抄。
开启 TUN 后断网,按以下顺序排查:
- 先关闭 TUN,只保留 mixed 或 socks 入站,确认单个应用能否连接。
- 确认
route.auto_detect_interface、route.default_interface或出站绑定网卡设置,避免流量重新进入 TUN 形成环路。 - Windows 检查 TUN 服务或管理员权限;macOS 在“隐私与安全性”中放行网络扩展并处理隔离提示;Linux 检查专用用户的配置文件、证书和 TUN 设备权限。
- Linux 使用
auto_route时,检查auto_redirect是否与 Docker、虚拟机或现有防火墙规则冲突。 - DNS 劫持规则必须有匹配条件,优先确认 DNS 流量是否命中
protocol: dns,不要使用无条件的hijack-dns规则。 - 查看连接日志中的实际出站 tag,再用出口 IP 对比判断流量是否经过预期路径。
如果只是端口冲突,Windows 可执行 netstat -ano | findstr :7890,macOS 使用 lsof -nP -iTCP:7890 -sTCP:LISTEN,Linux 使用 sudo ss -lntp | grep 7890。这些命令检查的是示例端口,实际应替换成配置中的 listen_port。TUN 字段和平台限制以 官方 TUN 文档为准。
常见报错如何判断
| 现象 | 优先检查 | 处理方式 |
|---|---|---|
JSON 解析失败或出现 invalid character | 逗号、双引号、括号和注释 | 删除 JSON 注释,用编辑器格式化,再执行 check |
| 日志中出现找不到字段的提示 | 字段是否来自旧版本或其他核心 | 对照当前官方配置页和迁移页,不要只删除字段后继续运行 |
| 日志中出现找不到对应 tag 的出站 | route.final、规则引用和 outbounds[].tag | 逐字核对大小写、连字符和 tag 是否一致 |
| 端口绑定失败 | 本机是否已有程序监听同一端口 | 使用对应平台的端口命令查询 PID,再关闭冲突程序或修改 listen_port |
| 配置能启动但域名节点无法连接 | DNS、domain_resolver、TLS SNI 和服务器地址 | 确认 DNS server 标签存在,检查日志中的解析和 TLS 错误 |
| TUN 开启后系统断网 | 权限、自动路由、默认网卡、DNS 模式和劫持规则 | 先关闭 TUN 验证出站,再逐项恢复路由、DNS 和规则 |
这些描述是按配置检查时的故障类别整理,不把某个未核实的日志句子当作固定版本报错。真正判断时,应以当前核心输出的完整日志为准。
常见问题
sing-box 配置文件应该叫什么名字?
命令行可以使用任意 JSON 文件名,本文统一使用 config.json。关键不是文件名,而是启动命令中的 -c 路径必须指向该文件;图形客户端通常通过导入功能管理本地或远程配置。
Trojan 示例是不是只需要替换四个字段?
本文的四字段结论只适用于示例中的 Trojan 出站:服务器地址、端口、密码和 TLS server_name。VLESS、VMess、Hysteria2、TUIC、Shadowsocks 和 WireGuard 需要按各自官方出站或 endpoint 字段填写。
为什么旧配置中的 dns.servers.address 会报错?
sing-box 1.12.0 迁移了 DNS server 格式,新的写法使用 type,例如 local、udp 或 tcp,并按需要填写 server。应同时检查 domain_resolver 或 route.default_domain_resolver,避免依赖隐式解析器。
WireGuard 应该写在 outbounds 还是 endpoints?
新配置应使用顶层 endpoints 中的 wireguard 端点。官方迁移说明显示,旧 WireGuard outbound 已从 1.11.0 起迁移到 endpoint,继续照抄旧结构可能触发字段或类型错误。
dns_mode 和 dns_address 从哪个版本开始支持?
官方 TUN 文档标明,这两个字段自 sing-box 1.14.0 起支持。dns_mode 控制 TUN 上的 DNS 处理方式,dns_address 指定相关 DNS 地址;使用前要确认实际核心版本。
sing-box check 通过后为什么仍然无法连接?
check 主要验证配置结构和字段,不代表远端服务器可达。继续检查连接日志中的域名解析、TCP 建连、TLS SNI、认证失败和路由命中情况,并对比启用代理前后的出口 IP。