深入了解校园网802.1x认证的EAP协议(1)——EAP的总体流程

EAP(Extensible Authentication Protocol),是一个普遍使用的认证机制,详细介绍可见Wikipedia。本文介绍的,是被广泛使用在国内高校校园网的认证机制使用的EAP协议,暂不具体地说明某个品牌的私有协议如何如何,而是从整体角度看EAP协议如何工作,从一个第三方Supplicant客户端的开发者角度解释EAP的通信机制。在后续的章节将继续介绍PT接触过的几种认证协议中,国内的“标准践踏者们”如何实现各种变态的认证协议。

文中出现的术语和名词,基本参考了RFC 3748的相关描述,以及Wireshark软件对相关报文的解释用词。

认证过程简述:

  1. 主机向服务器(多播或广播地址)发送EAPOL-Start
  2. 服务器向主机发送EAP-REQUEST-Identity要求验证身份的请求
  3. 主机向服务器发送EAP-RESPONSE-Identity回应
  4. 服务器向主机发送EAP-REQUEST-MD5_Challenge要求验证密码的MD5校验值
  5. 主机向服务器发送EAP-RESPONSE-MD5_Challenge回应
  6. 服务器向主机发送EAP-Success
  7. 保持连接的通信…

当然这只是一般过程,如果在任何时候服务器发来EAP-Failure数据包,都表示整个认证过程终止。

 Supplicant主机                  服务器
 ———–                 ————-
    |——————————>|
    | 1.  EAPOL-Start               |
    |                               |
    |<——————————|
    | 2. EAP-REQUEST-Identity       |
    |                               |
    |——————————>|
    | 3. EAP-RESPONSE-Identity      |
    |                               |
    |<——————————|
    | 4. EAP-REQUEST-MD5_Challenge  |
    |                               |
    |——————————>|
    | 5. EAP-RESPONSE-MD5_Challenge |
    |                               |
    |<——————————|
    | 6.       EAP-Success          |
    |                               |

在以太网中,EAP协议当然也是通过以太网帧的格式来传送,帧类型为0x888e,在基于pcap的抓包程序中,可使用”ether proto 0x888e”来抓取。

Ethernet-Header:
################################################
#  0              5               11       13  #
# +—————-+—————-+——–+ #
# |DST–MAC        |SRC–MAC        |0x888e  | #
# +—————-+—————-+——–+ #
################################################


当用作802.1x应答帧时,常使用802.1x分配的多播地址01-80-c2-00-00-03作为目的地址。

从Wiki的简介得知,EAP协议不仅可用于本文关注的以太网环境中,还可在无线WLAN、令牌环网中应用,而这些链路帧是各不相同的,这就是为什么有EAPOL类型的数据帧,用以抽象EAP协议报文。

EAPOL-报文结构
############################################
#  0                           14 15       #
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+        #
# | Ethernet-Header           |a|b|        #
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+        #
#    17                                    #
# +-+-+————-                       #
# |c  |Packet Body                         #
# +-+-+————-                       #
############################################
a:EAPOL 协议版本
b:EAPOL 报文类型
c:EAPOL 帧长度

a类型说明:通常为常量0x01

b类型取值:
EAPOL-Packet :   0x00
EAPOL-Start:     0x01
EAPOL-Logoff:    0x02

各种EAP协议的信息交互,封装在EAPOL-Packet类型的EAPOL报文内。至于EAP报文的格式,基本就是如下所示。

EAP-报文结构
#########################################
#  0                            15      #
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+     #
# |                               |     #
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+     #
#   17 18 19 21 22                      #
# +-+-+-+-+-+-+-+————–         #
# |   |d|e|f  |g|EAP Body               #
# +-+-+-+-+-+-+-+————–         #
#########################################

d:EAP通信类型
e:EAP通信id
f:EAP数据长度
g:EAP协商类型

d类型取值:
EAP-Request:  0x01
EAP-Resopnse: 0x02
EAP-Success:  0x03
EAP-Failure:  0x04

e类型说明:
通常由服务器发来的报文指定,在连续的报文内使用这个id来协商或者计算MD5值的数据之一。

g类型取值:
Identity:        0x01
MD5_Challenge:   0x04

一个EAP Supplicant客户端程序主要的任务就是处理服务器发来的数据帧和组织回应服务器的数据帧。除了根据上述的“c:EAP通信类型”和“f:EAP协商类型”位来识别协商类型外,更需要根据这些报文内的其他数据来组织回应数据帧。

下面是需要程序构建的数据包的大概细节:

