强制门户认证

1,450 阅读18分钟

强制网络门户(captive portal)就是手机在连接上某个WiFi的时候,自动弹出一个页面,这个页面通常可以用来配置网络、验证用户信息等。

一、 强制门户原理

强制门户技术的核心是重定向,重定向的方法有多种,比如基于MAC或IP的重定向、DNS重定向、HTTP重定向、WPAD等等,当然重定向的作用范围远不止强制门户技术。无论是何种重定向,本质上是利用通信协议的机制和规则,实现特定数据流的转发

对于强制门户使用的主要是DNS重定向和HTTP重定向结合的方案,通过DNS重定向,将用户的外网访问请求指定到管理地址,然后HTTP进程接收特定的HTTP请求后,返回特定的HTTP重定向报文,客户端浏览器以重定向报文中指定的URL再次发起请求,以此将用户强制到网关的登陆页面。

image.png

图1 强制门户重定向交互流程

二、 DNS 应用层协议

1. DNS 资源记录****

在介绍DNS层协议之前,先了解一下DNS服务器存储的资源记录( Resource Records RRs ,一条资源记录(RR)记载着一个映射关系。每条RR通常包含如下表所示的一些信息:

表1 RR信息类型

字段****含义****
NAME名字
TYPE类型
CLASS
TTL生存时间
RDLENGTHRDATA所占的字节数
RDATA数据

NAME和RDATA表示的含义根据TYPE的取值不同而不同,常见的:

1)        若TYPE=A,则name是主机名,value是其对应的ip;

2)        若TYPE=NS,则name是一个域,value是一个权威DNS服务器的主机名。该记录表示name域的域名解析将由value主机名对应的DNS服务器来做;

3)        若TYPE=CNAME,则value是别名为name的主机对应的规范主机名;

4)        若TYPE=MX,则value是别名为name的邮件服务器的规范主机名;

5)        ……

TYPE实际上还有其他类型,所有可能的type及其约定的数值表示如下:

表2 TYPE类型以及含义

TYPEvaluemeaning
A1a host address
NS2an authoritative name server
MD3a mail destination (Obsolete - use MX)
MF4a mail forwarder (Obsolete - use MX)
CNAME5the canonical name for an alias
SOA6marks the start of a zone of authority
MB7a mailbox domain name (EXPERIMENTAL)
MG8a mail group member (EXPERIMENTAL)
MR9a mail rename domain name (EXPERIMENTAL)
NULL10a null RR (EXPERIMENTAL)
WKS11a well known service description
PTR12a domain name pointer
HINFO13host information
MINFO14mailbox or mail list information
MX15mail exchange
TXT16text strings

2. DNS 整体说明****

DNS请求与响应的格式是一致的,其整体分为Header、Question、Answer、Authority、Additional5部分,如下图所示:

image.png 图2 DNS协议整体结构

3. Header 部分说明****

Header部分是一定有的,长度固定为12个字节;其余4部分可能有也可能没有,并且长度也不一定,这个在Header部分中有指明。Header的结构如下:

image.png

图3 Header结构

下面说明一下各个字段的含义:

1)        ID:占16位。该值由发出DNS请求的程序生成,DNS服务器在响应时会使用该ID,这样便于请求程序区分不同的DNS响应。

2)        QR:占1位。指示该消息是请求还是响应。0表示请求;1表示响应。

3)        OPCODE:占4位。指示请求的类型,有请求发起者设定,响应消息中复用该值。0表示标准查询;1表示反转查询;2表示服务器状态查询。3~15目前保留,以备将来使用。

4)        AA(Authoritative Answer,权威应答):占1位。表示响应的服务器是否是权威DNS服务器。只在响应消息中有效。

5)        TC(TrunCation,截断):占1位。指示消息是否因为传输大小限制而被截断。

6)        RD(Recursion Desired,期望递归):占1位。该值在请求消息中被设置,响应消息复用该值。如果被设置,表示希望服务器递归查询。但服务器不一定支持递归查询。

7)        RA(Recursion Available,递归可用性):占1位。该值在响应消息中被设置或被清除,以表明服务器是否支持递归查询。

8)        Z:占3位。保留备用。

