最后验证:2026-10-02T15:08:46Z

sing-box 网络全面审计报告

审计时间:2026-10-01 20:5x 对象:正在运行的 sing-box 1.14.2(TUN stack: system,规则集全本地化)
方法:全部为真实流量实测(dig / curl / ss / ip / podman 容器),非推断。

追注(2026-10-02 晚):本文审计在 TUN 模式下完成,属当时快照。当前模式已是 eBPF
(local: cgroup + shared: packet_rewrite on virbr0,TCX 挂载),本机没有 tun0,
所以下文所有 tun0/TUN 地址/MTU 类证据只描述当时状态;逐条复测见”结论速览”后的追注与各节追注。

结论速览

检查项 结果
daed 残留 ⚠️ dae0 设备与 tc 钩子已清,但 daens netns 仍在 → 已加入脚本自动清理
遗留系统代理 ✅ 干净(gsettings mode=none,无 *_proxy 环境变量)
DNS 劫持完整性 ✅ UDP 与 TCP 都被劫持
IPv6 处理 ❌ TUN 无 v6 地址 → 所有 IPv6 被黑洞,v6-only 站点不可达 → 已修
IPv6 泄露 ✅ 无泄露(宁可不可达,也不绕过代理)
局域网 ✅ 路由器 / 本机 / libvirt 网关都通,strict_route 没吃掉 LAN
私有反查 ✅ dig -x 192.168.31.1 → XiaoQiang.(resolved 按链路送到路由器)
NTP / 时钟 ✅ systemd-timesyncd active,System clock synchronized: yes
并发稳定性 ✅ 20 个并发请求 20/20 成功
大文件传输 ✅ 10 MB 完整下载无中断(1.68 MB/s,proof.ovh.net)
MSS / MTU ✅ TUN 侧 8948、远端 1400/1489 协商,由 sing-box 正确处理,重传率 0.27%
SOCKS5 ✅ curl --socks5-hostname 127.0.0.1:7892 可用
应用自带 DoH ✅ curl --doh-url https://dns.google/dns-query → 200
Podman ✅ 出口=代理 IP、国内=直连、DNS 经 pasta→宿主→劫持、端口发布正常(本节是 TUN 模式下的审计;eBPF 模式下这条不成立,见 docs/09 §6)
订阅节点质量 ⚠️ 存在失效节点(5s i/o timeout),urltest 会自动绕开

逐条复测(2026-10-02 晚,eBPF 模式)

检查项 TUN 时代结论 eBPF 模式现状
daed 残留 ⚠️ daens netns 仍在 ✅ 已清理:ip netns list 输出为空、dae0 不存在、tc filter show dev wlan0 ingress 无输出
遗留系统代理 ✅ 干净 ✅ 仍干净:gsettings get org.gnome.system.proxy mode → 'none',无 *_proxy 环境变量
IPv6 处理 ❌ TUN 无 v6 地址 → 全部黑洞 ✅ 已可用:ip -6 rule 只有 local/main(无 9000: from all unreachable)、eBPF 入站 ipv6: true、curl -6 https://ipv6.google.com → 200
DNS 劫持完整性 ✅ UDP 与 TCP 都被劫持 ✅ 仍成立,改由 eBPF local cgroup 数据面完成:dig +tcp doubleclick.net @192.168.31.1 → 空、dig +tcp www.google.com @192.168.31.1 → 真实 Google IP
私有反查 ✅ dig -x 192.168.31.1 → XiaoQiang. ⚠️ 现在返回 _gateway.(路由器 PTR 变了),链路仍正常
局域网 ✅ 都通 ✅ ping -c2 192.168.31.1 → 2/2,0% loss
NTP / 时钟 ✅ ✅ systemd-timesyncd active、System clock synchronized: yes
MSS / MTU ✅ TUN 侧 8948 ➖ 不适用:没有 TUN 设备,MTU 不再是 TUN 的事
运行配置 旧版(第 12/13 项未应用) 已是最新:DNS 广告顺序修复、IPv6、MetaCubeXD 摘除都已落地;当前 15 份规则集全 local
系统 DNS resolvectl → tun0(172.19.0.2) resolvectl → wlan0(fd00:6868:6868::1 / 192.168.31.1),但查询仍被劫持(见第 4 条的追注)

Bug 1:daens 网络命名空间残留

$ ip netns list
daens (id: 0)          ← 残留
$ ip -brief link show dae0
(已不存在)✅
$ tc filter show dev wlan0 ingress | grep daed
(无)✅
  • 影响:一个空 netns,几乎无害;但说明当初 daed 并未干净卸载,若以后有程序误用该 netns 会出怪问题。
  • 修复:部署脚本新增 1b/6 清理 dae 残留 步骤(ip netns delete daens,并顺带复查 dae0 与 tc 钩子)。

Bug 2:IPv6 在 TUN 模式下完全不可用(结构性)

根因:TUN 只配了 172.19.0.1/30(无 v6 地址),于是 sing-box 装了这条规则主动黑洞全部 v6:

$ ip -6 rule show
9000:   from all unreachable      ← sing-box 的防泄露黑洞

这是 sing-box 的有意设计(没有 v6 出口就别让 v6 偷偷绕出去),所以不会泄露;代价是 v6 目标一律不可达。

实测证据(ipv6.google.com 是 AAAA-only:2404:6800:400b:c00e::8b):

访问方式 结果
TUN 模式直连 ❌ 000(失败)
经本地代理口 127.0.0.1:7892 ✅ 200

→ 你的代理节点本身能到 IPv6,只是客户端用不上。任何 AAAA-only 的站点(部分 Google 服务、v6-only CDN/自建服务)在 TUN 模式下都打不开。

修复:给 TUN 加上 v6 地址(已写入待部署配置并 check 通过):

"inbounds": [{ "type": "tun", "address": ["172.19.0.1/30", "fdfe:dcba:9876::1/126"], ... }]

修复后:v6 流量同样进入 TUN → 经代理出去;ip_is_private 规则保证 LAN 的 ULA v6 仍直连;
strict_route: true 继续防止绕过。

追注(2026-10-02 晚,eBPF 模式):本节只描述 TUN 模式,上面的 TUN v6 地址修法仅作历史记录。
切到 eBPF 后不存在 v6 黑洞:ip -6 rule show 只有 local/main 两张表(没有 unreachable 规则),
curl -6 https://ipv6.google.com 实测 200;国内回显也已经是电信 IPv6 地址。

应用后请这样验证:

curl -6 -s -o /dev/null -w '%{http_code}\n' https://ipv6.google.com   # 期望 200(现在是 000)
ip -6 rule show | grep -c unreachable                                  # 期望 0

若你不想要 v6(例如担心某些应用优先走 v6 变慢),把这行 "fdfe:dcba:9876::1/126" 删掉即可回到现在的
“v6 不可达但绝不泄露” 状态。两种都安全。

次要观察

  1. 订阅里有失效节点:日志反复出现
    connection upload handshake: dial tcp <node-server-ip>:<node-server-port>: i/o timeout(5 秒超时)。
    该节点已死。urltest 会自动切走,但探测/回退时会带来偶发 5 秒卡顿。
    已优化:Auto 的 interval 已从 10m 收紧到 5m(死节点最迟 5 分钟被换掉);
    另新增地区级 urltest(Auto-Japan / Auto-HongKong / Auto-Singapore)。
    (IP 已脱敏:它是订阅节点的 server 地址;端口与 🇭🇰 香港Z02 | IEPL 的 server_port 一致,
    但节点域名与解析结果都可能变,别把 IP 当身份。)

    追注(2026-10-02 晚):interval: 5m 确实已生效(Auto/Auto-Japan/Auto-HongKong/Auto-Singapore 都是 5m ✓)。
    最近日志里的失效节点换成了 🇯🇵 日本Z05 | 下载专用(connection refused,同样已脱敏)。
    失效节点会持续更替,不要把某个具体 IP 当结论。

  2. 一个国内直连目标超时:182.140.248.155:443(无 PTR、直连也 000)→ 目标本身不可达,
    很可能是某个广告/追踪域名解析到的死 IP,不是配置问题。
  3. 运行中的配置仍是旧版(20:31 部署):所以现在还不包含
    DNS 广告拦截顺序修复(第 12 项)、MetaCubeXD 面板(第 11 项)、IPv6 修复(第 13 项)。

    追注(2026-10-02 晚):这条已过期 —— 配置早已更新,上述三项都已落地(其中 MetaCubeXD 反过来是被摘除),
    运行模式也从 TUN 换成了 eBPF。

  4. resolvectl 显示 tun0 已成为系统当前 DNS(172.19.0.2,DNS Domain: ~.)→ 系统解析直连 sing-box ✅。

    追注(2026-10-02 晚,eBPF 模式):现在 resolvectl 指向 wlan0(DNS fd00:6868:6868::1、192.168.31.1),
    没有 tun0。系统解析器虽然直连路由器,但它的 53 查询在 eBPF local cgroup 层被劫持
    (dig www.google.com 返回真实 Google IP、dig random-zzq.doubleclick.net → NXDOMAIN),
    所以”系统解析实际走 sing-box”这个结论仍然成立。

待执行

cd ~/Documents/deepseek-harness/default-workspace
sudo ./switch-to-local-rules.sh --dry-run   # 共 13 项 + dae 残留清理
sudo ./switch-to-local-rules.sh

追注(2026-10-02 晚):这份”待执行”已完成(12/13 项都已应用),切模式脚本现在是
scripts/switch-to-ebpf.sh / scripts/switch-to-tun.sh;switch-to-local-rules.sh 只作历史留档。

应用后再跑一次这份审计里的关键三条:

curl -6 -s -o /dev/null -w '%{http_code}\n' https://ipv6.google.com   # 期望 200
dig +short doubleclick.net                                            # 期望 空
curl -s https://myip.ipip.net                                         # 期望 你的电信 IP