【协议】AAA Radius协议的常用报文分析
写在前面的话
RADIUS:Remote Authentication Dial In User Service,远程用户拨号认证系统由RFC2865,RFC2866定义,是应用最广泛的AAA协议。
如下简单的分析一下 RADIUS 协议是怎么工作的。
名词解释
BRAS:宽带接入服务器,Broadband Remote Access Server,简称 BRAS
NAS: 网络接入服务器,Network Access Server,简称 NAS
AAA: 认证 Authentication,授权 Authorization,计费 Accounting
RADIUS: 远程认证拨号用户服务,remote authentication dial-in user service,简称RADIUS。
DM: Radius主动发起断开链接请求 Disconnect-Request,简称DM
COA: Radius主动发起修改授权属性,Change of Authorization,简称 COA
报文说明
Radius协议的报文协议
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Code | Identifier | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Authenticator |
| |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attributes ...
+-+-+-+-+-+-+-+-+-+-+-+-+-
在报文中的表示如下所示:

Radius 报文可以分为 Header 和 Attribute 两部分
Radius 的头部代码定义
// radius header
typedef struct RadHeader {i
unsigned char code;
unsigned char identifier;
unsigned short length;
unsigned char authcator[16];
} RadHeader;
Code 占一个字节
常用的取值如下:
1 Access-Request
2 Access-Accept
3 Access-Reject
4 Accounting-Request
5 Accounting-Response 6 Accounting Status (now Interim Accounting [5])
7 Password Request
8 Password Ack
9 Password Reject
10 Accounting Message
11 Access-Challenge
12 Status-Server (experimental)
13 Status-Client (experimental) 21 Resource Free Request
22 Resource Free Response
23 Resource Query Request
24 Resource Query Response
25 Alternate Resource Reclaim Request
26 NAS Reboot Request
27 NAS Reboot Response 29 Next Passcode
30 New Pin
31 Terminate Session
32 Password Expired
33 Event Request
34 Event Response
40 Disconnect Request
41 Disconnect Ack
42 Disconnect Nak
43 Change Filters Request
44 Change Filters Ack
45 Change Filters Nak
50 IP Address Allocate
51 IP Address Release 255 Reserved
Identifier是报文的流水号
NAS 和 AAA 服务器通过这个流水号来标识认证请求和认证响应,计费请求和计费响应的配对关系。
如下所示:
认证请求和认证响应的配对关系。


计费请求和计费响应的配对关系。

Length 字段是整个报文的长度
长度包括 Code, Identifier, Length, Authenticator 和 Attribute fields.
Authenticator认证
这个字段主要是为了验证报文的合法性。
计算方式如下 MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
Attribute属性
这个字段是 Radius 协议的重点,包括标准属性和厂家的26号私有属性两类。
Attribute 通过 T-L-V 编码格式进行编码,Type-Length-Value
Radius 的 Attribute 代码定义
// radius int attribute.
typedef struct RadInt {
unsigned char type;
unsigned char length;
char value[4];
} RadInt; #define RAD_ATTRSTR_LEN 253 /* Attribute (string) */
// radius string attribute.
typedef struct RadStr {
unsigned char type;
unsigned char length;
char value[RAD_ATTRSTR_LEN];
} RadStr; // radius structure attribute.
typedef struct AttrStru {
unsigned char type;
unsigned char length;
char iValue[1];
} AttrStru;
Radius 的 Attribute 的 Type 有如下几种,不同的类型使用不同的编解码器进行编解码处理。
// Define Attribute and Value Type.
#define RAD_ATTR_TYPE_STRING (0x01)
#define RAD_ATTR_TYPE_ADDRESS (0x02)
#define RAD_ATTR_TYPE_INTEGER (0x03)
#define RAD_ATTR_TYPE_TIME (0x04)
#define RAD_ATTR_TYPE_ADDRESS6 (0x05)
#define RAD_ATTR_TYPE_FIX8 (0x06)
#define RAD_ATTR_TYPE_BINARY (0x07)
#define RAD_ATTR_TYPE_IPV6PREFIX (0x08)
#define RAD_ATTR_TYPE_SECRET (0x09)
#define RAD_ATTR_TYPE_UNKNOWNTP (0x00)
认证计费的完整流程
认证失败流程

