近期公司做一个项目,动态将用户从BAS踢下线及动态修改用户带宽。
由于里面涉及到Radius 3576协议,找了一些资料 如下:
A:中断消息(DM)
为了中断NAS上的用户会话,中断请求报文由RADIUS服务器发送。并丢弃所有关
联会话的上下文。中断请求报文发送到UDP端口3799,and identifies the NAS
+----------+ Disconnect-Request +----------+
| | <-------------------- | |
| NAS | | RADIUS |
| | Disconnect-Response | Server |
| | ---------------------> | |
+----------+ +----------+
NAS回应由RADIUS服务器发送的中断请求报文,如果所有的关联会话上下文被丢
弃并且用户会话不再连接,NAS回应Disconnect-ACK报文,如果NAS不能中断会
话和丢弃所有的关联会话上下文,NAS则发送Disconnect-NAK报文。如果
Disconnect-Request报文中包含值为“Authorize Only”的Service-Type属
性,则NAS必须(MUST)回应Disconnect-NAK报文,Disconnect-ACK报文必须不
能(MUST NOT)发送。如果Disconnect-Request报文中包含不支持的
Service-Type属性,则NAS必须(MUST)回应Disconnect-NAK报文,该报文可以
(MAY)包含值为“Unsupported Service”的Error-Cause属性。
Disconnect-ACK报文可以(MAY)包含值为6(Admin-Reset)的
Acct-Terminate-Cause属性(属性类型49,定义在[RFC2866])。
B:更改授权消息(CoA)
CoA-Request报文包含了动态更改会话授权的信息。通常使用在更改数据过滤
上。数据过滤可以是关于入口或者出口的,在额外的标识属性(标识入口或者
出口的??)中发送,在3章节描述。使用的端口和报文格式(在2.3节描述)
和Disconnect-Request消息相同。
下列属性可以(MAY)在CoA-Request报文中发送:
Filter-ID (11) - 表示应用在会话中的数据过滤列表的名称。
+----------+ CoA-Request +----------+
| | <-------------------- | |
| NAS | | RADIUS |
| | CoA-Response | Server |
| | ---------------------> | |
+----------+ +----------+
NAS在回应由RADIUS服务器发送的CoA-Request报文时,如果NAS能够成功地更改
用户会话的授权信息。NAS发送CoA-ACK报文。如果请求不成功时发送CoA-NAK报
文。如果CoA-Request报文中包含值为“Authorize Only”的Service-Type属
性,则NAS必须(MUST)回应CoA-NAK报文,CoA-ACK报文必须不能(MUST NOT)
发送。如果CoA-Request报文中包含不支持的Service-Type属性,则NAS必须
(MUST)回应CoA-NAK报文,该报文可以(MAY)包含值为“Unsupported
Service”的Error-Cause属性。
需要注意的一点就是,在向NAS 发DM 40Radius包时,创建Authonticator 进行MD5一定要进行清零操作。
3576 Radius Package:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Code | Identifier | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Authenticator |
| |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attributes ...
+-+-+-+-+-+-+-+-+-+-+-+-+-
example:
protected byte[] create2866RequestAuthonticator(String sharedSecret, int packetLength, byte[] attributes){
MessageDigest md5 = getMd5Digest();
byte [] requestAuthenticator = new byte [16];
for (int i = 0; i < 16; i++){
requestAuthenticator[i] = 0;
}
md5.reset();
md5.update((byte)getPacketType());
md5.update((byte)getPacketIdentifier());
md5.update((byte)(packetLength >>
);
md5.update((byte)(packetLength & 0xff));
md5.update(requestAuthenticator, 0, requestAuthenticator.length);
md5.update(attributes, 0, attributes.length);
md5.update(sharedSecret.getBytes());
return md5.digest();
}