Linux 上的 sing-box + eBPF 透明代理实践

这不是只有最终配置的一篇教程,而是 Singborg 整套实验记录的总览:从 daed 时代的 DNS 故障开始,到 sing-box 网络审计、功能验收、eBPF 预检与 A/B 试跑,再到面板、安全配置管线、规则集维护、脚本化运维和最终收尾。

最终状态

截至 2026-10-08 加固验收后:

  • eBPF local.cgroup 接管本机流量
  • shared.packet_rewrite / TCX 接管 virbr0 上的共享流量
  • 国内域名/IP 直连,海外流量进入 Proxy → Auto
  • DNS 53 端口全部劫持
  • 海外 DNS 使用代理侧 DoH,国内 DNS 使用阿里 / 腾讯 DoH
  • DNS 广告拦截使用 predefined + NXDOMAIN
  • 连接层继续使用规则集拦截,覆盖浏览器自带 DoH 等绕过 DNS 劫持的情况
  • 17 份规则集,其中 8 份来自自建 sing-box-rule-sets,通过 /usr/share/sing-box-rule-sets 随包更新
  • 自研 sing-box-panel 提供订阅、节点、分应用策略和安全配置
  • 配置变更统一走 check → 备份 → 原子替换 → 重启 → 健康检查 → 失败回滚

先看哪一篇

如果你第一次看这个项目,推荐按下面的顺序:

  1. 09 踩坑与经验 —— 先知道哪些结论是真的、哪些测试曾经测错
  2. 01 审计报告 —— 看真实流量到底发现了什么
  3. 02 eBPF 可行性验证 —— 决定自己的机器是否值得上 eBPF
  4. 03 面板指南 —— 日常管理配置
  5. 04 功能测试报告 —— 换机器时照着验收
  6. 06 优化评审 —— 想改架构再看取舍
  7. 05 网络审计 —— 对照更早一轮网络体检
  8. 07 daed DNS 故障诊断 与 08 daed 迁移计划 —— 只看历史迁移过程

eBPF 的关键结论

预检 51 项全过,不代表数据面就一定能用。

实际 A/B 试跑才发现:

  • local 的 TC 数据面受当前内核能力限制,不能用
  • shared 的 TCX / packet_rewrite 路径实际可以工作
  • VM / bridge 流量和本机进程的覆盖范围不同
  • rootless Podman 的 pasta 用户态转发不属于 shared bridge 覆盖路径
  • 因此不能简单写成“eBPF 能接管所有容器”,需要按网络路径分别验证

这也是为什么项目保留了独立的 eBPF A/B 试跑套件。

DNS 与广告拦截

DNS 是这套配置最容易出现“看起来正常、实际绕过”的地方。

当前策略是:

53 端口
  ↓
sing-box hijack-dns
  ├─ 国内 → 阿里 / 腾讯 DoH
  └─ 海外 → 代理侧 Cloudflare / Google DoH

广告域名
  ├─ DNS 层 → predefined + NXDOMAIN
  └─ 连接层 → 规则集兜底

之所以不用单纯的 reject,是因为 REFUSED 在当前客户端路径上可能导致解析重试;NXDOMAIN 是正常的“域名不存在”响应,失败速度更快。

规则集与配置

当前配置包含 17 份规则集,来源包括官方 sing-geosite / sing-geoip 数据和自建规则包:

  • anti-AD
  • geoip/cn-fresh
  • cncidr-mihomo
  • must-direct
  • ads-extra
  • adblockfilters
  • geosite/category-ads-all
  • geosite/cn
  • geosite/geolocation-!cn
  • geosite/google
  • geosite/category-ai-!cn
  • geoip/cn
  • geosite/apple@cn
  • Ads_AWAvenue
  • geoip/telegram
  • lyc/cn
  • lyc/geolocation-!cn

完整字段结构、DNS 设计、规则顺序和脱敏配置见 配置与规则集文档。2026-10-08 的审计还核对了控制面独立密钥、CORS 来源限制、备份权限与保留策略、开机网络依赖及脱敏脚本断言,详见 10 月 8 日完整审计报告。

2026-10-08 加固状态

第二轮审计完成后,控制面 clash_api 与 services.api 使用各自独立的随机密钥,CORS 限制到本机面板源;备份目录和文件权限分别收紧为 700/600,并执行保留与归档策略;systemd 增加 network-online.target 依赖。未被引用的 block 出站已清理,下载专用节点也从自动测速候选中剔除。验收报告记录 T1–T6 全部通过;节点失效自动切换与回落 T7 仍标注为待补,不把它写成已通过。

面板与安全配置管线

sing-box-panel 负责订阅、节点、分应用策略等日常操作,但它不是直接“写完 JSON 就重启”。

配置修改统一经过:

check
  ↓
备份当前配置
  ↓
原子替换
  ↓
restart
  ↓
健康检查
  ↓
失败 → 回滚

具体操作见 面板指南。

完整资料

完整项目源代码:emoeem/Singborg。

实践原则:先验证数据面,再决定配置;先验证失败路径,再把它写进自动化脚本。