AAA 返回给 NAS认证拒绝时,流程结束 。
认证成功+计费流程

AAA 返回给 NAS 认证成功时,NAS 会继续发起计费开始报文,用户下线时 NAS 发起计费结束报文,AAA 回复计费相应报文。
认证请求报文(Authentication Request)
报文数据方向,NAS发起到AAA Radius Server
+----------+ Auth-Request +----------+
| | --------------------> | |
| NAS | | RADIUS |
| | Auth-Response | Server |
| | <--------------------- | |
+----------+ +----------+
Code取值:1
如下以华为的设备为例说明认证请求报文:

认证通过响应报文(Authentication Accept)
报文数据方向,AAA Radius Server发送认证通过给 NAS
+----------+ Auth-Request +----------+
| | --------------------> | |
| NAS | | RADIUS |
| | Auth-Response | Server |
| | <--------------------- | |
+----------+ +----------+
Code取值:2
如下是一个认证成功的响应报文例子:

通过验证用户的账号和密码,验证方式优 PAP 和 CHAP, 对通过验证的用户,下发授权峰值带宽,控制用户的上网带宽。
以华为设备为例,AAA 会通过上网策略下发如下几个属性控制上网带宽。
如下举例说明,将上行带宽设置为1M,下行带宽设置为2M。
HW-Input-Peak-Rate 1048576
HW-Input-Average-Rate 1048576
HW-Input-Basic-Rate 1048576
HW-Output-Peak-Rate 2097152
HW-Output-Average-Rate 2097152
HW-Output-Basic-Rate 2097152
认证拒绝响应报文(Authentication Reject)
报文数据方向,AAA Radius Server发送认证拒绝给 NAS
+----------+ Auth-Request +----------+
| | --------------------> | |
| NAS | | RADIUS |
| | Auth-Response | Server |
| | <--------------------- | |
+----------+ +----------+
Code取值:3
通过PAP 和 CHAP方式验证用户的用户名和加密密码失败时,AAA会返给NAS 一个认证拒绝报文。
如下是一个认证拒绝的响应报文例子:

计费请求报文(Accounting Request)
报文数据方向,NAS 发送计费报文给AAA Radius Server
+----------+ Acct-Request +----------+
| | --------------------> | |
| NAS | | RADIUS |
| | Acct-Response | Server |
| | <--------------------- | |
+----------+ +----------+
Code取值:4
通过第一步中,NAS 发起认证请求到 AAA,AAA 认证通过给 NAS 后。
NAS 进行第二步的报文交互,NAS 发起计费开始报文请求到 AAA,AAA 计费响应报文给 NAS 。
注:计费报文的 Acct-Session-Id必须和第一步认证通过的 Acct-Session-Id 一致,说明本次计费是以认证成功的 Acct-Session-Id为计费对象。
用户某一时间段的总流量是通过这个时间段内一个一个的 Acct-Session-Id上流量合并得到。
计费报文分三类:
- 计费开始报文 Start
- 计费保活报文 Keepalive
- 计费结束报文 Stop
计费的开始报文Start:
计费请求参数 Acct-Status-Type = 1
如下是一个计费开始报文的报文例子:

计费的结束报文Stop
计费报文的Acct-Status-Type = 2
问题:运营商是如何统计一个宽带账号使用了多少流量呢?
运营商通过计费结束报文的Acct-Input-Octets统计上行流量,Acct-Output-Octets 统计下线流量,将这两个流量相加得到用户实际上网使用的流量是多少。
注:若用户流量超过一定的额度,可以通过下次账号登录后,下发授权峰值带宽,控制用户的上网带宽。见认证响应通过报文。
如下是一个计费结束报文的报文例子:

计费响应报文(Accounting Response)
报文数据方向,AAA Radius Server发送计费相应给 NAS
+----------+ Acct-Request +----------+
| | --------------------> | |
| NAS | | RADIUS |
| | Acct-Response | Server |
| | <--------------------- | |
+----------+ +----------+
Code取值:5
如下是一个计费响应报文的报文例子:

