sing-box 升 1.14 前先改三处旧配置,不然启动直接报错

sing-box 升 1.14 前先改三处旧配置,不然启动直接报错

背景:不是节点坏了,是旧配置被删了

sing-box 是开源的通用代理平台,服务器端和客户端共用同一份 JSON 配置。它的版本迭代有个特点:旧写法先标"已弃用"、过一两个大版本直接删除,升级后旧配置不是"跑得慢一点",而是启动时直接报错退出。最近不少人从 1.11 一路升到 1.14,结果卡在三类报错上,本文按报错讲改法。前置知识:一份能跑起来的 sing-box 配置、会用命令行;日志定位方法见排错篇,DNS 分流思路见 DNS 篇。

升级前先做两件事,任何一处改错都能回滚:

cp config.json config.json.bak
sing-box check -c config.json

第一条是备份,第二条是校验——改完先跑校验,通过再重启服务。写稿时 1.14 线已出到 1.14.4,本文对照的是官方迁移文档与更新日志。

第一处:DNS 服务器的 address 写法,1.14 已删除

这是最常见的报错。旧写法用一个 address 字符串同时表达协议和地址,新写法拆成 type、server、server_port 三个字段。报错关键词通常是 legacy DNS server formats are deprecated in sing-box 1.12.0 and removed in sing-box 1.14.0。

旧写法与新写法对照如下:

// 旧写法:1.14 起拒绝启动
{ "address": "tcp://1.1.1.1" }
{ "address": "https://1.1.1.1/dns-query" }
{ "address": "local" }

// 新写法
{ "type": "tcp", "server": "1.1.1.1" }
{ "type": "https", "server": "1.1.1.1" }
{ "type": "local" }

规律很好记:去掉协议前缀,把前缀变成 type,剩下的地址填 server;DoH 的路径如果不是默认的 /dns-query,用 path 字段单独写。纯 IP 的旧写法("address": "1.1.1.1")对应新写法的 type 是 udp。FakeIP 也要顺手改:旧写法是 dns 下独立的 fakeip 一段,新写法把它并进一个 type 为 fakeip 的服务器里,地址段写在该服务器的 inet4_range、inet6_range 中。

第二处:TUN 的旧地址字段,1.12 已删除

如果你在客户端用 TUN 模式接管全部流量,升级到 1.12 后可能看到 legacy tun address fields are deprecated in sing-box 1.10.0 and removed in sing-box 1.12.0。旧的 TUN 地址字段已被统一的 address 数组取代:

{
  "type": "tun",
  "address": ["172.18.0.1/30"]
}

只改这一处还不够:TUN 入站常配合 auto_route、auto_redirect 使用,改完地址后务必用 sing-box check 校验一遍,再看系统路由表是否如预期——地址写错的表现不是报错,而是"能启动但所有流量都不走代理",容易误判成节点问题。

第三处:DNS 规则里的地址过滤,1.14 换了玩法

1.14 的 DNS 规则引入了 evaluate 与 match_response 两个新机制,旧的地址过滤玩法与之冲突。典型场景是:规则集里只有 IP 段(例如 GeoIP 规则集),DNS 规则直接拿它匹配、决定走哪个 DNS 服务器;一旦规则里同时用了 1.14 新增的 ip_version、query_type 这类字段,启动时会被直接拒绝。

官方推荐的新写法分两步:先用 evaluate 动作取一次 DNS 应答,再用带 match_response: true 的规则对"应答结果"做匹配:

{
  "dns": {
    "rules": [
      { "action": "evaluate", "server": "remote" },
      {
        "match_response": true,
        "rule_set": "geoip-cn",
        "action": "route",
        "server": "local"
      },
      { "action": "route", "server": "remote" }
    ]
  }
}

理解这段的关键是顺序:第一条规则不决定去向,只负责"先问一次远端";第二条看应答里的 IP 是否命中规则集,命中才走本地 DNS;都不命中才落到最后的远端。rule_set 里的名字(上例的 geoip-cn)换成你自己的规则集 tag 即可,不要照抄。

升级检查清单

步骤做什么不通过的表现
备份复制一份旧配置改错无法回滚
校验sing-box check -c config.json直接报出哪一行字段非法
分段升级先升 1.12 修 DNS 与 TUN,再升 1.14 修 DNS 规则一次跨多个大版本,报错混在一起难定位
逐项验证改完一项校验一次,再改下一项多处同改,出问题不知道是哪处

还有两点容易踩:一是不要因为看到 block 出站曾被标弃用就急着删它——1.11.10 已取消对它的弃用标记,在有替代方案之前它仍可正常用;二是不要顺手跟进 1.15 的 alpha 版尝鲜,alpha 版的 TUN 协议栈正在换代,stack 字段已被标弃用,生产配置没必要陪跑。升级的正确姿势永远是:备份、校验、一次只改一处、改完验证再继续。

小结

三处旧写法对应三条升级线:DNS 服务器写法是 1.12 弃用、1.14 删除;TUN 旧地址字段是 1.10 弃用、1.12 删除;DNS 规则的地址过滤在 1.14 改为 evaluate + match_response。报错文案里通常直接写明"在哪个版本弃用、在哪个版本删除",按文案里的版本号去迁移文档里找对应小节,比全文搜索旧配置更快。