Skip to content

出口分流 ​

出口分流是整套系统的核心:Unbound 递归时发出的每一个包,按目标权威的位置决定走哪条路。

落地方式 ​

机制作用
nft inet dns_route 的 output 链只匹配 Unbound 进程(按 uid)。目标不在 @direct4、@cn_authority、@tunnel_endpoints 里,就打上 fwmark 0x1d5
ip rule fwmark 0x1d5 lookup 100打了标的包查路由表 100,走 wg0 隧道
ip rule fwmark 0x1d5 prohibit隧道断开时,打了标的包被显式拒绝
postrouting 链出隧道的包做源地址改写

作用范围只有 Unbound 进程,本机其它流量不受影响。

隧道断了宁可失败 ​

默认的故障策略是 closed:隧道断开时境外查询直接失败,不回落直连。回落直连拿到的是被污染的答案——看着成功,实际更危险。

可以在 config.env 里把 TUNNEL_FAIL_MODE 设为 open 换取可用性,代价是隧道断开期间境外解析可能拿到伪造地址。不建议。

两个集合 ​

@direct4:大陆 IPv4 网段 ​

  • 来源是 APNIC 的一手委派记录,用纯真库(qqwry)补充并反向排除,每天重建。
  • 只收全局可路由地址:私有、保留、组播网段一律不进。
  • 安装分流链前会做语义校验:集合不能含非全局网段;本机公网地址必须在集合里;隧道对端(香港)必须不在集合里。任何一条不满足都拒绝安装。
  • 集合条数低于下限时拒绝安装分流链,否则国内递归查询会被全部导进隧道。

@cn_authority:已知的国内权威 ​

「权威含大陆地址」的区域,由流水线从 Unbound 的 infra 记录里学习,每 15 分钟更新:

  • 大陆权威按网段聚合;
  • 境外权威严格按 /32 收录——一些境外 CDN 和国内服务共用 anycast 地址,按网段聚合会误伤;共享 anycast 地址由专门的步骤每小时识别并排除。

判断一个域名走哪条路 ​

bash
sudo dns-stack test www.example.com

输出会逐台列出注册域的权威、它们的地址和判定(在大陆 → 直连 / 属于国内权威 → 直连 / 在境外 → 经隧道),再给出最终答案落在大陆还是境外,以及本机 Unbound 与香港 Unbound 两个视角的 A / AAAA / CNAME / HTTPS 记录。

一次解析里直连和隧道可以交替出现:问根和 .com 的包多半走隧道,问国内 CDN 权威的那一跳走直连。

人工干预 ​

绝大多数情况不需要。国内权威集合每 15 分钟自动学习,一个域名第一次被查询时可能还没被收录,第二次就会纠正。持续不纠正时再人工补,两张名单:

名单文件(/var/lib/dns-stack/)效果适用
国内解析manual-cn-zones.txt它的权威服务器从国内直连查询,并带上客户端子网按来源地区给不同答案、国内能访问却被解析到境外的网站
香港解析manual-gfw.txt整条交给香港 Unbound国内解析结果被污染或不完整的域名

manual-exclude.txt 可以把域名从香港名单里摘出来,回到默认路径。

在面板「设置 → 域名规则」里加、删,或者用命令:

bash
sudo dns-stack route add cn sb.sb        # 加进国内解析
sudo dns-stack route add hk example.com  # 加进香港解析
sudo dns-stack route remove cn sb.sb
sudo dns-stack route                     # 列出两张名单

改完立即生效,不用等定时器:国内解析会马上重算一次国内权威路由和 ECS 白名单,香港解析会让 mosproxy 重载名单;之后清掉这个域名在 Unbound 和 mosproxy 里的旧缓存。加 --no-apply 只改文件。一个域名只能在一张名单里,加进一张会自动从另一张移出。

从国内解析里移出时,出口当场恢复成按权威位置分流;它的权威地址在 ECS 白名单里还会保留最多 3 天,之后自然淘汰——白名单本来就按「连续 3 天没用到才删」累积,避免来回抖动。

几条限制:

  • 只在国内节点上能改,香港节点上执行会被拒绝;
  • 不接受公共后缀(com.cn、github.io 这类)和内网后缀(.lan、.local 等),它们会连带整个后缀下的所有网站;
  • 文件可以手工编辑,说明写成 # 开头的独立行或写在域名后面都行,面板和命令改名单时会原样保留。

生效顺序和 mosproxy 一致:拦截 → manual-exclude.txt → 香港解析 → 默认本机。所以香港名单里有 example.com 时,把 a.example.com 加进国内解析不会生效,要先把它写进 manual-exclude.txt。面板的解析测试和 dns-stack test 显示的都是实际生效的那一条。

在「工具 → 解析测试」或查询详情里,结果下方也有「走国内 / 走香港」按钮,效果相同。

匹配是域匹配:写 example.com 就覆盖 www.example.com 等全部子域。

例子:sb.sb 打开提示「你的地区不能访问」

它按来源地区给不同的地址:从国内问,拿到国内能用的源站;从香港问,拿到 Cloudflare,而 Cloudflare 对你的出口返回 403。它的权威在境外,默认走隧道,于是拿到的是香港视角的答案。加进国内解析之后,权威改为直连并带上你的子网,拿到的就是国内视角的地址。

查看现状 ​

bash
sudo dns-stack routing-status

面板「设置 → 缓存与数据」可以查看并整表导出直连域名、污染 IP 等分流数据集。

看门狗 ​

dns-stack-routing-watchdog 每分钟检查一次:分流链在不在、策略路由在不在、集合规模是否正常。异常时自动重建,并通过告警通道推送。详见 健康检查与告警。

只有两台机器:一台国内,一台香港。