DM踢用户下线报文
+----------+ Disconnect-Request +----------+
| | <-------------------- | |
| NAS | | RADIUS |
| | Disconnect-Response | Server |
| | ---------------------> | |
+----------+ +----------+
Code取值:请求40,响应成功41,响应失败42
40 - Disconnect-Request [RFC2882]
41 - Disconnect-ACK [RFC2882]
42 - Disconnect-NAK [RFC2882]
如下是一个 DM 的报文例子:

注:在 DM 报文中比较重要的属性是 Acct-Session-Id,即:要将用户的哪个会话踢下线。
如下是一个 DM 的组包代码例子:
int DisconnectHuaWei(int argc, char **argv) {
char radiusPacketBuffer[0xffff+1] = {0};
memset(radiusPacketBuffer, 0, sizeof(radiusPacketBuffer));
radiusPacketBuffer[0] = 40;
gID = ++gID % 0xff;
radiusPacketBuffer[1] = gID;
int len = 20;
// User-Name 1
int tmpLen = strlen(argv[1]);
sprintf(radiusPacketBuffer+len, "%c%c%s", 1, tmpLen+2, argv[1]);
len += tmpLen+2;
// Framed-Ip-Address 8
unsigned int sin_addr;
if(inet_pton(AF_INET, argv[2], &sin_addr) <= 0)
{
return TCL_ERROR;
}
// 转换成网络套接字
//sin_addr = htonl(sin_addr);
radiusPacketBuffer[len++] = 8;
radiusPacketBuffer[len++] = 6;
memcpy(radiusPacketBuffer+len, &sin_addr, 4);
len += 4;
// NAS-IP-Address 4
if(inet_pton(AF_INET, argv[4], &sin_addr) <= 0)
{
return ERROR;
}
// 转换成网络套接字
//sin_addr = htonl(sin_addr);
radiusPacketBuffer[len++] = 4;
radiusPacketBuffer[len++] = 6;
memcpy(radiusPacketBuffer+len, &sin_addr, 4);
len += 4;
// Acct-Session-Id 44
tmpLen = strlen(argv[3]);
sprintf(radiusPacketBuffer+len, "%c%c%s", 44, tmpLen+2, argv[3]);
len += tmpLen+2;
radiusPacketBuffer[2] = len / 0xff;
radiusPacketBuffer[3] = len % 0xff;
unsigned char authen[17] = {0};
int keyLen = strlen(brasSecureKey);
memcpy(radiusPacketBuffer+len, brasSecureKey, keyLen);
MD5Calc((unsigned char*)radiusPacketBuffer, len+keyLen, authen);
memcpy(radiusPacketBuffer+4, authen, 16);
return OK;
}
COA下发策略报文(修改上下行带宽,即:网络提速)
+----------+ CoA-Request +----------+
| | <-------------------- | |
| NAS | | RADIUS |
| | CoA-Response | Server |
| | ---------------------> | |
+----------+ +----------+
Code取值:请求43,响应成功44,响应失败45
43 - CoA-Request [RFC2882]
44 - CoA-ACK [RFC2882]
45 - CoA-NAK [RFC2882]
COA 的请求包43
如下是一个 COA 报文例子:

注:在 COA 报文中比较重要的属性是 Acct-Session-Id,即:要改变用户的哪个会话上的属性。
COA 可以做 Portal 登录重定向,修改上网带宽等功能。
COA的回包44