9)        RCODE(Response code):占4位。该值在响应消息中被设置。取值及含义如下:

Ø  0:No error condition,没有错误条件;

Ø  1:Format error,请求格式有误,服务器无法解析请求;

Ø  2:Server failure,服务器出错。

Ø  3:Name Error,只在权威DNS服务器的响应中有意义,表示请求中的域名不存在。

Ø  4:Not Implemented,服务器不支持该请求类型。

Ø  5:Refused,服务器拒绝执行请求操作。

Ø  6~15:保留备用。

10)    QDCOUNT:占16位(无符号)。指明Question部分的包含的实体数量。

11)    ANCOUNT:占16位(无符号)。指明Answer部分的包含的RR(Resource Record)数量。

12)    NSCOUNT:占16位(无符号)。指明Authority部分的包含的RR(Resource Record)数量。

13)    ARCOUNT:占16位(无符号)。指明Additional部分的包含的RR(Resource Record)数量。

4. Question 部分说明****

Question部分的每一个实体的格式如下图所示:

image.png 图4 Question结构

1)        QNAME:字节数不定,以0x00作为结束符。表示查询的主机名。注意:众所周知,主机名被"."号分割成了多段标签。在QNAME中,每段标签前面加一个数字,表示接下来标签的长度。比如:api.sina.com.cn表示成QNAME时,会在"api"前面加上一个字节0x03,"sina"前面加上一个字节0x04,"com"前面加上一个字节0x03,而"cn"前面加上一个字节0x02;

2)        QTYPE:占2个字节。表示RR类型,见上述RR介绍;

3)        QCLASS:占2个字节。表示RR分类,见上述RR介绍。

5. Answer Authority Additional 部分****

Answer、Authority、Additional部分格式一致,每部分都由若干实体组成,每个实体即为一条RR,之前有过介绍,格式如下图所示:

image.png 图4 Answer&Authority&Additional结构

1)        NAME:长度不定,可能是真正的数据,也有可能是指针(其值表示的是真正的数据在整个数据中的字节索引数),还有可能是二者的混合(以指针结尾)。若是真正的数据,会以0x00结尾;若是指针,指针占2个字节,第一个字节的高2位为11。

2)        TYPE:占2个字节。表示RR的类型,如A、CNAME、NS等,见上述RR介绍;

3)        CLASS:占2个字节。表示RR的分类,见上述RR介绍;

4)        TTL:占4个字节。表示RR生命周期,即RR缓存时长,单位是秒;

5)        RDLENGTH:占2个字节。指定RDATA字段的字节数;

6)        RDATA:即上述介绍的value,含义与TYPE有关,见上述RR介绍。

三、 HTTP 重定向

URL重定向(也称为 URL转发)是一种为页面、表单或者整个Web站点/应用提供多个URL地址的技术。HTTP对此操作有一种特殊类型的响应,称为 HTTP重定向(HTTP redirect)。

1. 方案简述****

在HTTP中,服务器可以通过返回一个重定向响应来进行重定向。这个重定向响应有一个以3开头的状态码,并且有一个 Location 头字段表示要重定向到的位置。

浏览器接收到这个重定向之后,会立即加载 Location中指定的URL。通常这一过程耗时极短,用户基本注意不到这个过程。

重定向过程如下图所示:


image.png 图5 HTTP重定向过程

2. 重定向状态码及含义****

表3 HTTP重定向状态码

状态码****状态短语****状态含义****
300Multiple Choices当请求的URL对应有多个资源时(如同一个HTML的不同语言的版本),返回这个代码时,可以返回一个可选列表,这样用户可以自行选择。通过Location头字段可以自定首选内容。
301Moved Permanetly当前请求的资源已被移除时使用,响应的Location 头字段会提供资源现在的URL。直接使用GET方法发起新情求。
302Found与301类似,但客户端只应该将Location返回的URL当做临时资源来使用,将来请求时,还是用老的URL。直接使用GET方法发起新情求。
303See Other用于在PUT或者POST请求之后进行重定向,这样在结果页就不会再次触发重定向了。
304Not Modified资源未修改,表示本地缓存仍然可用。
305Use Proxy用来表示必须通过一个代理来访问资源,代理的位置有Location头字段给出
306Switch Proxy在最新版的规范中,306状态码已不再被使用。最初是指“后续请求应使用指定的代理”。
307Temporary Redirect与302类似,但是使用原请求方法发起新情求。
308Permanent Redirect与 301 类似,但是使用原请求方法发起新情求。

