第十四节:Daloradius限制上网流量
本节内容主要通过在Daloradius下配置Freeradius,可以按月限制用户的流量,Freeradius本身没有内置限制用户每个月最大流量的功能。网上有很多类似的文章,但是都是针对freeradius版本2的文档。由于版本3在很多地方与2有细微差别,直接用版本2的设置方法是行不通的。
这里总结整理了freeradius3的环境下每月流量限制功能的设置方法
1、增加radius自定义属性
编辑字典文件:
vi /etc/raddb/dictionary
在最下方增加两行自定义属性
ATTRIBUTE Max-Monthly-Traffic 3003 integer ATTRIBUTE Monthly-Traffic-Limit 3004 integer
2、配置计数器SQL
1)新建月流量的计数器sql语句,下面的文件没有需要新增
vi /etc/raddb/mods-config/sql/counter/mysql/monthlytrafficcounter.conf
内容如下
query = "SELECT SUM(acctinputoctets + acctoutputoctets) DIV 1048576 FROM radacct WHERE UserName='%{${key}}' AND UNIX_TIMESTAMP(AcctStartTime) > '%%b'"
重要说明:在radius 中的结果是以B来统计的,上面的语句中查询结果除以 1048576 将单位转换为MB,如果此处不 除以 1048576 ,最大只能限制2G,因为 int 最大为 2G
1KB=1024B;
1MB=1024KB=1024×1024B=1048576B
2)在sqlcounter模块中增加新的计数器
编辑sqlcounter文件
vi /etc/raddb/mods-available/sqlcounter
在最下面一行追加以下内容,注意,如果本文件中有其他内容,请注视掉
sqlcounter monthlytrafficcounter { sql_module_instance = sql #dialect = ${modules.sql.dialect} dialect = "mysql" counter_name = Monthly-Traffic check_name = Max-Monthly-Traffic reply_name = Monthly-Traffic-Limit key = User-Name reset = monthly $INCLUDE ${modconfdir}/sql/counter/${dialect}/${.:instance}.conf }
启用sqlcounter模块
cd /etc/raddb/mods-enabled ln -s ../mods-available/sqlcounter sqlcounter
3、将monthlytrafficcounter模块添加到用户认证过程中
编辑以下文件
vi /etc/raddb/sites-enabled/default
在authorize部分中的sql后面,添加monthlytrafficcounter,例如:
authorize { ... sql # check monthly usage limit monthlytrafficcounter ... }
注意:monthlytrafficcounter 一定要放在sql的下方,否则不生效,在很多教程中没有说明这一点
4、重启radiusd
1)重启服务(或者先用radiusd -X模式进行调试)
systemctl restart radiusd
2)故障排除,某些时候radiusd重启后,会出现以下错误
/etc/freeradius/mods-enabled/sqlcounter[43]: Reference "${modules.sql.dialect}" not found
错误分析:这个错误的原因是在sqlcounter里面调用了sql模块里面的dialect变量。如果模块的启动顺序出现了启动sqlcounter时,sql还没有被加载的情况,就会导致这个变量获取不到。
解决思路一:是在/etc/raddb/radiusd.conf中的instantiate部分指定模块的启动顺序;
解决思路二:简单粗暴的方式,直接在sqlcounter中将所有的dialect都指定为’mysql’。例如:
sqlcounter dailycounter { sql_module_instance = sql #dialect = ${modules.sql.dialect} dialect = "mysql" counter_name = Daily-Session-Time check_name = Max-Daily-Session reply_name = Session-Timeout key = User-Name reset = daily $INCLUDE ${modconfdir}/sql/counter/${dialect}/${.:instance}.conf }
5、对目标用户或者组设置限量属性
例如:增加mygroup组,对这个组限制每个月最大流量为1GB(1024MB)此处的单位已经转换为MB了。如果用户已经超过这个使用量,认证将失败。
在radius数据库的check表以及reply表中,分别添加以下两条记录(也可以使用第三方的radius操作界面进行操作,例如daloradius系统)
# 在数据库中限制用户组的最大流量为1GB(本例中的用户组名为mygroup) mysql> INSERT INTO radgroupcheck (groupname,attribute,op,VALUE) VALUES ('mygroup','Max-Monthly-Traffic',':=','1024'); # 流量统计时间的间隔(60秒) mysql> INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('mygroup','Acct-Interim-Interval',':=','60');
如果用户使用量已经超过限制,radius认证会失败。使用radtest调试,可以看到返回的信息
返回的错误信息样例:
Sending Access-Request Id 219 from 0.0.0.0:40100 to 127.0.0.1:1812 User-Name = 'myusername' User-Password = 'mypassword' NAS-IP-Address = 172.16.241.135 NAS-Port = 0 Message-Authenticator = 0x00 Received Access-Reject Id 219 from 127.0.0.1:1812 to 127.0.0.1:40100 length 70 Reply-Message = 'Your maximum monthly usage time has been reached' (0) -: Expected Access-Accept got Access-Reject
6、【可选】为daloRadius系统添加dictionary辅助定义
使用daloRadius管理界面管理为用户或组添加属性时,选择Vendor的下拉框可以很方便的选择属性。对于自定义的属性,也可以使用SQL语句添加到dictionary表里使其出现在下拉列表里
INSERT INTO dictionary (Type, Attribute,Vendor, RecommendedOP,RecommendedTable,RecommendedHelper,RecommendedTooltip) VALUES ('integer','Max-Monthly-Traffic','dictionary.freeradius.vpntraffic', ':=', 'check', 'The traffic of user per month', '1024=1G'); INSERT INTO dictionary (Type, Attribute,Vendor, RecommendedOP,RecommendedTable,RecommendedHelper,RecommendedTooltip) VALUES ('integer','Monthly-Traffic-Limit','dictionary.freeradius.vpntraffic', ':=', 'reply', 'The traffic of user per month', '1024=1G');