项目概览
pcdn-detector 是面向家庭网络的 PCDN 检测与阻断工具,用于在 OpenWrt / Linux 路由器上识别局域网内的 P2P CDN(PCDN)行为,并可自动阻断。它不是流量整形工具,也不看具体应用协议,只用一条统计特征判断:
某台设备在指定时长内,通过同一个本地端口连接了超过阈值数量的不同远端公网 IP。
这条特征对 PCDN 非常有效——正常客户端即便并发很高,也很少在单个端口上连出几十个互不相关的 公网 IP;而 PCDN 节点为了就近回源,恰恰就是这么做的。
| 仓库 | 角色 | 语言 / 运行时 | 说明 |
|---|---|---|---|
pcdn-detector |
检测内核(Go) | Go 1.27.3+,纯 Go、无 CGO | 交叉编译静态二进制;AF_PACKET + TPACKET_V3 |
pcdn-detector-c |
检测内核(C 移植) | C23,pthread | 无 GC、体积更小;AF_PACKET + TPACKET_V2 |
luci-app-pcdn-detector |
LuCI 管理面板 | Lua / LuCI | 仅前端,不含检测二进制 |
三者共同组成一个完整方案:内核做检测与封禁,面板做配置与观测。两个内核的功能、配置格式、 命令行参数、HTTP API、状态文件格式与发布产物命名保持一致,可以互相替换。
- 加载配置:读取 TOML 配置,命令行参数覆盖同名项。
- 抓包:在指定网卡上用
AF_PACKET抓包,socket 挂内核层经典 BPF 过滤器,默认只放行 UDP, ARP / STP / ICMP 等无关报文在进入用户态前就被丢弃。 - 统计:解析以太网、IPv4 / IPv6(含扩展头)、TCP / UDP 头部,按
设备 MAC + 本地端口 + 协议统计滑动窗口内不同远端公网 IP 的数量。 - 告警:数量达到阈值输出「疑似产生PCDN行为」;随后进入持续期,期间只要该端口仍有流量 就刷新计时器,出现新对端时额外输出「持续产生PCDN行为」;持续期内无任何流量则输出 「PCDN行为结束」。
- 过滤:若配置了黑白名单,按设备 MAC(可再限定端口)决定「检测谁」或「不检测谁」。
- 联动封禁:首次告警即封禁该设备在该端口上的流量,行为结束时解封;可叠加全 UDP 端口封禁。
- UPnP 拦截:可选,拦截设备发往路由器的 SSDP / HTTP 控制请求,阻止其自动打洞。
| 能力 | 说明 |
|---|---|
| 单端口多对端检测 | 核心判定逻辑,阈值与窗口可调 |
| 三段式告警生命周期 | 疑似 → 持续 → 结束,可重复触发 |
| IPv6 完整支持 | 解析并跳过各类扩展头;按「端口 + 地址族」分别统计 |
| 黑白名单 | 按 MAC 过滤,可限定端口,支持临时停用单条 |
| 防火墙联动 | hook / iptables / nftables 三种后端,自动封禁与兜底解封 |
| 全 UDP 端口封禁 | 多端口被封后升级为设备级全封禁,仅放行常用端口 |
| UPnP 拦截 | 随名单方向决定拦截范围,与封禁共用防火墙后端 |
| HTTP API | 状态读取、设备与端口明细、手动解封、热重载 |
| 热重载 | SIGHUP 恒定可用;HTTP 开启后可用 POST /api/v1/reload |
| 状态继承 | 兜底重启时通过二进制状态文件继承告警与封禁(PCST v1) |
| 低内存适配 | 抓包缓冲、snaplen、对端上限、端口上限、低内存模式 |
| 隐私模式 | 日志中隐藏设备自身 MAC / IPv6 / 公网 IPv4 |
| LuCI 面板 | 状态、TOML 全文编辑、在线校验、日志、二进制下载与回滚 |
- 不解析应用层协议:判定只看连接行为,不区分 BitTorrent、网盘或 PCDN 厂商。
- 不做限速 / QoS:只有「放行」与「丢弃」。
- 不提供 HTTPS:HTTP API 仅明文,需要加密请在前置反向代理终结 TLS。
- 不保证零误报:阈值需要按实际网络规模调整,见检测与抓包。
三个仓库均为 GPL-3.0。贡献需先阅读各仓库的 CONTRIBUTING.md,PR 视为同意 CLA.md,
且每个提交需要 Signed-off-by 签署行(git commit -s)。
C 版内嵌第三方库的许可证:tomlc99 / cJSON 为 MIT,picohttpparser 为 MIT / Perl,uthash 为 BSD-1-Clause。