这9种状态码可以分成3大类,分别是:

Ø  永久重定向:301、308;

Ø  临时重定向:302、303、307

Ø  特殊重定向:300、304、305、306;

对于强制门户,使用一般都为临时重定向,下面进一步说明临时重定向处理方法以及应用场景。

表4 临时重定向使用场景

状态码处理方法典型应用场景
302GET方法不会发生变更。其他方法有可能会变更为GET方法。由于不可预见的原因该页面暂不可用。
303GET方法不会发生变更,其他方法会变更为GET方法(消息主体丢失)。用于PUTPOST请求完成之后重定向,来防止由于页面刷新导致的操作的重复触发。
307方法和消息主体都不发生变化。由于不可预见的原因该页面暂不可用。当站点支持非GET方法的链接或操作的时候,该状态码优于302状态码。

由于我们的状态HTTP服务器仅支持GET方法,所以选用302进行HTTP重定向。

四、 相关案例分析

在了解了上述强制门户的原理以及相关基础后,下面,使用Wireshark抓取路由器强制门户的实际案例。

| (dns || tcp || http) && !tcp.analysis.out_of_order && !tcp.analysis.retransmission && !tcp.analysis.duplicate_ack | | --------------------------------------------------------------------------------------------------------------------- |

其中WireShark过滤规则可以参考如下规则:

1)        dns || tcp || http:

Ø  dns:显示所有DNS协议的数据包。

Ø  tcp:显示所有TCP协议的数据包。

Ø  http:显示所有HTTP协议的数据包。

Ø  逻辑操作符||表示“或”,即只要数据包属于DNS、TCP或HTTP协议之一,就会被显示出来。

2)        !tcp.analysis.out_of_order && !tcp.analysis.retransmission && !tcp.analysis.duplicate_ack :

Ø  tcp.analysis.out_of_order:标识为“TCP out of order”的数据包。这些数据包表示TCP流中的数据包到达顺序与发送顺序不一致。

Ø  tcp.analysis.retransmission:标识为“TCP Retransmission”的数据包。这些数据包表示数据包由于丢失或错误而被重新发送。

Ø  tcp.analysis.duplicate_ack:标识为“TCP Dup ACK”的数据包。这些数据包表示接收方收到了重复的ACK(确认)数据包,通常表示之前的某个数据包没有正确接收。

Ø  !:表示“非”或“排除”,即排除掉上述所有标记的数据包。

1. DNS 解析****

分析其DNS解析部分,可以看到路由器将客户端的DNS请求,解析为了172.31.255.254这个IP地址,后续客户端将使用此IP去打开socket。

image.png 图6 DNS解析报文

2. 建立 TCP 连接并且进行 HTTP 重定向****

image.png 图7 HTTP重定向报文

1)        建立TCP连接

在通过DNS获取到目标IP(172.31.255.254)后,客户端将与目标IP建立TCP连接,其端口为HTTP的默认端口:80;

2)        HTTP请求以及重定向

建立TCP连接后,客户端请求HTTP服务,服务使用307将HTTP请求进行重定向到http://192.168.8.1/html/index.html?origin=xxx,此url为路由器的管理网站;

3)        关闭TCP连接

因为重定向后的IP(192.168.1.1)与DNS解析的IP(172.31.255.254)不一致,所以客户端断开TCP连接。随后,客户端将使用重定向后的IP重新建立TCP连接;

3. 登录管理页面****


image.png 图8 登录管理界面报文

1)        建立TCP连接

客户端将与重定向后的IP(192.168.1.1)建立TCP连接,其端口为HTTP的默认端口:80;

2)        HTTP请求与回复

建立TCP连接后,客户端使用重定向的url(/html/index.html?origin=xxx)发起HTTP请求,服务端回复管理页面的html文件;

至此,客户端WEB已成功打开管理页面,强制门户认证过程完成。

