[esp32] Captive Portal

2026 年 8 月 14 日 星期五
/ , ,
41

[esp32] Captive Portal

ESP32 Captive Portal 自动弹出原理

1. 功能概述

手机连接 ESP32 的 SoftAP 后,Android 或 iOS 会自动弹出配网页面。

这个页面并不是 ESP32 主动命令手机打开的,而是手机操作系统检测到当前 Wi-Fi 存在 Captive Portal 后,主动打开系统配网窗口。

当前实现结合了以下三种机制:

  1. DHCP Option 114 声明配网页面地址。
  2. DNS 劫持将所有域名解析到 ESP32。
  3. HTTP Server 将未知路径重定向到配网页面。

2. 手机连接 Wi-Fi 后的行为

手机连接 Wi-Fi 后,通过 DHCP 获取以下网络参数:

  • IP 地址
  • 子网掩码
  • 默认网关
  • DNS Server
  • Captive Portal 地址

ESP32 SoftAP 通常分配:

手机地址:192.168.4.2
网关地址:192.168.4.1
DNS 地址:192.168.4.1

ESP32 还通过 DHCP Option 114 告诉手机:

Captive Portal URL = http://192.168.4.1/

支持 DHCP Option 114 的操作系统可以直接知道配网页面的地址。

3. 操作系统联网检测

手机连接 Wi-Fi 后,会主动访问操作系统预设的 HTTP 地址,判断当前网络是否能够访问互联网。

常见检测地址如下:

Android:
http://connectivitycheck.gstatic.com/generate_204

iOS:
http://captive.apple.com/hotspot-detect.html

Windows:
http://www.msftconnecttest.com/connecttest.txt

操作系统期望收到特定响应:

系统预期响应
AndroidHTTP 204 No Content
iOS包含固定 Success 内容的页面
Windows固定的文本内容

如果收到预期响应,系统认为网络可以正常访问互联网。

如果收到重定向、配网页面或其他内容,系统会认为当前网络需要进行网页登录认证。

4. DNS 劫持

ESP32 在 UDP 53 端口运行 DNS Server。

DNS Server 会将客户端发来的所有 IPv4 A 记录查询都解析为 SoftAP 地址:

任意域名 -> 192.168.4.1

例如手机查询:

connectivitycheck.gstatic.com

ESP32 返回:

connectivitycheck.gstatic.com -> 192.168.4.1

因此手机原本发往互联网的联网检测请求,最终会发送到 ESP32 的 HTTP Server。

5. HTTP 重定向

手机可能访问以下路径:

/generate_204
/hotspot-detect.html
/connecttest.txt

ESP32 当前只提供根路径:

/

当 HTTP Server 收到未注册的路径时,返回:

HTTP/1.1 303 See Other
Location: /

手机随后访问:

http://192.168.4.1/

ESP32 返回完整的配网页面。

6. 完整流程

手机连接 ESP32 SoftAP
        |
        v
通过 DHCP 获取 IP、网关和 DNS
        |
        v
DHCP Option 114 声明配网页面地址
        |
        v
手机发起系统联网检测
        |
        v
查询 connectivitycheck.gstatic.com 等域名
        |
        v
ESP32 DNS 返回 192.168.4.1
        |
        v
联网检测请求到达 ESP32 HTTP Server
        |
        v
未知路径返回 HTTP 303
        |
        v
重定向到根路径 /
        |
        v
ESP32 返回配网页面
        |
        v
系统判断当前 Wi-Fi 存在 Captive Portal
        |
        v
Android/iOS 自动弹出系统配网窗口

7. 各模块职责

DHCP Server

负责向客户端分配网络参数,并通过 Option 114 声明配网页面:

http://192.168.4.1/

Captive DNS Server

监听 UDP 53 端口,将所有 A 记录查询解析为:

192.168.4.1

HTTP Server

负责:

  • 返回配网页面。
  • 处理手机的联网检测请求。
  • 将未知路径重定向到 /。

Android/iOS

负责:

  • 主动检测网络连通性。
  • 判断是否存在 Captive Portal。
  • 打开系统配网窗口。
  • 配网完成后重新检查互联网连接。

8. 为什么使用 HTTP 而不是 HTTPS

Captive Portal 主要依赖 HTTP 联网检测。

如果手机访问:

https://example.com

浏览器要求服务器提供与 example.com 匹配的 TLS 证书。

ESP32 无法提供任意网站的合法证书,因此 HTTPS 请求会产生证书错误,不能透明重定向到配网页面。

因此可以认为:

普通 HTTP 请求可以被引导到配网页面。
HTTPS 请求不能可靠劫持和重定向。

9. 配网页面不一定始终自动弹出

是否自动弹出最终由手机操作系统决定,以下情况可能影响弹窗:

  • 手机启用了 Private DNS、DoH 或 DoT。
  • 手机缓存了之前的 DNS 结果。
  • 手机自动切换到蜂窝网络。
  • 操作系统厂商修改了联网检测机制。
  • 手机已经记住了该 Wi-Fi 的检测结果。
  • 浏览器访问的是 HTTPS 或启用了 HSTS 的网站。

即使系统没有自动弹窗,用户仍然可以手动访问:

http://192.168.4.1/

进入配网页面。

10. 当前实现总结

当前 ESP32 Captive Portal 使用:

SoftAP
+ DHCP Option 114
+ 通配 DNS 解析
+ HTTP 303 重定向
+ HTML 配网页面

其本质是:

ESP32 将手机的联网检测请求引导到本地 HTTP Server,操作系统发现响应不符合互联网连通性检测要求,因此判定该 Wi-Fi 需要认证,并自动打开配网页面。

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...