(需要注意EAPOL帧和EAP帧的两处长度位置,前者的长度是不算EAPOL头的4个字节的,而后者则包含自身头部的5个字节,所以这两个长度的值可能是一致的,但具体可能有扩展信息放在EAPOL帧尾部,则前者比后者大。)

1.EAPOL-Start、EAPOL-Logoff
通常是比较简单的数据包,只需填好相应的位,没有其他附加消息,EAPOL-Start、EAPOL-Logoff两种报文长度为0,通常建立起来两个报文的长度就只有18字节。

2.EAP-REQUEST-Identity
服务器发来的这个报文也比较简单,可能唯一有用的数据是“e:EAP通信id”位,需要给发送回去的报文中把相应位设置为该值,虽然这很可能是常数。

Identity格式
+-+-+-+-…..-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| EAP Header      |  Username
+-+-+-+-…..-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

3.EAP-RESPONSE-Identity
只需要设置“d:EAP通信id”位,然后在EAP头后紧接用户名的ASCII码信息。有些品牌的协议中,则顺带在此数据包开始校验客户端的IP、版本号等信息。

4.EAP-REQUEST-MD5_Challenge
服务器请求MD5校验的报文中包含了重要的信息,首先也是“e:EAP通信id”位,后一个报文也需要设置该位;
在EAP报头后紧接一个一位的长度值L(常量0x10),表示紧跟其后的重要数据的长度,其后的16位值则需要用来计算下一个报文中的信息,我们称之为attach-key。

MD5_Challenge格式
+-+-+-+-…..-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| EAP Header      |L|MD5-Key/Value
+-+-+-+-…..-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

5.EAP-RESPONSE-MD5_Challenge
首先需要设置“d:EAP通信id”位,然后构建一个这样的字节数组[(e:EAP通信id)(用户密码的ASCII)(attach-key)],这个字节的长度当然是(1+用户密码长度+16),然后送入MD5计算函数中,获得16位的计算结果,再把这16位计算结果填入报文。报文格式跟请求的类似,在包头后紧接一位长度值,当然是0x10,然后是16位的计算结果。

一个客户端程序所做的事情通常就是这么多,而因为EAP协议的“Extensible”的特性,几乎我们见到的每个品牌的协议都有所扩展,而且各不相同,所以各个品牌之间的客户端甚至交换机等设备都可能完全不可兼容的,其协议很可能在上述的报文中都添加一个信息尾,用来校验各种信息,具体的情况请留意PT博客的后续文章。