4. 对比 ESP32 门户网站案例****

在分析完路由器的案例后,又抓取了ESP32门户网站的相关报文。

发现两者之间存在以下差异点:

1)        对于DNS请求的处理不同

Ø  路由器将客户端所有的DNS请求统一定向到172.31.255.254;

image.png 图9 路由器DNS请求与回复

Ø  ESP32仅对部分域名(type A)的DNS请求返回了IP(192.168.4.1),但是对其余的DNS请求,进行了特殊的回复(Unused);

image.png 图10 ESP32DNS请求与回复

其特殊回复实现主要是将 Type 值设置为了 0 ,如下图所示:**

image.png 图10 ESP32回复Unused

查看 DNS 的标准规范DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION并未找到对 Type 值为 0 的明确定义,但在 DNS 的相关规范中Domain Name System (DNS) IANA Considerations找到了如下说明:**

说明了 RRTYPE 值为 0 的特殊用途,即在某些特定的情况下(例如 SIG(0) 记录中)使用,而不应用于普通的 DNS 查询。虽未并未明确说明 Type0 可以在用于这种情况,但在此暂且进行深究,若有兴趣可以继续研读相关规范。**

image.png 图11 对于Type0的相关说明

 

2)        HTTP重定向状态码不同

image.png 图12 HTTP重定位内容对比

Ø  路由器使用307进行重定向回复

Ø  ESP32使用302进行重定向回复

参照上述表4对于状态码的描述,可以看到,ESP32重定位后仅支持GET方法,而路由器重定位后所支持更多的请求方法。

3)        HTTP重定位内容差异

Ø  路由器重定位时,不仅指定新资源的url:/html/index.html?origin=xxx,同时,指定了新资源的IP地址: 192.168.8.1;

Ø  ESP32重定位时,仅指定新资源的url:/;

路由器将所有客户端的DNS请求解析到一个特定的IP地址(172.31.255.254),这是一个中间服务器,此IP不是真正的目标网站,而是一个内部IP,路由器用它来捕获所有的流量。但是,此操作需要多打开一个TCP服务器,对于资源要求较高。

5. 正常 WiFi 测试****

image.png

图13 WIFI测试****

1)        DNS请求

Ø  系统首先会进行 DNS 查询,解析 www.msftconnecttest.com 这个域名。由于该域名是一个 CNAME 记录,实际解析指向的是 ncsi-geo.trafficmanager.net

Ø   系统通过 DNS 查询获得 ncsi-geo.trafficmanager.net 的 IP 地址

2)        HTTP 请求

Ø  -在成功解析到 IP 地址后,系统会尝试通过 HTTP 协议访问 [http://www.msftconnecttest.com/connecttest.txt](www.msftconnecttest.com/connecttest…

Ø  这是一个简单的 HTTP GET 请求,没有复杂的参数或数据发送。请求的目标是获取一个预定义的静态文件。

3)        接收响应

Ø   如果请求成功,服务器会返回一个 HTTP 200 OK 的状态码以及一个包含预期文本内容的响应体,通常这个文件内容是 Microsoft Connect Test

Ø  如果能够成功接收到这个内容,系统就会判断当前网络连接能够访问互联网,并在网络状态图标上显示“已连接互联网”。

五、 方案确定

1. 方案总述****

基于上述分析,确定最终的门户认证方案,其流程如下:

image.png 图13 强制门户流程

Ø  因资源限制,只能开启一个TCP服务器,所以在域名解析时仅将部分域名直接解析为最终的IP(192.168.1.1),并且,对其余的DNS请求,进行特殊回复(Unused);

Ø  因仅支持GET请求,所以HTTP重定义时使用302进行回复;

2. 疑问点分析****

若要按照上述步骤实施,要解决下面两个问题:

Q1:DNS解析时,将哪些域名解析为:192.168.1.1?

A1:在案例分析中看到路由器对所有的DNS请求都进行解析,而ESP32仅正常解析Type A记录查询,也可以实现强制门户,这是因为Type A应用于网站访问。那么,域名解析的范围是否可以进一步缩小呢?

