看到这个标题,估计不少玩ESP的朋友第一反应是:ESP不是做物联网小硬件的吗?Flash才4MB,RAM更是以KB为单位,让它去当DNS服务器,这不是硬凑吗?
先说结论:如果你把“DNS服务器”想象成BIND、PowerDNS那种跑在机房里、每天处理几十亿次解析的服务,那ESP当然不行。但如果你把“DNS服务器”理解成“监听UDP 53端口、收到解析请求后返回一条A记录”,那ESP不仅做得到,而且很多量产智能硬件里早就这么干了。智能插座初次配网时弹出来的配置页面、路由器管理系统里的“强制门户”,核心机制都包含一个微型DNS响应器。
这篇文章我打算把这件事一次讲透:ESP怎么当DNS服务器、业内常说的“DNS劫持”在局域网实验里是怎么实现的、以及Windows在判断“当前网络是否连上互联网”时用的NCSI机制,为什么会被一个几十块钱的板子“骗”过去。整个实验只涉及你自己创建的局域网、自己的AP和受控客户端,目的是理解协议和做开发调试,不是去别人网络里搞破坏。
1. 凭什么说“ESP能当DNS服务器”?先把硬件底子盘清楚
1.1 DNS请求本质上就是几十字节的UDP报文
很多人觉得“DNS服务器”很重,是因为公网DNS需要递归查询、缓存、抗DDoS、支持DNSSEC、处理各种超时和重试逻辑。但在一个局域网或实验性软AP里,DNS负载完全不是同一个量级。
给你算一笔账:一次普通的DNS查询报文,通常不超过100字节,响应也差不多。ESP8266主频80到160MHz,内存虽小但处理一个“查表就回IP”的请求,耗时通常不到几毫秒;ESP32双核240MHz、520KB SRAM,处理这种小报文更轻松。如果你的场景是“家里几十台设备接进来做实验”,一秒十几个DNS请求已经算压力不小,ESP的算力完全顶得住。
真正的瓶颈不在CPU,而在UDP协议栈的处理方式。Arduino框架下的ESP8266默认能同时打开的UDP socket数量很有限,每次收包后要很快处理完,否则下一个包可能被丢弃。所以ESP适合做“低并发、低延迟、高成功率”的轻量DNS响应器,不适合放在高并发公网环境下。
我做过一个简单压测,客户端连续发起几千次查询,ESP8266能稳定响应其中大部分请求,偶发超时主要集中在客户端瞬间并发打出大量请求的时候。这个表现做局域网实验和产品配网Portal完全够用了。
1.2 三种“ESP DNS”形态,你适合做哪种
在开始写代码前,建议先明确你想让ESP扮演什么角色。不同角色对应完全不同代码复杂度:
| 实现形态 | 工作方式 | 内存占用 | 典型场景 |
|---|---|---|---|
| 全量域名吸附型 | 收到任何域名解析请求,全部返回ESP自身IP | 很低 | 配网Portal、强制门户演示 |
| 白名单重定向型 | 命中指定域名时返回自定义IP,其余解析转发到上游DNS | 中 | 内网开发调试、私有域名测试 |
| DNS旁路转发型 | 自己不解析,只把请求原样转发给真实DNS | 低 | 实验性DNS代理 |
这篇文章主要带你落地第一形态,因为它是“NCSI欺骗 + DNS劫持”这个实验最直观的载体。第二种形态适合做内网调试,我会在后面的扩展思路里讲一下,但不会给出完整的生产级实现,因为ESP在一个进程里同时做接收和转发,天然会碰到并发问题,需要额外设计状态管理才能稳定跑起来。
1.3 为什么以前很少有人想到让ESP干这个
一方面是惯性思维。大家提到“DNS服务器”就觉得应该是跑Linux的大型服务,ESP那么小,容易被忽略。另一方面,很多ESP的项目用不到域名解析,只要能控制GPIO、能上报传感器数据就行。
但如果你玩过用ESP做Wi-Fi配网,会发现一个现象:手机连上ESP开的热点后,系统会自动弹出一个网页,或者状态栏显示“需要登录”。这个体验背后的原理,就是一个藏在ESP里的微型DNS服务器,把手机发出的任意域名解析请求全部“吸”到自身,然后提供一个HTTP配置页面。
如果你做完配网功能之后继续往深里问一句:为什么手机连上热点就知道要弹页面?为什么会显示“已连接”而不是“无Internet”?这个问题就会引出一个更深的东西:NCSI。刚好这篇文章就把这块一起讲了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. “DNS劫持”到底在劫什么:局域网域名吸附实验
2.1 先澄清:这里的“劫持”是可控的本地重定向
说到DNS劫持,正经网络安全从业者马上会想到恶意行为:比如在公网链路上篡改DNS响应,把用户访问的域名解析到钓鱼服务器。这种是违法的,也是这篇内容完全不涉及的部分。
局域网开发里还有另一种“DNS劫持”,本质上是可控的域名吸附。客户端向你自己的AP发起域名解析请求,正常情况下它应该去真正的DNS服务器查记录,但在实验网络里,客户端配置的DNS就是ESP本身,ESP可以选择性地回答“你要解析的这个域名地址是192.168.4.1”或者干脆不回消息。
这就像小区门口传达室,物业统一告诉访客:不管你要去哪一栋,先到我这里登记。访客在小区内部体验到的就是“所有地址都要先过传达室”,但如果传达室不放行,访客也去不了真正的目的地。
这里必须说清楚边界:整个实验只允许在你自己的AP、自己连接的设备上做。如果你把设备放到别人网络、公共热点里去做这类测试,或者利用这个机制干扰其他人的上网体验,既不道德也可能违反服务条款甚至法律。动手之前先把这条路封死。
2.2 一个DNS请求从客户端发出后,ESP实际看到了什么
先看一个最简DNS查询的结构。当你在电脑上敲 `nslookup
