sing-box 1.14.4 的 check 会拒绝出站上的旧 domain_strategy。报错里提到的环境变量不是替换办法。迁移节把新字段写成 domain_resolver,对不是 direct 的出站,它解析的是服务器域名,不是 ChatGPT、Claude 或 Gemini 的网站名。

OpenAI、Anthropic 和 Google 都没有把中国大陆写成这些产品的无条件服务地。从名单外访问可能违反条款,账号可能被限制或停用。改节点域名用哪一族地址,不改变名单。本文不写伪造证件、购买或借用账号、手机号和支付卡。起草环境不是大陆宽带,没有执行 run。

先确认失败停在配置检查

一个可单独引用的区分:旧字段让 check 退出,和网站已经返回国家或地区不支持,不是同一种失败。

你能观察到的更像什么不要先做的事
check 退出码 1,原文含 legacy domain strategy出站还留着 1.12 之前的字段不要先改 AI 账号
原文是 domain resolver not found,或 empty domain_resolver.server新字段写了,但 DNS 服务器标签对不上不要设文末那个环境变量
隧道已建立,网站返回国家、地区或 territory出口不在对方名单不要改服务器域名的地址族
网站名有 AAAA,隧道只接住 IPv4目的站的地址族见 AI 的 AAAA 可以不进 IPv4 隧道

目的站那一篇处理的是 chatgpt.com 这一类名字。本文的例子域名是迁移节里的 example.org,把它当成节点自己的服务器名,不要当成要访问的网站。

1.14.4 对旧字段的原文

2026-11-08 查询 GitHub Releases API:latest 仍是非预发布的 v1.14.4,published_at 为 2026-10-24T01:04:25Z。当天的 linux-amd64 二进制 sing-box version 为 1.14.4,修订 c005f35300ce76427dc285481ec5695f5b179cd2。

标签 docs/configuration/shared/dial.md 把 domain_strategy 标为 1.12.0 弃用、将在 1.14.0 移除,并链到迁移节。取值仍列出 prefer_ipv4、prefer_ipv6、ipv4_only、ipv6_only。同一页写明:不是 direct 的出站,这个旧字段影响的是服务器地址里的域名。

下面这份只有旧字段,没有 DNS 段:

{
  "outbounds": [
    {
      "type": "socks",
      "tag": "proxy",
      "server": "example.org",
      "server_port": 2080,
      "domain_strategy": "prefer_ipv4"
    }
  ]
}

sing-box check 退出码 1。去掉颜色后的两句是:

  • legacy domain strategy options is deprecated in sing-box 1.12.0 and will be removed in sing-box 1.14.0, checkout documentation for migration: https://sing-box.sagernet.org/migration/#migrate-domain-strategy-options
  • to continuing using this feature, set environment variable ENABLE_DEPRECATED_LEGACY_DOMAIN_STRATEGY_OPTIONS=true

第二句的 “to continuing” 是二进制原文,没有改。把该变量设为 true 之后,同一次 check 退出码变成 0,但仍打出上一句的 WARN。变量只是把已经声明要删除的路径再放行一次。本文不把它写成修复步骤。

报错里的锚点是 #migrate-domain-strategy-options。同一标签的 docs/migration.md 里,对应标题写的是 “Migrate outbound domain strategy option to domain resolver”,锚点文本并不相同。内容在那一节,不要因为锚点对不上就认为没有迁移说明。

替换只使用结构体里有的键

迁移节的新例子是:DNS 里有一台 type 为 local、tag 为 local 的服务器;出站删掉 domain_strategy,改成 domain_resolver 对象,server 为 local,strategy 为 prefer_ipv4。

标签 option/outbound.go 里的 _DomainResolveOptions 有这些 JSON 名:server、timeout、strategy、disable_cache、disable_optimistic_cache、rewrite_ttl、client_subnet。strategy 的类型是 DomainStrategy。option/types.go 的反序列化接受空字符串、as_is、prefer_ipv4、prefer_ipv6、ipv4_only、ipv6_only,其它字符串返回 unknown domain strategy。

当天四次 check:

配置退出码原文里可核对的一句
迁移节那种对象,strategy 为 prefer_ipv40无报错
同一对象,strategy 改为 ipv4_only0无报错
strategy 写成 ipv41unknown domain strategy: ipv4
对象里没有 server1empty domain_resolver.server
server 为 local,但没有这个标签的 DNS 服务器1domain resolver not found: local

