M-Abozaid/esp32-c3-adblock
运维与部署在一块约 2 美元的 ESP32-C3 上实现 DNS 广告拦截:把域名哈希存进 flash 并二分查找,适合想用极低成本做家庭网络过滤的人。
用 2 美元开发板做 DNS 广告拦截
项目在无需 PSRAM 的 ESP32-C3 上运行一套类似 Pi-hole 的 DNS sinkhole。它不把拦截域名的字符串放进 RAM,而是把每个域名存成排好序的 40 位 FNV-1a 哈希放入 flash,查询时对这张表做二分查找:命中就返回 0.0.0.0,未命中就转发给上游解析器并回传结果。按 README 的说法,约 14 万个域名占用约 0.7 MB flash,匹配耗时约 10 ms,内存占用约 50 KB;537k 域名的大列表也能放下,但预计会有约 1 次哈希碰撞。
它面向希望在家庭网络里做 DNS 过滤、又不想投入太多硬件的人,例如把 C3 SuperMini 插进路由器的空闲 USB 口。其他功能包括带每个客户端统计的 Web 面板、封禁客户端、自定义拦截域名、通过 c3adblock.local 做 mDNS 发现、固件与拦截列表的 OTA 更新,以及配网门户。
快速使用
准备一块 4 MB flash 的 ESP32-C3 板(不需要 PSRAM)、稳定的 USB 供电,以及较新的 PlatformIO。发行版/apt 里的 platformio 版本过旧会报错,请使用当前 VS Code 扩展自带的核心,或在虚拟环境里执行 pip install -U platformio。
- 复制密钥模板并编辑:
cp src/secrets.example.h src/secrets.h。WEB_USER、WEB_PASS和OTA_PASS必须设置,它们保护面板上会改变状态的接口和网络 OTA;WIFI_SSID和WIFI_PASS可选,保留占位符即可改用设备上的配网门户。 - 生成拦截列表哈希表:
python3 tools/build_blocklist.py data/blocklist.bin。默认来源是 StevenBlack 基础列表加 Hagezi Light,约 10 万条。也可以额外传入 URL 和本地文件,支持 hosts 文件、纯域名列表和基础 AdGuard/Adblock 规则。 - 烧录固件和文件系统:先
pio run -t upload,再pio run -t uploadfs。这是唯一一次 USB 烧录。 - 用
pio device monitor查看启动日志、记下 IP,然后访问http://c3adblock.local打开面板。
如果没填 WiFi 或连接失败,设备会开启名为 C3-AdBlock-XXXX 的开放热点和配网页面。用手机连上,选择网络并输入密码即可。之后想换网络,可以在面板点 Forget WiFi,或按住 BOOT 键上电让配网页面重新出现。
使用时,把某个设备的 DNS 指向 C3 的 IP,或把它作为主 DNS 之后的辅助解析器。验证方式:
dig @<c3-ip> doubleclick.net # -> 0.0.0.0 (被拦截)
dig @<c3-ip> github.com # -> 真实 IP (被转发)
更新方式
首次烧录之后,拦截列表和固件都可以通过 WiFi 从面板更新。可以上传新生成的 blocklist.bin,也可以设置一个远程 URL 让设备按计划拉取预构建列表,或上传 .pio/build/c3/firmware.bin 做 OTA。GitHub Actions 每周一重建默认列表并发布到固定的 release 地址。命令行 OTA 可用 pio run -t upload --upload-port c3adblock.local --upload-protocol espota,需要 OTA_PASS。
使用约束
- Flash 预算: 固件 OTA 需要两个 app 分区,只剩约 1.3 MB 给拦截列表,最多约 25 万域名。537k 的“终极”列表只能配合单 app 分区表使用,此时无法做固件 OTA。分区方案在
partitions.csv中调整。 - 板卡支持: C3 SuperMini 是测试过的目标。经典 ESP32 DevKit/WROOM 可用
pio run -e esp32dev -t upload构建,但属于社区贡献、只做过编译测试。 - 安全边界: 面板是 80 端口的明文 HTTP,Basic Auth 凭据只是 base64 编码而非加密。会改变状态的接口还要求携带
X-Requested-With: c3-adblock请求头,以阻止跨站表单/图片请求。如果secrets.h仍使用公开的占位密码,设备会打印警告并在面板显示横幅,但仍然会启动,因此在不可完全信任的网络上使用前务必改成真实密码。配网热点在设置期间按设计是开放且不加密的。 - 列表表达能力: 正则、通配符、
$修饰符和 cosmetic##规则会被跳过并计数。@@允许规则只能移除某一条精确条目,无法从被拦截的父域名下单独放行子域名。 - Linux 串口: Fedora/Ubuntu 上的 ModemManager 可能占用
/dev/ttyACM0并复位 C3。停用 ModemManager 并为厂商 ID303a添加 udev 规则即可解决。 - 天线与供电: README 提醒廉价的 USB-C 转 A 转接头可能导致射频发射时掉电,打印外壳时也应让天线一端保持空旷。
HotRepo 点评
在 2026-11-01 的 C++ 月榜记录中,项目当月新增 2,789 Star,最好名次为第 15。更早的 2026-10-06 日榜记录显示 1,614 Star、当日新增 196。它还在 2026-10-07 引出一个 195 分、82 条评论的 Hacker News 讨论。讨论中最实质的技术质疑集中在哈希碰撞:评论者认为 README 把碰撞描述成“两个被拦截域名同哈希”,但真正的风险是误报,即一个正常域名与被拦截域名哈希相同(muti、zamadatix)。这一点值得留意,因为设备处在所有 DNS 查询的路径上,一次不巧的碰撞就可能误伤正常网站,直到通过面板或接口手动放行。其余讨论多集中在硬件选择上,例如部分 C3 板载天线较弱,这更多影响设备摆位而非核心设计。
本文由 AI 根据项目 README 生成,更新于 ,以项目官方文档为准。