如下是一个 COA 的组包代码例子
int OpenHUAWEI(int argc, char **argv) {
char radiusPacketBuffer[0xffff+1] = {0};
memset(radiusPacketBuffer, 0, sizeof(radiusPacketBuffer));
radiusPacketBuffer[0] = 43;
gID = ++gID % 0xff;
radiusPacketBuffer[1] = gID;
int len = 20;
// User-Name 1
int tmpLen = strlen(argv[1]);
sprintf(radiusPacketBuffer+len, "%c%c%s", 1, tmpLen+2, argv[1]);
len += tmpLen+2;
// Framed-Ip-Address 8
unsigned int sin_addr;
if(inet_pton(AF_INET, argv[2], &sin_addr) <= 0)
{
return ERROR;
}
// 转换成网络套接字
//sin_addr = htonl(sin_addr);
radiusPacketBuffer[len++] = 8;
radiusPacketBuffer[len++] = 6;
memcpy(radiusPacketBuffer+len, &sin_addr, 4);
len += 4;
// Acct-Session-Id 44
tmpLen = strlen(argv[3]);
sprintf(radiusPacketBuffer+len, "%c%c%s", 44, tmpLen+2, argv[3]);
len += tmpLen+2;
// Huawei-HW-Portal-Mode 85
radiusPacketBuffer[len++] = 0x1a;
radiusPacketBuffer[len++] = 6+4+2;
radiusPacketBuffer[len++] = HUAWEIVendor[0];
radiusPacketBuffer[len++] = HUAWEIVendor[1];
radiusPacketBuffer[len++] = HUAWEIVendor[2];
radiusPacketBuffer[len++] = HUAWEIVendor[3];
radiusPacketBuffer[len++] = 0x55;
radiusPacketBuffer[len++] = 0x06;
radiusPacketBuffer[len++] = 0x00;
radiusPacketBuffer[len++] = 0x00;
radiusPacketBuffer[len++] = 0x00;
radiusPacketBuffer[len++] = 0x01;
// Huawei-PortalURL 27
tmpLen = strlen(argv[4]);
radiusPacketBuffer[len++] = 0x1a;
radiusPacketBuffer[len++] = tmpLen+2+4+2;
radiusPacketBuffer[len++] = HUAWEIVendor[0];
radiusPacketBuffer[len++] = HUAWEIVendor[1];
radiusPacketBuffer[len++] = HUAWEIVendor[2];
radiusPacketBuffer[len++] = HUAWEIVendor[3];
sprintf(radiusPacketBuffer+len, "%c%c%s", 27, tmpLen+2, argv[4]);
len += tmpLen+2;
radiusPacketBuffer[2] = len / 0xff;
radiusPacketBuffer[3] = len % 0xff;
unsigned char authen[17] = {0};
int keyLen = strlen(brasSecureKey);
memcpy(radiusPacketBuffer+len, brasSecureKey, keyLen);
MD5Calc((unsigned char*)radiusPacketBuffer, len+keyLen, authen);
memcpy(radiusPacketBuffer+4, authen, 16);
return OK;
}
26号私有属性说明
不同的厂家使用的26号私有属性各有不同,如下列举国内运营商常用的厂家的26号属性。
# 亚信 AsiaInfo extern Vendor Attrib
# Vendor 26, 999
#
# 爱立信 Ericsson extern Vendor Attrib
# Vendor 26, 2352
#
# 华为 HuaWei extern Vendor Attrib
# Vendor 26, 2011
#
# 中兴 ZTE extern Vendor Attrib
# Vendor 26, 3902
#
# 贝尔 BELL-ALC extern Vendor Attrib
# Vendor 26, 6527
#
# 海蜘蛛 HISPIDER extern Vendor Attrib
# Vendor 26, 16010
# ...
参考材料:
认证报文RFC参考 RFC2865: https://www.rfc-editor.org/rfc/rfc2865
计费报文RFC参考 RFC2866:https://www.rfc-editor.org/rfc/rfc2866
动态授权(DM和COA)RFC参考 RFC3576:https://www.rfc-editor.org/rfc/rfc3576
认证请求的CHAP参考:https://www.cnblogs.com/voipman/p/5047912.html
认证请求报文的PAP参考:https://www.cnblogs.com/voipman/p/5345320.html
PPPoE的参考:https://www.cnblogs.com/voipman/p/pppoe.html
【协议】AAA Radius协议的常用报文分析的更多相关文章
- http协议请求报文与响应报文分析
什么是HTTP协议: HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到 不断地完善和扩展.目前在WWW中使用 ...
- 【转】 浅谈Radius协议
浅谈Radius协议 2013-12-03 16:06 5791人阅读 评论(0) 收藏 举报 分类: Radius协议分析(6) 从事Radius协议开发有段时间了,小弟不怕才疏学浅,卖弄一下, ...
- 转:浅谈Radius协议 -来自CSDN:http://blog.csdn.net/wangpengqi/article/details/17097221
浅谈Radius协议 2013-12-03 16:06 5791人阅读 评论(0) 收藏 举报 分类: Radius协议分析(6) 从事Radius协议开发有段时间了,小弟不怕才疏学浅,卖弄一下, ...
- 无线局域网中RADIUS协议原理与实现
转载自:http://blog.csdn.net/jinhill/article/details/5901042 摘要 RADIUS协议是一个被广泛应用于网络认证.授权和计费的协议.本文在介绍了RA ...
- OpenFlow协议1.0及1.3版本分析
OpenFlow是SDN控制器和交换之间交流的协议,在SDN领域有着十分重要的地位. OpenFlow协议发展到现在已经经过了1.0.1.3.1.4等版本.其中1.0和1.3版本使用的是最为广泛的. ...
- HTTP协议、HTTP协议原理分析
百度百科中说明: 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准.设计HTTP最初的目的是为 ...
- IP封包协议头/TCP协议头/TCP3次握手/TCP4次挥手/UDP协议头/ICMP协议头/HTTP协议(请求报文和响应报文)/IP地址/子网掩码(划分子网)/路由概念/MAC封包格式
IP协议头IP包头格式: 1.版本号:4个bit,用来标识IP版本号.这个4位字段的值设置为二进制的0100表示IPv4,设置为0110表示IPv6.目前使用的IP协议版本号是4. 2.首部长度:4个 ...
- Radius协议-学习
目录 RFC Radius 协议 Radius-学习 RADIUS协议的主要特征 客户端/服务器模式 安全的消息交互机制 良好的扩展性 AAA介绍 C/S结构 RADIUS在协议栈中的位置 RADIU ...
- 网络协议 12 - HTTP 协议:常用而不简单
系列文章传送门: 网络协议 1 - 概述 网络协议 2 - IP 是怎么来,又是怎么没的? 网络协议 3 - 从物理层到 MAC 层 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校 网 ...
随机推荐
- 续PA协商过程
续PA协商过程 当sw3的接口恢复之后会发生2中情况. ①sw3的G0/0/2口先发BPDU ②sw3的G0/0/3口先发BPDU sw3先发送BPDU sw3和sw1的交互过程: sw3的2口恢复后 ...
- Servlet核心技术
一.基本概念 1.C/S C/S架构是客户端服务器架构,将需要处理的业务合理的分配到客户端和服务器,客户端负责与用户的交互任务,服务器负责数据管理. 优点: 客户端界面和功能可以很丰富 应用服务器负荷 ...
- 你真的了解 Session 和 Cookie 吗?
我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. 前言 ...
- Redis的持久化机制你学会了吗
大家都知道Redis经常被使用在缓存的场景中,那有没有想过这么一个问题,一旦服务器宕机,内存中的数据全部丢失,我们该如何进行恢复呢?如果直接从后端数据库恢复,不仅会给数据库带来巨大的压力,还会使上层应 ...
- Collection集合工具类
Ⅷ.Collections 工具类 java.util.Collections Collections 集合工具类,用来对集合进行操作,部分重要方法如下: 1.public static <T& ...
- 简单快速安装Apache+PHP+MySql服务环境(一)
由于自己只是普通的coder,对于服务器的操作不是很熟悉,在网上找了很多关于PHP和apache服务器环境搭建的帖子,不过都不尽相同,尤其是编译安装更是看的云里雾里的,所以选择了一种比较简单的方式进行 ...
- Nodejs 处理异步(获取异步数据并处理)的方法
方法1. 回调函数方式 将异步方法如readFile封装到一个自定义函数中,通过将异步方法得到的结果传给自定义方法的回调函数参数.具体如下(以fs模块的readFile方法为例): //封装 var ...
- PostgreSQL-WITH AS短语
WITH提供了一种方式来书写在一个大型查询中使用的辅助语句.这些语句通常被称为公共表表达式或CTE,它们可以被看成是定义只在一个查询中存在的临时表.在WITH子句中的每一个辅助语句可以是一个SELEC ...
- python里面的垃圾回收机制
文章链接:https://www.jianshu.com/p/1e375fb40506 Garbage collection(GC) 现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c ...
- 基于BIT数组实现全局功能开关
前提 某一天巧合打开了sofa-bolt项目,查找部分源码,看到了项目中使用bit数组实现功能开关的特性,感觉这种方式可以借鉴,于是写下这篇文章. 原理 bit数组的布局如下: 由于每个bit都可以表 ...