庖丁开坛——细数无线Portal通关的心经暗语
庖丁开坛:
话说神厨丁赴文惠君府上一展屠牛神技之后,天下称奇,更有愿千斤学一技者不在少数,其中不乏如IT攻城狮之流。于是庖丁开坛授技,日复一日屠牛献艺。然观者只得见其手起刀落、筋断骨脱,却不得其中奥秘,哪里有关节?哪里有经络?从哪里下刀?使多大劲?庖丁解牛者宜观而不易学。讲学十载,解牛之最高境界——“目无全牛”——入者寥寥。庖丁心忧百年之后,神技失传,于是著书绘技,著成《解牛心经》,以通解牛之心经暗语。千年之后,《解牛心经》流入IT界,H3C小L得其精要,再撰文八十八篇传于世。常言:“解网络故障者如解牛也,得心经一篇,便可如臂使指,游刃有余”。是妄言?是真话?边看边评。
一、 识牛之Portal流程概要:
图1
无线Portal属于工作在IP网络层上的安全认证协议。涉及的网络单元从逻辑上分为四个:认证终端(手机)、认证点(AC)、Portal服务器、Radius服务器。用户认证上线的业务流程上,主要分为五个环节:
(1)终端关联WLAN网络,获取IP地址、DNS等信息;
(2)终端向任意目标IP发起HTTP连接请求,被AC截获,AC仿冒目标IP与终端建立HTTP连接,完成重定向;
(3)终端按照重定向的目标url(指向Portal认证页面),和Portal服务器建立HTTP连接,用户在WEB页面上输入用户名/密码上传到Portal服务器;
(4)Portal服务器向AC发起Portal认证,开始Portal协议交互;
(5)AC向Radius服务器完成AAA校验,校验成功后AC放行用户,用户可以正常访问网络,后续是计费过程。
分析:实际上在用户打开Portal认证页面并在登录对话框输入用户名、密码时,Portal协议交互还并没有开始,直到用户点击认证页面的“登录”按钮,Portal服务器向AC发送UDP2000认证报文时,才算真正“Portal协议交互”开始。也即Portal协议在整个Portal认证过程中只是环节之一,全流程的协议交互概略图如下:
图2
二、 解牛之Portal画骨描经:
1、Portal重定向
也许称之Portal重定向并不完全准确。事实上,重定向与Portal协议本身没有任何关系,它只不过是HTTP协议的功能,准确的名称应该叫HTTP重定向。但是Portal认证流程中少不了这个环节,因为它提供了面向终端用户的入口。有了它,Wifi网络的使用者并不需要提前知道网络中有没有Portal服务器,以及Portal服务器在哪,用户只需要像平常使用浏览器上网一样,随便访问一个网站链接,浏览器便可自动获取Portal服务器的认证url并打开Portal认证页面,这个过程都是在后台自动完成的。
(1)设备debug分析
在AC上开启debug开关:debugging portal tcp-cheat
*Apr 18 15:01:41:519 2014 AC TCPCHEAT/7/TCPCHEAT_DEBUG: Source MAC = 0024-d636-18b2
*Apr 18 15:01:41:549 2014 AC TCPCHEAT/7/TCPCHEAT_DEBUG: A connection of c0a80a02 added!
*Apr 18 15:01:41:590 2014 AC TCPCHEAT/7/TCPCHEAT_DEBUG: State of connection with source IP 192.168.10.2 is LISTEN!
*Apr 18 15:01:41:610 2014 AC TCPCHEAT/7/TCPCHEAT_DEBUG: State of connection with source IP 192.168.10.2 changed from LISTEN to SYN_RECVD!
*Apr 18 15:01:41:660 2014 AC TCPCHEAT/7/TCPCHEAT_DEBUG: State of connection with source IP 192.168.10.2 is SYN_RECVD!
*Apr 18 15:01:41:680 2014 AC TCPCHEAT/7/TCPCHEAT_DEBUG: State of connection with source IP 192.168.10.2 changed from SYN_RECVD to ESTABLISHED!
*Apr 18 15:01:41:701 2014 AC TCPCHEAT/7/TCPCHEAT_DEBUG: State of connection with source IP 192.168.10.2 is ESTABLISHED!
以上显示了一个完整的TCP三次握手建立连接的过程:LISTEN-> SYN_RECVD->ESTABLISHED。即AC需要先仿冒终端访问的目标IP,与终端建立TCP连接,接着才能进行HTTP重定向的操作。
(2)终端表现分析
用户打开浏览器,输入任意的网站链接(比如baidu.com),可以看到浏览器导航地址栏自动跳转到Portal认证url,参见IE截图:
图3
但也有一些特殊的终端,比如苹果IOS 7.0之后版本,在关联wifi之后会自动打开Portal认证页面,并不需要手动操作浏览器,这是由于IOS操作系统有内置网络活动状态探测机制。IOS终端关联WiFi之后,后台会通过HTTP探测www.itools.info、www.ibook.info等网站,在被AC设备截获并完成重定向之后表现为自动打开Portal页面。
2、Portal协议交互
(1)原理解析
Portal服务器获取用户的认证用户名/密码之后,通过Portal协议向设备发起认证。先了解一下Portal协议报文结构:
本文不做全面解析,只重点分析其中三个字段:Type、UserIP、ErrCode。
字段一:Type
Portal报文类型,有如下几种在故障处理中经常接触。
类型 | 值 | 方向 | 含义 |
REQ_CHALLENGE | 0x01 | Portal server--> BAS | 表示此报文是Portal Server向BAS发送的 Challenge请求报文 |
ACK_CHALLENGE | 0x02 | BAS --> Portal server | 表示此报文是BAS对Portal Server请求Challenge报文的响应报文 |
REQ_AUTH | 0x03 | Portal server --> BAS | 表示此报文是Portal Server向BAS发送的请求认证报文 |
ACK_AUTH | 0x04 | BAS --> Portal server | 表示此报文是BAS对Portal Server请求认证报文的响应报文 |
REQ_LOGOUT | 0x05 | Portal server --> BAS | 表示此报文是Portal Server向BAS发送的下线请求报文 |
NTF_LOGOUT | 0x08 | BAS --> Portal server | 表示此报文是BAS发送给Portal Server的用户被强制下线的通知报文 |
其中在处理Portal认证失败问题中,前四种REQ_CHALLENGE(挑战请求)、ACK_CHALLENGE(挑战回应)、REQ_AUTH(认证请求)、ACK_AUTH(认证回应)需重点关注。
字段二:UserIP
接入用户的IP地址,也是终端标识。4字节,其值由Portal Server根据获得的终端IP地址填写。不同厂家的Portal Server获取终端信息的方式存在差异。比如中国移动亚信的服务器是在终端http请求中获取终端IP,它要求设备在HTTP重定向时将终端IP地址携带在重定向url中。
字段三:ErrCode
此字段在不同的Type类型情况下,有不同的含义。主要关注ACK_CHALLENGE(Type=2)、ACK_AUTH(Type=4)报文中的ErrCode信息。
对于ACK_CHALLENGE(Type=2)报文,ErrCode有如下含义:
ErrCode=0,表示设备告诉Portal Server请求Challenge成功;
ErrCode=1,表示设备告诉Portal Server请求Challenge被拒绝;
ErrCode=2,表示设备告诉Portal Server此链接已建立;
ErrCode=3,表示设备告诉Portal Server有一个用户正在认证过程中,请稍后再试;
ErrCode=4,则表示设备告诉Portal Server此用户请求Challenge失败(发生错误);
对于ACK_AUTH(Type=4)报文,ErrCode有如下含义:
ErrCode=0,表示设备告诉Portal Server此用户认证成功;
ErrCode=1,表示设备告诉Portal Server此用户认证请求被拒绝;
ErrCode=2,表示设备告诉Portal Server此链接已建立;
ErrCode=3,表示设备告诉Portal Server有一个用户正在认证过程中,请稍后再试;
ErrCode=4 ,表示设备告诉Portal Server此用户认证失败(发生错误);
(2)设备debug分析
在AC上开启debug开关:debugging portal packet interface vlan xxx。检索“Type:”关键字,能快速找到Portal协议报文的debug信息。
*Apr 26 13:58:18:142 2000 WX3024 PORTAL/7/PORTAL_DEBUG:
Portal receive packet length:32
Portal check packet OK
Portal packet head:
Type:1 SN:33 ReqId:0 AttrNum:0 ErrCode:0 UserIP:192.168.10.2
// Portal服务器发送给设备REQ_CHALLENGE报文
*Apr 26 13:58:18:183 2000 WX3024 PORTAL/7/PORTAL_DEBUG:
Portal send packet length:62
Portal packet head:
Type:2 SN:33 ReqId:7 AttrNum:3 ErrCode:0 UserIP:192.168.10.2
Portal packet attribute list:
[ 3 Challenge ] [ 18] [0b07f5d53739c46ac9e90096bf684be5]
[ 10 BAS-IP ] [ 6] [10.153.43.157]
[ 38 DeviceStartTime ] [ 6] [956750483]
// 设备回应给Portal服务器ACK_CHALLENGE报文,报文中携带Challenge挑战字段。
*Apr 26 13:58:18:253 2000 WX3024 PORTAL/7/PORTAL_DEBUG:
Portal receive packet length:82
Portal check packet OK
Portal packet head:
Type:3 SN:33 ReqId:7 AttrNum:4 ErrCode:0 UserIP:192.168.10.2
Portal packet attribute list:
[ 1 UserName ] [ 8] [wcq123]
[ 4 ChapPassWord ] [ 18] [3e4c7275e9aa5f2281dd8a534d08c2e7]
[ 3 Challenge ] [ 18] [0b07f5d53739c46ac9e90096bf684be5]
[ 10 BAS-IP ] [ 6] [10.153.43.157]
//Portal服务器发送给设备REQ_AUTH报文
当Portal服务器向设备发起REQ_AUTH之后,设备需要先和Radius服务器完成AAA交互,根据AAA验证情况再回应服务器ACK_AUTH。这里略去和Radius服务器的AAA交互过程,先看ACK_AUTH。
*Apr 26 13:58:18:931 2000 WX3024 PORTAL/7/PORTAL_DEBUG:
Portal send packet length:117
Portal packet head:
Type:4 SN:33 ReqId:7 AttrNum:4 ErrCode:0 UserIP:192.168.10.2
Portal packet attribute list:
[ 10 BAS-IP ] [ 6] [10.153.43.157]
[ 11 Session-ID ] [ 8] [6c881459898c]
[ 33 RelayMessage ] [ 65] [6]
[ 38 DeviceStartTime ] [ 6] [956750483]
//设备回应给Portal服务器ACK_AUTH报文,ErrCode=0表示用户认证成功。
3、Radius协议交互
通过Portal的debug分析,我们能知道Portal认证通过与否,但“为什么通过、为什么不通过”只有Radius能给我们清晰的答案。
(1)原理解析
先看看Radius报文结构:
字段一:Code
Radius数据包类型,1字节。主要包括如下类型:
Code | 报文类型 | 方向 | 含义 |
1 | Access-Request认证请求包 | BAS--> Server | 表示此报文是BAS向AAA发送的认证请求报文 |
2 | Access-Accept认证接受包 | Server-->BAS | 表示此报文是AAA向BAS发送的认证成功响应报文 |
3 | Access-Reject认证拒绝包 | Server-->BAS | 表示此报文是AAA向BAS发送的认证拒绝响应报文 |
4 | Accounting-Request计费请求包 | BAS--> Server | 表示此报文是BAS向AAA发送的计费请求报文 |
5 | Accounting-Response认证响应包 | Server-->BAS | 表示此报文是AAA向BAS发送的计费响应报文 |
字段二:Identifier
Radius数据包标识,1字节。用于匹配请求包和响应包,同一组请求包和响应包的Identifier应该相同。如果在一个很短的时间片段里,两个认证请求包有相同的客户源IP地址、源UDP端口号和标识符,RADIUS服务器会认为这是一个重复的请求而不响应处理。
字段三:Length
包长度,2字节。
字段四:Authenticator
验证字,用于验证来自RADIUS服务器的回复是否合法。验证字分为两种:
请求验证字:Request Authenticator 用在请求报文中。
响应验证字:Response Authenticator 用在响应报文中。
响应验证字=MD5(Code+ID+Length+请求验证字+Attributes+Key)
字段五:Attributes
Radius属性字段,用来在请求和响应报文中携带详细的认证、授权、信息和配置细节,来实现认证、授权、计费等功能。它采用(Type、Length、Value)三元组的形式提供。Attributes属性是我们处理AAA故障的重要关注点。
(2)设备debug分析
在AC上开启debug开关:debugging radius packet,检索“Code=[”关键字,能快速找到Radius协议报文。
*Apr 26 13:58:18:364 2000 WX3024 RDS/7/DEBUG: Send attribute list:
*Apr 26 13:58:18:374 2000 WX3024 RDS/7/DEBUG:
[1 User-name ] [8 ] [wcq123]
[60 CHAP_Challenge ] [18] [0B07F5D53739C46AC9E90096BF684BE5]
[4 NAS-IP-Address ] [6 ] [10.153.43.157]
[32 NAS-Identifier ] [8 ] [WX3024]
[5 NAS-Port ] [6 ] [16781322]
[87 NAS_Port_Id ] [18] [0100001000000010]
*Apr 26 13:58:18:414 2000 WX3024 RDS/7/DEBUG:
[61 NAS-Port-Type ] [6 ] [19]
[H3C-26 Connect_ID ] [6 ] [9]
[6 Service-Type ] [6 ] [2]
[7 Framed-Protocol ] [6 ] [255]
[31 Caller-ID ] [19] [36432D38382D31342D35392D38392D3843]
[30 Called-station-Id ] [26] [58-66-BA-6B-F2-C0:h3c-wu]
*Apr 26 13:58:18:455 2000 WX3024 RDS/7/DEBUG:
[44 Acct-Session-Id ] [15] [1000326135880]
[8 Framed-Address ] [6 ] [192.168.10.2]
[H3C-255Product-ID ] [12] [H3C WX3024]
[H3C-60 Ip-Host-Addr ] [32] [192.168.10.2 6c:88:14:59:89:8c]
[H3C-59 NAS-Startup-Timestamp ] [6 ] [956750400]
*Apr 26 13:58:18:495 2000 WX3024 RDS/7/DEBUG:
Event: Begin to switch RADIUS server when sending 0 packet.
*Apr 26 13:58:18:515 2000 WX3024 RDS/7/DEBUG: The RD TWL timer has resumeed.
*Apr 26 13:58:18:525 2000 WX3024 RDS/7/DEBUG: Malloc seed:11 in 10.153.43.100 for User ID:9
*Apr 26 13:58:18:536 2000 WX3024 RDS/7/DEBUG:
Event: Modify NAS-IP to 10.153.43.157.
*Apr 26 13:58:18:546 2000 WX3024 RDS/7/DEBUG: Send: IP=[10.153.43.100], UserIndex=[9], ID=[11], RetryTimes=[0], Code=[1], Length=[249]
// 设备向Radius服务器发送认证请求包,其中会携带User-name、NAS-IP等Radius属性
*Apr 26 13:58:18:839 2000 WX3024 RDS/7/DEBUG: Free seed:11 in 10.153.43.100 for User ID:9
*Apr 26 13:58:18:850 2000 WX3024 RDS/7/DEBUG: Receive:IP=[10.153.43.100],Code=[2],Length=[145]
*Apr 26 13:58:18:860 2000 WX3024 RDS/7/DEBUG:
[1 User-name ] [8 ] [wcq123]
[6 Service-Type ] [6 ] [2]
[24 State ] [10] [756D387A48336C30]
[29 Termination-Action ] [6 ] [0]
[27 Session-TimeOut ] [6 ] [86401]
[85 Acct_Interim_Interval ] [6 ] [600]
*Apr 26 13:58:18:900 2000 WX3024 RDS/7/DEBUG:
[H3C-26 Connect_ID ] [6 ] [9]
[H3C-61 Server_String ] [65] []
//Radius服务器向设备回应认证接受包,其中会携带授权用户上线时长Session-TimeOut、计费更新间隔Acct_Interim_Interval等属性
如果AAA校验过程中有任何差错,Radius服务器便不会向设备发送认证接受包,而是会回应认证拒绝包。
*Apr 26 14:03:41:257 2014 WX3024 RDS/7/DEBUG: Free seed:146 in 10.10.43.3 for User ID:9
*Apr 26 14:03:41:257 2014 WX3024 RDS/7/DEBUG: Receive:IP=[221.176.1.138],Code=[3],Length=[35]
*Apr 26 14:03:41:257 2014 WX3024 RDS/7/DEBUG:
[18 Reply-Message ] [15] [user not exist]
*Apr 26 14:03:41:257 2014 WX3024 RDS/7/DEBUG: RejectMsg=[user not exist]
//Radius服务器向设备回应认证拒绝包
一般情况下,Radius服务器会在认证拒绝包中携带Replay-Message属性,内容是AAA“愿意”告诉设备的一些额外信息,比如认证拒绝的原因等。当然,服务器返回的Reply-Message也可能什么也没有,这里没有RFC强制规范。
三、 附送锦囊之Portal排错自检:
常见的Portal认证故障,经过上述过程的检查梳理之后,且不说一定能如庖丁般“使牛像泥土一样摊在地上、胫骨毕现”,至少能把牛大卸八块,找出故障环节。下面再列举一些常见的导致Portal故障的原因,以飨诸位刀客。
(1)终端已经通过Portal认证,但上不了网
点评:在设备上display connection看到终端已经通过Portal认证啦,但还是看不了美剧。偶滴神,这个wifi有可能没有通互联网哦,需要排查有线出口和路由。
(2)设备上未放通DNS,Portal页面无法弹出
点评:终端在浏览器上输入网址域名后,浏览器必须先完成DNS解析才能向目标IP发起TCP连接请求,从而触发重定向。如果终端未配置DNS或DNS不可用,则无法发起TCP连接和触发重定向。这种错误可以通过直接在浏览器地址栏输入任意IP而不是域名来测试。
(3)设备三层接口未配置portal nas-ip,用户点击登陆按钮后WEB页面返回“设备无响应”报错。
点评:当设备上没有配置portal nas-ip时,设备缺省以用户三层接口IP地址跟Portal服务器通信,如果这个IP与服务器侧配置的接入设备IP不一致,就会导致服务器不识别设备的回应报文,从而出现“设备无响应”报错。
(4)设备未定义正确的Portal认证域,导致认证不通过
点评:这个属于基本配置漏缺,找错了认证域,自然无法匹配正确的Radius策略和通过AAA校验。
(5)设备上学不到终端的ARP,CHALLENGE挑战不通过,认证失败
点评:当因无线关联问题或其它原因导致设备上学习不到终端ARP时,设备在Portal CHALLENGE挑战环节会由于查询不到UserIP所属的无线终端,会拒绝CHALLENGE挑战,导致Portal认证失败。
(6)终端浏览器缓存认证页面,导致认证失败
点评:在中国移动的WLAN网络中,一种常见的错误是终端将Portal认证页面保存起来,从一个热点走到另一个热点再次关联WiFi,然后用之前保存的Portal页面输入用户名密码登录。这常常会导致认证失败。原因在于终端切换热点后,所获取的IP地址可能会变化,而且新热点和老热点还可能是由不同的AC管理。这就要求新热点下的重定向url中携带的用户IP和AC标识信息同步刷新,如果用保存的老页面url登陆,会导致Portal服务器向错误的AC设备发起认证,或者AC上找不到指定UserIP的终端,总之,这都会导致认证最终失败。