出口分流
出口分流是整套系统的核心: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 地址由专门的步骤每小时识别并排除。
判断一个域名走哪条路
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 可以把域名从香港名单里摘出来,回到默认路径。
在面板「设置 → 域名规则」里加、删,或者用命令:
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。它的权威在境外,默认走隧道,于是拿到的是香港视角的答案。加进国内解析之后,权威改为直连并带上你的子网,拿到的就是国内视角的地址。
查看现状
sudo dns-stack routing-status面板「设置 → 缓存与数据」可以查看并整表导出直连域名、污染 IP 等分流数据集。
看门狗
dns-stack-routing-watchdog 每分钟检查一次:分流链在不在、策略路由在不在、集合规模是否正常。异常时自动重建,并通过告警通道推送。详见 健康检查与告警。