【Python】模拟radius coa报文

Radius协议中网关设备NAS是client,实现radius协议的服务为服务端(例如freeradius),这种情况下radius server并不能主动给NAS发送信息。在 rfc3576 Dynamic Authorization Extensions to RADIUS 中定义了一种radius的拓展,叫做 Change-of-Authorization (CoA) ,通过这个协议就可以从radius server主动给 radius client发起请求,例如用户下线,用户上网带宽动态修改等需求就可以通过COA来完成。

下面就是用pyrad来完成一种COA的请求发送,需求是通过python发送COA给网关,网关正确应答ACK。

注意: pypi中的pyrad最新版本并没有实现coa,你可以通过github自行安装 pyrad : http://github.com/andreynpetrov/pyrad.git 这个版本有这部分实现。

COA中定义的code


40 - Disconnect-Request [RFC2882]   下线请求

41 - Disconnect-ACK [RFC2882]   下线确认

42 - Disconnect-NAK [RFC2882]    下线不正常

43 - CoA-Request [RFC2882]   coa请求

44 - CoA-ACK [RFC2882]   coa确认

45 - CoA-NAK [RFC2882]   coa不正常

Python模拟COA

这里的COA请求是网关设备厂商自定义的,用来完成用户认证,具体包结构定义只能参照rfc和厂家给的定义来实现,这里只记录下程序如何写的。调试中几个重要的点有: 网关厂商的字典,对于字典中厂商自定义字段的含义和值是否正确,防火墙是开启对应的白名单。 如果总是无法调通,请抓包对比,然后再测试。

#coding:utf-8
import socket, sys
import pyrad.packet
from pyrad.client import Client
from pyrad.dictionary import Dictionary

#NAS and Radius same 注意字典的加载
dict_dir = "./dictionary"
SECRET = "test"
NASIP = "172.16.15.188"

def send_coa_auth(uname, acl="auth_sla", qos="32M_Full"):
    """
        send coa message to NAS, the attributes are
        User-Name
        Calling-Station-Id
        Benu-ACL-Policy
        Benu-QoS-Policy
    """
    srv = Client(server=NASIP, secret=SECRET, dict=Dictionary(dict_dir))
    req = srv.CreateCoAPacket(code=pyrad.packet.CoARequest, User_Name=uname)
    req["Calling-Station-Id"] = uname
    req["NAS-IP-Address"] = NASIP
    req["Benu-ACL-Policy"] = acl  # Benu开头为厂商定义字段
    req["Benu-QoS-Policy"] = qos

    try:
        print "Sending COA request"
        reply = srv.SendPacket(req)
    except pyrad.client.Timeout:
        print "DAS(NAS or Bas) does not reply"
        return
    except socket.error, error:
        print "Network error: " + error[1]
        return

    if reply.code==pyrad.packet.CoAACK:
        print "Coa accepted"
    elif reply.code==pyrad.packet.CoANAK:
        print "Coa nak"
    else:
        print reply.code
    print "Attributes returned by NAS:"
    for i in reply.keys():
        print "%s: %s" % (i, reply[i][0])

if __name__ == "__main__":
    send_coa_auth("F8-CF-C5-83-09-B9")

'''
# python coa_auth.py
import settings failure
Sending COA request
Coa accepted
Attributes returned by NAS:
Event-Timestamp: 1452219598
'''

参考

使用python发送COA报文动态改变RADIUS用户属性 此博主有很多相关的研究,表示感谢

上一篇:”Validation of viewstate MAC failed” 错误


下一篇:如何把Python2的代码转换为Python3的代码