市场上的各类设备通常会访问特定域名,用于检测互联网连接状态,为了确保强制门户跳转(Captive Portal)能够在常见的设备上生效,就需要穷举出这些域名:

表5 各设备域名表

设备类型****域名****
Windows设备www.msftconnecttest.comconnectivitycheck.gstatic.com
联想设备connectivitycheck.lenovo.com
苹果设备captive.apple.comwww.apple.com/library/test/success.htmlwww.apple.com
安卓设备connectivitycheck.android.comclients3.google.com/generate_204
鸿蒙设备connectivitycheck.hicloud.com
华为设备connectivitycheck.platform.hicloud.com
小米设备www.miui.com/generate_20…
Vivo设备devel.vivo.com.cn/generate_204
三星设备config.samsungcloudsolution.com/generate_204
OPPO设备connectivitycheck.oppo.com
一加设备connectivitycheck.oneplus.net
索尼设备connectivitycheck.sonymobile.com

归纳一下上述表格,得到以下通用字段:

msftconnecttest、connectivitycheck、generate_204、apple

经过上述分析,确定正常解析的域名需同时满足以下两个条件:

ü  条件一:DNS查询类型为Type A;

ü  条件二:域名中包含通用字段;

*注意:虽然上述的字段可以包含市面常见设备,但无法保证对支持所有设备,在资源足够的情况下,不建议使用条件二进行过滤!

Q2:若TCP服务器只能打开1个socket,如何保证跳转成功率?

A2:首先分析路由器和ESP32的相关报文:

Ø  在成功跳转到ESP32门户网站前,设备依然保持其余3个socket连接,总共耗费了4个socket资源,才成功跳转到了门户网站;

image.png 图14 路由器socket连接状态

Ø  在成功跳转到ESP32门户网站前,设备依然保持其余2个socket连接,总共耗费了3个socket资源,才成功跳转到了门户网站。

虽然从表现上ESP32相对路由器少消耗1个socket资源,但是,深入分析发现,这只是因为设备DNS请求的顺序不一致导致的,因此,其现象不存在必然性。

image.png 图14 ESP32 socket连接状态

按照上面分析,要成功跳转到门户网站一般需要3-4个socket资源,但因设备资源限制(共5个socket资源,其余4个socket用作它用),仅有1个socket资源用于门户网站,所以,必须通过优化相关过程,才能实现强制门户跳转。

按照上面分析,主要可以从下面两方面进行流程优化:

优化一:提高 Socket 资源准确性****

1)        如上面A1所述,通过增加DNS解析条件,使Socket资源更精确地用于门户网站,从而提升Socket资源的使用准确性。

优化二:提高 Socket 资源使用率****

1)        缩短重定向后资源的有效时长:

u  DNS重定向:当通过DNS解析将请求重定向至强制门户时,将重定向后资源的有效时长设定为5秒。这意味着在DNS缓存或TTL过期后,客户端将再次进行DNS查询,有助于快速恢复正常的网络访问。

u  HTTP重定向:在需要重定向至门户页面时,使用HTTP状态码302(临时重定向),指示客户端临时访问强制门户。

2)        服务器主动关闭非门户网站连接:

u  在检测到Socket连接未成功打开门户网站后,服务器将主动关闭该连接。这种措施有助于释放无效的Socket资源,避免长时间占用资源而导致其他用户无法访问门户页面。

u  通过监控Socket连接的状态和活动情况,服务器可以判断哪些连接未正确访问门户,并及时进行处理,以优化资源利用率。

这些优化措施旨在确保Socket资源被准确、高效地使用,从而提升强制门户方案的整体性能和用户体验。

3. 最终方案****

image.png 图15 强制门户最终流程

最终强制门户认证的最终方案如上图所示。

六、 方案验证

下面为照此方案具体实现后的报文。

image.png

image.png 图16 方案实现的DNS解析报文

七、 改进与优化

按照上述方案实施后,虽然大大提高了跳转成功率,但对有些设备(Vivo手机)成功跳转的概率依然较低,其主要原因还是因为socket资源较少,并且经过测试,若将socket资源提高到3个,将基本市面上所有设备。

所以,在socket资源充足的情况下,建议多开几个socket资源,以提高使用体验。