文章分类 Programming 标签: , ,
12 comments on “深入了解校园网802.1x认证的EAP协议(1)——EAP的总体流程
  1. ayanmw说道:

    挺好的,我早就想研究下它了,不过基础不行…
    寨主啊,你可以编写zlenovoclient(比你写的那个多俩字母,不过我这个名字更好记,更规范.)的windows版本么??用C来编写就行..
    我讨厌死1xclient了(联想客户端).早就希望有个其他版本来代替了.
    我在想,应该能用cygwin来编写出来,不过最近没研究,试过一次,配置libpcap或者winpcap的环境,让我发愁,不知道该如何是好!希望你能给点思路或者重新编写windows版本的.
    linux版本的zlevoclient加入了许多linux的头文件什么sys/time.h等.我也不清楚,目前编程水平还比较差.希望你费点心!多谢!
    我是测试这个软件的河南工业大学的那名同学.希望咱们可以经常交流.QQ 52527459

  2. ayanmw说道:

    用cygwin编写遇到的问题就是
    zlevoclient.o: In function `action_by_eap_type’:
    /home/Administrator/zclient/zlevoclient.c:326: undefined reference to `_pcap_breakloop’
    zlevoclient.o: In function `send_eap_packet’:
    /home/Administrator/zclient/zlevoclient.c:387: undefined reference to `_pcap_sendpacket’
    /home/Administrator/zclient/zlevoclient.c:389: undefined reference to `_pcap_geterr’
    zlevoclient.o: In function `init_device’:
    /home/Administrator/zclient/zlevoclient.c:542: undefined reference to `_pcap_lookupdev’
    /home/Administrator/zclient/zlevoclient.c:551: undefined reference to `_pcap_open_live’
    /home/Administrator/zclient/zlevoclient.c:559: undefined reference to `_pcap_datalink’
    /home/Administrator/zclient/zlevoclient.c:598: undefined reference to `_pcap_compile’
    /home/Administrator/zclient/zlevoclient.c:599: undefined reference to `_pcap_geterr’
    /home/Administrator/zclient/zlevoclient.c:605: undefined reference to `_pcap_setfilter’
    /home/Administrator/zclient/zlevoclient.c:606: undefined reference to `_pcap_geterr’
    /home/Administrator/zclient/zlevoclient.c:610: undefined reference to `_pcap_freecode’
    zlevoclient.o: In function `signal_interrupted’:
    /home/Administrator/zclient/zlevoclient.c:619: undefined reference to `_pcap_breakloop’
    zlevoclient.o: In function `main’:
    /home/Administrator/zclient/zlevoclient.c:755: undefined reference to `_pcap_loop’
    /home/Administrator/zclient/zlevoclient.c:759: undefined reference to `_pcap_close’
    collect2: ld returned 1 exit status
    make: *** [zlevoclient.exe] Error 1

    Administrator@ayanmw ~/zclient

  3. ayanmw说道:

    在cygwin下的环境还是和linux的不一样.
    到底是libpcap和winpcap的差异在哪里?真是搞不懂…继续尝试..

  4. PT说道:

    @ayanmw : libpcap和winpcap是完全兼容的,API完全一致。所以zlevoclient很容易就能编译成Win的版本。问题在于对系统API的调用,主要在于init_device函数里面,我使用了Linux的Api以获取本机IP、网卡Mac地址等信息,因此只需要重写这个函数就可以编译出win版的拨号程序了,当然后台进程那几个函数也得去掉,win里面没有fork,还有那个认证后60秒定时发保持链接数据的线程用的是pthread,Win下虽然也有pthread的移植,但建议改成MFC的线程调用;

    你们可以基于zlevoclient的代码写个Win版本出来,难度并不高的,我准备写文章解释一下联想和神州数码的认证细节。

  5. PT说道:

    你遇到那个编译错误似乎是pcap库没有链接成功,加上-L指向winpcap的目录的参数吧,不过肯定有别的地方无法编译的。

  6. ayanmw说道:

    我使用的是cygwin,许多linux系统函数都已经在了,我编译的问题应该是3个问题:
    1,线程的pthread,在我这里不知道为何头文件错误?竟然不提示zlevoclient.c的错误,提示系统头文件错误;不过我随便写个hello,包括pthread的头文件,仍然有问题,看来是头文件的事情了..反正没用,我去了;-background 我也去;program unique我也去了;win下暂时不需要
    2,ioctl,cygwin里已经有ioctl-types.h和ioctls.h了;这个函数可以使用吧,不懂;
    3,cygwin下没有libpcap,我下载winpcap的源码编译也出现问题,无法在cygwin下编译;所以没有了libpcap.o了;;所以我用winpcap里的libwpcap代替了() -lwpcap 参数解决();编译出来了,但是无法运行,一点反映都没,;

    哎,很想用你这版本的win版,但是自己又无法重新用win下的VC来编写;痛苦撒

  7. PT说道:

    @ayanmw 上次邮件里面问的不是你么?不是已经编译好了?程序的ioctl用法在win里面不可用,需要重写init_device函数,主要是网卡mac的获取;上次邮件里面那人硬编码了网卡mac地址,据说已经成功了。在win下还需要修改一下print_serve_info函数,因为win不用转换成utf-8的文字。

  8. BOYPT说道:

    @ayanmw

    我已经开发了锐捷客户端的Win版本,理论上只需要把联想版本的init_frame函数替换过去就可以成为联想的客户端了,但是我没有测试环境,如果你们有兴趣可以自己修改,或者邮件联系我。

  9. ayanmw说道:

    现在我们的学校(河南工业大学)的8021又改了,有两方面,第一就是我抓的包,多了一些其他的EAP包,由于咱们的zlevoclient中没有这个EAP类型,所以zlevoclient就无法接受服务器发送最后的Success了..郁闷了,第二就是就是…万恶的1xclient.dll,简直就是个流氓软件,偶尔发送来msgbox消息框,现在更是检测电脑中是否有AntiARP.exe这个进程了,,该死,但是这个应该是客户端干的事情,如果zlevoclient能用,估计不需要这个进程,也说不定,但是抓包没有获得掉线或者什么的EAP包,难道是通过TCP/UDP传送数据?也不知道..
    不知道其他学校的人有没有类似的问题啊?
    总之,现在我linux下时上不了网了,至于1xdialclient,我在fedora12下运行失败,估计是包依赖出现了问题?

  10. hxangel说道:

    @ayanmw: 我这里linux下上网没有问题哦。不过我就啥都不懂,只是他说咋用就咋用这样的

  11. kid说道:

    na个。。我们学校用的是dr。com的定制版

  12. kid说道:

    能帮忙分析下么

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*