另外把 not_a_real_field 放进同一个对象,check 仍然是 0。UnmarshalJSON 用的是会忽略未知键的解码。退出码 0 不能证明多写的键会被读到。只保留上面列出的名字。

server 也可以写成字符串,等价于只设置服务器标签。当天 "domain_resolver": "local" 且 DNS 里有这个标签时,退出码是 0。字符串形式没有地方放 strategy。

{
  "dns": {
    "servers": [
      { "type": "local", "tag": "local" }
    ]
  },
  "outbounds": [
    {
      "type": "socks",
      "tag": "proxy",
      "server": "example.org",
      "server_port": 2080,
      "domain_resolver": {
        "server": "local",
        "strategy": "prefer_ipv4"
      }
    }
  ]
}

local 必须是你这份配置里已经存在的 DNS 服务器标签。prefer_ipv4 和 ipv4_only 都通过了检查,本文没有执行 run,所以不写运行时最终选中了哪一个地址。名字如果没有 A 记录,ipv4_only 可能得不到地址;这一点没有在当天做成一次失败的查询。拨号页里 fallback_delay 的 300 毫秒说明写在旧 domain_strategy 下面,没有把同一句写到新字段上,本文也不把 300 毫秒挪过去。

DNS 规则动作上的 strategy 是另一处弃用:1.14.0 弃用,1.16.0 移除,并且不能和 ip_version 写在同一套 DNS 规则里。那是 AI 的 AAAA 一文里的检查。不要把出站 domain_resolver.strategy 和那条规则动作当成同一个键。

它不改网站走哪一族

拨号页的表:direct 出站解析请求里的域名;其它出站解析服务器地址里的域名。上面的 socks 属于后者,所以 example.org 是节点名。把 strategy 写成 ipv4_only,不会让 chatgpt.com 少一条 AAAA。网站名的 AAAA 仍按 那一篇 查。双栈先连谁的概念见 Happy Eyeballs,那一篇没有这份 1.14.4 的字段。

2026-11-08,DiG 9.18.39。example.org 在默认解析器和 @1.1.1.1 上各有两条 A、两条 AAAA,两组字面量相同,AAAA 的顺序不同。各留一条:A 是 172.66.157.237,AAAA 是 2606:4700:10::ac42:9ded。dig +time=3 +tries=1 @1.1.1.1 CH TXT id.server +short 的结果是 "iad14"。这只说明这次查询到达了返回该记号的服务器,不说明大陆网络上的节点域名也会得到同样的答案。地址会变,不要写进规则。

可以照着做的一轮

  1. 对现有配置跑 sing-box check,保存退出码和去掉颜色后的第一句 FATAL。
  2. 若是 legacy domain strategy,删掉出站上的 domain_strategy,按迁移节写成 domain_resolver。不要为了让检查通过去设置那个环境变量。
  3. strategy 只用四个完整取值之一。ipv4 这种省略会被拒绝。
  4. server 的标签必须能在 dns.servers 里找到。
  5. 网站已经返回国家或地区不支持时,停在名单上。这个字段碰不到那一次 HTTP。

公开文件里的法律范围

2026-11-08 请求《关于清理规范互联网网络接入服务市场的通知》的部委网页得到 HTTP 403,正文没有打开。下面沿用该通知(工信部信管函〔2017〕32号)和 2017 年 1 月 24 日答记者问的公开表述:未经批准,不得自行建立或租用专线(含 VPN)等其他信道开展跨境经营活动;答记者问说明,对象是无国际通信业务经营资质而开展跨境电信业务经营的企业或个人,企业办公自用、向依法设置国际通信出入口局的经营者租用,不在该条针对的范围内。本文不判断某种个人使用是否违法,也不写规避执法的做法。

一次检查留下的记录

  1. sing-box version 的版本和修订,以及 check 的退出码。
  2. FATAL 或 WARN 的原文。是旧字段、未知 strategy,还是找不到 DNS 标签,三句不要合成一句。
  3. 出站 type 是不是 direct。不是的话,被解析的是服务器域名。
  4. 若网站已经给出地区英文,另记主机名,不要记进这次 check。