esp32-c3-adblock 如何切换上游 DNS:一行构建参数换到 1.1.1.1,10 分钟生效
发布时间:2026/11/2 18:42:22 锦皓数字建站

esp32-c3-adblock 如何切换上游 DNS一行构建参数换到 1.1.1.110 分钟生效【免费下载链接】esp32-c3-adblockPi-hole-class DNS ad-blocker on a $2 ESP32-C3 (no PSRAM): 537k domains as 40-bit FNV-1a hashes in flash, binary-searched. UDP DNS sinkhole web dashboard. https://youtube.com/shorts/RaxszOUMi8E?featureshare项目地址: https://gitcode.com/GitHub_Trending/es/esp32-c3-adblockesp32-c3-adblock 是一个 Pi-hole 式的 DNS 广告拦截器一块约 2 美元的 ESP32-C3 小模块把 53.7 万个广告域名以 40 位 FNV-1a 哈希存进 flash查询命中就直接回0.0.0.0掐死。本文只解决一件事——把设备的默认上游解析器Quad99.9.9.9换成 Cloudflare1.1.1.1或其他公共 DNS全程不碰源码。工作量加一行构建参数、烧录一次、两条命令验证大约 10 分钟。在build_flags加一行-DUPSTREAM_IP官方预留的覆盖入口先看默认值写在哪。src/main.cpp 第 24~29 行#ifndef UPSTREAM_IP #define UPSTREAM_IP 9, 9, 9, 9 // Quad9 #endif #ifndef UPSTREAM_PORT #define UPSTREAM_PORT 53 #endif#ifndef的意思是编译时如果已有定义就用你给的值。这就是官方预留的自定义入口只要构建时传了自己的UPSTREAM_IP源码里的 Quad9 自动被跳过一行代码都不用改。打开 platformio.ini在[env:c3]段的build_flags末尾追加一行如果你用的是经典 ESP32 开发板改的是[env:esp32dev]段[env:c3] board esp32-c3-devkitm-1 build_flags -DARDUINO_USB_MODE1 -DARDUINO_USB_CDC_ON_BOOT1 -DUPSTREAM_IP1, 1, 1, 1 ; ← 新增上游改为 Cloudflare 1.1.1.1 ; -DUPSTREAM_PORT5353 ; 仅当上游跑在非标准 53 端口时才放开想切回 Quad9 就把值改回9, 9, 9, 9。保存后选一条烧录路径USB 本地烧录执行pio run -t uploadPlatformIO 会重新编译并把新固件经 USB 写入设备在线 OTA设备已在网内打开 Web 控制台http://c3adblock.local把编译产物.pio/build/c3/firmware.bin传到Firmware → OTA update设备校验通过后自动重启进新镜像也可以在命令行直接推pio run -t upload --upload-port c3adblock.local --upload-protocol espota。小结改动只有一行参数USB 或 OTA 任一方式烧录完成即生效源码原样未动烧完别急着收工下一步用两条命令确认流量真的换了门。两条dig命令验收一条被拦一条放行dig是命令行 DNS 查询工具host表示把这条查询指给指定地址下文c3-ip指 C3 设备在局域网内被路由器分配的 IP可在 Web 控制台或路由器面板看到其 mDNS 域名是c3adblock.local。重新上电后从任意一台能访问 C3 的电脑执行dig c3-ip doubleclick.net # 广告域名应仍返回 0.0.0.0 dig c3-ip github.com # 正常域名应返回新上游解析出的真实 IP两条命令各验一支第一条预期0.0.0.0证明拦截链路不受上游切换影响——广告域名到 C3 就被 sinkhole 掉根本轮不到上游第二条预期真实 IP证明正常查询确实经由新上游1.1.1.1解析并回传了。辅助信号控制台首页的 Total allowed 计数src/page.h 渲染的统计随每条成功转发增长直观说明转发在干活。顺带一提这两条命令在切换之前跑一遍就是定位工具第一条通、第二条超时无应答说明问题出在上游那一支而不是拦截逻辑。小结一拦一放两条命令都符合预期切换就算真正完成至于为什么改上游动不了拦截逻辑回看下面这张数据走向图就明白了。回看数据走向哈希表命中后的两个分支整台 C3 在网里扮演的角色类似守门员每个进来的查询先在门口盘一遍广告域名当场拦下盘不出问题的再交给它请的外援——上游解析器——去跑腿查真实 IP。一条查询的完整路径客户端 DNS 查询 (UDP 53) │ ▼ 提取域名 → 做 FNV-1a 40 位哈希 │ ▼ 在 flash 哈希表中二分查找 │ ├─ 命中 ──▶ 直接回 0.0.0.0sinkhole与上游无关 │ └─ 未命中 ▶ 转发上游解析器默认 9.9.9.9:53 │ ▼ 把答复原样回传客户端Total allowed 1关键就在命中/未命中这个分叉拦截发生在转发之前命中哈希的查询永远到不了上游上游解析器只服务未命中那一支所以换它的地址天然碰不到拦截逻辑。这也是为什么本次改动可以只加一行参数。小结上游只负责没被拦的查询是替换安全度最高的一环那这一环到底该填谁的地址上游选谁Quad9、Google、Cloudflare 一张表对比解析器地址官方定位Quad9本项目默认9.9.9.9安全导向自带已知恶意域名/DGA 拦截Google8.8.8.8全球节点覆盖广延迟普遍较低Cloudflare1.1.1.1主打速度与隐私Cloudflare for Families1.1.1.2在 1.1.1.1 基础上额外过滤成人内容三条选择建议先测延迟在自家网络里对各地址各跑一次dig挑实测快且稳定的理论排名不如实测数看日志政策对照各家的隐私声明确认你能接受查询记录被保留多久、以什么形式保留看附加能力要不要免费搭上的恶意域名拦截Quad9或成人内容过滤1.1.1.2按需取舍。普通家宽到这几家公共解析器都能直连不需要任何端口映射想保留默认 Quad9什么都不用改。小结按三点挑定目标地址后回第一节改那一行参数即可动手前再把下面三个容易混淆的边界划清楚省得改完去排查不相干的故障。三个易混淆的边界拦截列表、配网与应答匹配 上游 ≠ 拦截列表。换上游不会让拦截列表变新。列表更新是另一条独立链路用 tools/build_blocklist.py 把域名源构建成blocklist.bin再经控制台Blocklist → Upload上传或在Remote auto-update里填一个 URL 让设备按设定间隔自动拉取——两条路都和本次改动互不干扰。设备连不上网 ≠ 上游的锅。如果切换后设备直接离线那是配网问题不是 DNS 问题走控制台Forget WiFi或按住 BOOT 键上电重新进入配网引导页详见 README.md 的 WiFi setup 一节。转发有防串包机制。转发函数每次先丢弃积压的过期应答再用全新的随机事务 IDtxid发查询且只接收 txid、问题段、源地址/端口三者都对得上的应答——多客户端并发时不会把 A 的答复错发给 B。这套机制与上游是谁无关换了照样生效。小结列表更新、WiFi 配网、应答匹配三件事各走各的链路排查故障时先分清属于哪一支就能少跑不少弯路。行动清单按上表选定上游地址 → 在platformio.ini的[env:c3]加一行-DUPSTREAM_IP→pio run -t upload或控制台 OTA 上传固件→ 两条dig确认广告域名仍被拦、正常域名走新上游。资源索引src/main.cpp主程序入口UPSTREAM_IP/UPSTREAM_PORT默认值第 24~29 行与上游转发逻辑都在这里platformio.iniPlatformIO 构建配置本文唯一的改动位置src/page.hWeb 控制台页面源码固件 OTA 与拦截列表上传的入口tools/build_blocklist.py拦截列表构建脚本把域名源编译成blocklist.bin哈希表partitions.csv分区表决定固件双 OTA 槽位与拦截列表容量的取舍README.md完整文档含配网引导、OTA 细节与已知坑位。一句话收尾改一行参数、烧一次录、两条dig验证——上游从此由你自己说了算。【免费下载链接】esp32-c3-adblockPi-hole-class DNS ad-blocker on a $2 ESP32-C3 (no PSRAM): 537k domains as 40-bit FNV-1a hashes in flash, binary-searched. UDP DNS sinkhole web dashboard. https://youtube.com/shorts/RaxszOUMi8E?featureshare项目地址: https://gitcode.com/GitHub_Trending/es/esp32-c3-adblock创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。