PPTP-***第三章——用户流量与并发数限制

在前面两篇文章中详细介绍了pptp ***的安装与使用,以及如何配置用户认证存入mysql数据库。本文将在前面两篇文章的基础上介绍如何对用户的流量做限制,同时限制相同账号的用户,同一时刻的在线数为1

前文传送门地址:

PPTP-***部署与简单使用   http://ylw6006.blog.51cto.com/470441/1794577

PPTP-***使用mysql进行用户登录认证 http://ylw6006.blog.51cto.com/470441/1795201

 

一、向mysql库表中插入基础数据

mysql> use radius
mysql> INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Auth-Type',':=','Local'); 
mysql> INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Service-Type',':=','Framed-User'); 
mysql> INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Framed-IP-Address',':=','255.255.255.255'); 
mysql> INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Framed-IP-Netmask',':=','255.255.255.0'); 
mysql> INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Acct-Interim-Interval',':=','600');
mysql> INSERT INTO radgroupreply (groupname,attribute,op,VALUE) VALUES ('user','Max-Monthly-Traffic',':=','20480'); 
mysql> INSERT INTO radgroupcheck (groupname,attribute,op,VALUE) VALUES ('user','Simultaneous-Use',':=','1');

wKioL1d7Fh_j708bAABaWAdUsiw601.png-wh_50

acct-interim-interval是计算流量的间隔(600秒),意味着每隔10分钟记录当前流量;

Max-Monthly-Traffic是每月最大流量,这里是20G(单位是M;

radgroupcheck表的Simultaneous-Use表示单个用户的同时连接数目;

这里要格外注意的是,许多网络上的文章介绍Max-Monthly-Traffic单位为字节,数值为5368709102,换算一下大概5G左右,而如果我们也精确到字节,数值设为20G,也就是21474836480,则用户拨入进行身份验证的时候将会报错。因而此次我们将流量限制的精度单位修改为M。详细可参考如下链接介绍:http://www.xj123.info/2856.html

wKioL1d7GMzRpnRJAABzg6gARtU427.png-wh_50

二、修改配置文件

1、修改/etc/raddb/sites-enabled/default文件,添加流量限制的reject条件

# vi  /etc/raddb/sites-enabled/default 
#找到authorize一节插入如下内容:
update request { 
    Group-Name := "%{sql:SELECT groupname FROM radusergroup WHERE username='%{User-Name}' ORDER BY priority}" 
    } 
    if ("%{sql: SELECT SUM(acctinputoctets+acctoutputoctets) div 1048576 FROM radacct WHERE username='%{User-Name}' AND date_format(acctstarttime, '%Y-%m-%d') >= date_format(now(),'%Y-%m-01') AND date_format(acctstoptime, '%Y-%m-%d') <= last_day(now());}" >= "%{sql: SELECT value FROM radgroupreply WHERE groupname='%{Group-Name}' AND attribute='Max-Monthly-Traffic';}") { 
    reject 
    }

2、由于使用了非内置的attribute Max-Monthly-Traffic,所以需要在/etc/raddb/dictionary里面定义

# tail -1 /etc/raddb/dictionary 
ATTRIBUTE       Max-Monthly-Traffic     3003    integer

3、修改/etc/raddb/sql/mysql/dialup.conf文件,开启在线用户数检查

# vi  /etc/raddb/sql/mysql/dialup.conf 
sql_user_name = "%{%{Stripped-User-Name}:-%{%{User-Name}:-DEFAULT}}"
#sql_user_name = "%{User-Name}"  #注释掉这行
 
# Uncomment simul_count_query to enable simultaneous use checking 
        simul_count_query = "SELECT COUNT(*) \
                             FROM ${acct_table1} \
                             WHERE username = '%{SQL-User-Name}' \
                             AND acctstoptime IS NULL"
 
        simul_verify_query  = "SELECT radacctid, acctsessionid, username, \
                               nasipaddress, nasportid, framedipaddress, \
                               callingstationid, framedprotocol \
                               FROM ${acct_table1} \
                               WHERE username = '%{SQL-User-Name}' \
                               AND acctstoptime IS NULL"

三、重启服务

# /etc/init.d/radiusd stop

# /etc/init.d/pptpd restart

四、测试

1、将rediusd服务运行在debug模式下,进行拨号测试,主要测试流量控制!

#radiusd -X

wKiom1d7GT3x5D5DAAE2LoNLrYU607.png-wh_50

通过上面可以看到当前的用户流量消耗为2M,限制流量的值为20480M

因而在/etc/raddb/sites-enabled/default文件,判断流量限制的reject条件的结果为false,用户可以通过验证,完成拨号!下面是详细的拨号日志:

rad_recv: Access-Request packet from host 127.0.0.1 port 49226, id=94, length=150
        Service-Type = Framed-User
        Framed-Protocol = PPP
        User-Name = "ptest1"
        MS-CHAP-Challenge = 0x6716c32940f1c84ad213d2d52df1712d
        MS-CHAP2-Response = 0x2400c77c090296803fb3c0822b8c679547f000000000000000001eb41fe8e518c1f756fb5d9d5904ddb8dc1fe271e98aa055
        Calling-Station-Id = "27.151.123.121"
        NAS-IP-Address = 127.0.0.1
        NAS-Port = 0
# Executing section authorize from file /etc/raddb/sites-enabled/default
+group authorize {
++update request {
sql_xlat
        expand: %{Stripped-User-Name} -> 
        ... expanding second conditional
        expand: %{User-Name} -> ptest1
        expand: %{%{User-Name}:-DEFAULT} -> ptest1
        expand: %{%{Stripped-User-Name}:-%{%{User-Name}:-DEFAULT}} -> ptest1
sql_set_user escaped user --> 'ptest1'
        expand: SELECT groupname FROM radusergroup WHERE username='%{User-Name}' ORDER BY priority -> SELECT groupname FROM radusergroup WHERE username='ptest1' ORDER BY priority
rlm_sql (sql): Reserving sql socket id: 30
sql_xlat finished
rlm_sql (sql): Released sql socket id: 30
        expand: %{sql:SELECT groupname FROM radusergroup WHERE username='%{User-Name}' ORDER BY priority} -> user
++} # update request = noop
++? if ("%{sql: SELECT SUM(acctinputoctets+acctoutputoctets) div 1048576 FROM radacct WHERE username='%{User-Name}' AND date_format(acctstarttime, '%Y-%m-%d') >= date_format(now(),'%Y-%m-01') AND date_format(acctstoptime, '%Y-%m-%d') <= last_day(now());}" >= "%{sql: SELECT value FROM radgroupreply WHERE groupname='%{Group-Name}' AND attribute='Max-Monthly-Traffic';}")
sql_xlat
        expand: %{Stripped-User-Name} -> 
        ... expanding second conditional
        expand: %{User-Name} -> ptest1
        expand: %{%{User-Name}:-DEFAULT} -> ptest1
        expand: %{%{Stripped-User-Name}:-%{%{User-Name}:-DEFAULT}} -> ptest1
sql_set_user escaped user --> 'ptest1'
        expand:  SELECT SUM(acctinputoctets+acctoutputoctets) div 1048576 FROM radacct WHERE username='%{User-Name}' AND date_format(acctstarttime, '%Y-%m-%d') >= date_format(now(),'%Y-%m-01') AND date_format(acctstoptime, '%Y-%m-%d') <= last_day(now()); ->  SELECT SUM(acctinputoctets+acctoutputoctets) div 1048576 FROM radacct WHERE username='ptest1' AND date_format(acctstarttime, '2016-06-30') >= date_format(now(),'2016-06-01') AND date_format(acctstoptime, '2016-06-30') <= last_day(now());
rlm_sql (sql): Reserving sql socket id: 29
sql_xlat finished
rlm_sql (sql): Released sql socket id: 29
        expand: %{sql: SELECT SUM(acctinputoctets+acctoutputoctets) div 1048576 FROM radacct WHERE username='%{User-Name}' AND date_format(acctstarttime, '%Y-%m-%d') >= date_format(now(),'%Y-%m-01') AND date_format(acctstoptime, '%Y-%m-%d') <= last_day(now());} -> 2
sql_xlat
        expand: %{Stripped-User-Name} -> 
        ... expanding second conditional
        expand: %{User-Name} -> ptest1
        expand: %{%{User-Name}:-DEFAULT} -> ptest1
        expand: %{%{Stripped-User-Name}:-%{%{User-Name}:-DEFAULT}} -> ptest1
sql_set_user escaped user --> 'ptest1'
        expand:  SELECT value FROM radgroupreply WHERE groupname='%{Group-Name}' AND attribute='Max-Monthly-Traffic'; ->  SELECT value FROM radgroupreply WHERE groupname='user' AND attribute='Max-Monthly-Traffic';
rlm_sql (sql): Reserving sql socket id: 28
sql_xlat finished
rlm_sql (sql): Released sql socket id: 28
        expand: %{sql: SELECT value FROM radgroupreply WHERE groupname='%{Group-Name}' AND attribute='Max-Monthly-Traffic';} -> 20480
? Evaluating ("%{sql: SELECT SUM(acctinputoctets+acctoutputoctets) div 1048576 FROM radacct WHERE username='%{User-Name}' AND date_format(acctstarttime, '%Y-%m-%d') >= date_format(now(),'%Y-%m-01') AND date_format(acctstoptime, '%Y-%m-%d') <= last_day(now());}" >= "%{sql: SELECT value FROM radgroupreply WHERE groupname='%{Group-Name}' AND attribute='Max-Monthly-Traffic';}") -> FALSE
++? if ("%{sql: SELECT SUM(acctinputoctets+acctoutputoctets) div 1048576 FROM radacct WHERE username='%{User-Name}' AND date_format(acctstarttime, '%Y-%m-%d') >= date_format(now(),'%Y-%m-01') AND date_format(acctstoptime, '%Y-%m-%d') <= last_day(now());}" >= "%{sql: SELECT value FROM radgroupreply WHERE groupname='%{Group-Name}' AND attribute='Max-Monthly-Traffic';}") -> FALSE
++[preprocess] = ok
++[chap] = noop
[mschap] Found MS-CHAP attributes.  Setting 'Auth-Type  = mschap'
++[mschap] = ok
++[digest] = noop
[suffix] No '@' in User-Name = "ptest1", looking up realm NULL
[suffix] No such realm "NULL"
++[suffix] = noop
[eap] No EAP-Message, not doing EAP
++[eap] = noop
[sql]   expand: %{Stripped-User-Name} -> 
[sql]   ... expanding second conditional
[sql]   expand: %{User-Name} -> ptest1
[sql]   expand: %{%{User-Name}:-DEFAULT} -> ptest1
[sql]   expand: %{%{Stripped-User-Name}:-%{%{User-Name}:-DEFAULT}} -> ptest1
[sql] sql_set_user escaped user --> 'ptest1'
rlm_sql (sql): Reserving sql socket id: 27
[sql]   expand: SELECT id, username, attribute, value, op           FROM radcheck           WHERE username = '%{SQL-User-Name}'           ORDER BY id -> SELECT id, username, attribute, value, op           FROM radcheck           WHERE username = 'ptest1'           ORDER BY id
WARNING: Found User-Password == "...".
WARNING: Are you sure you don't mean Cleartext-Password?
WARNING: See "man rlm_pap" for more information.
[sql] User found in radcheck table
[sql]   expand: SELECT id, username, attribute, value, op           FROM radreply           WHERE username = '%{SQL-User-Name}'           ORDER BY id -> SELECT id, username, attribute, value, op           FROM radreply           WHERE username = 'ptest1'           ORDER BY id
[sql]   expand: SELECT groupname           FROM radusergroup           WHERE username = '%{SQL-User-Name}'           ORDER BY priority -> SELECT groupname           FROM radusergroup           WHERE username = 'ptest1'           ORDER BY priority
[sql]   expand: SELECT id, groupname, attribute,           Value, op           FROM radgroupcheck           WHERE groupname = '%{Sql-Group}'           ORDER BY id -> SELECT id, groupname, attribute,           Value, op           FROM radgroupcheck           WHERE groupname = 'user'           ORDER BY id
[sql] User found in group user
[sql]   expand: SELECT id, groupname, attribute,           value, op           FROM radgroupreply           WHERE groupname = '%{Sql-Group}'           ORDER BY id -> SELECT id, groupname, attribute,           value, op           FROM radgroupreply           WHERE groupname = 'user'           ORDER BY id
rlm_sql (sql): Released sql socket id: 27
++[sql] = ok
++[expiration] = noop
++[logintime] = noop
[pap] WARNING: Auth-Type already set.  Not setting to PAP
++[pap] = noop
+} # group authorize = ok
Found Auth-Type = MSCHAP
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!    Replacing User-Password in config items with Cleartext-Password.     !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! Please update your configuration so that the "known good"               !!!
!!! clear text password is in Cleartext-Password, and not in User-Password. !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Executing group from file /etc/raddb/sites-enabled/default
+group MS-CHAP {
[mschap] Creating challenge hash with username: ptest1
[mschap] Client is using MS-CHAPv2 for ptest1, we need NT-Password
[mschap] adding MS-CHAPv2 MPPE keys
++[mschap] = ok
+} # group MS-CHAP = ok
# Executing section session from file /etc/raddb/sites-enabled/default
+group session {
[radutmp]       expand: /var/log/radius/radutmp -> /var/log/radius/radutmp
++[radutmp] = ok
+} # group session = ok
# Executing section post-auth from file /etc/raddb/sites-enabled/default
+group post-auth {
[sql]   expand: %{Stripped-User-Name} -> 
[sql]   ... expanding second conditional
[sql]   expand: %{User-Name} -> ptest1
[sql]   expand: %{%{User-Name}:-DEFAULT} -> ptest1
[sql]   expand: %{%{Stripped-User-Name}:-%{%{User-Name}:-DEFAULT}} -> ptest1
[sql] sql_set_user escaped user --> 'ptest1'
[sql]   expand: %{User-Password} -> 
[sql]   ... expanding second conditional
[sql]   expand: %{Chap-Password} -> 
[sql]   expand: INSERT INTO radpostauth                           (username, pass, reply, authdate)                           VALUES (                           '%{User-Name}',                           '%{%{User-Password}:-%{Chap-Password}}',                           '%{reply:Packet-Type}', '%S') -> INSERT INTO radpostauth                           (username, pass, reply, authdate)                           VALUES (                           'ptest1',                           '',                           'Access-Accept', '2016-06-30 13:05:14')
rlm_sql (sql) in sql_postauth: query is INSERT INTO radpostauth                           (username, pass, reply, authdate)                           VALUES (                           'ptest1',                           '',                           'Access-Accept', '2016-06-30 13:05:14')
rlm_sql (sql): Reserving sql socket id: 26
rlm_sql (sql): Released sql socket id: 26
++[sql] = ok
++[exec] = noop
+} # group post-auth = ok
Sending Access-Accept of id 94 to 127.0.0.1 port 49226
        Service-Type := Framed-User
        Framed-IP-Address := 255.255.255.255
        Framed-IP-Netmask := 255.255.255.0
        Acct-Interim-Interval := 600
        MS-CHAP2-Success = 0x24533d46303044303641413737333432343231363234364143413245333041373133433531344439353037
        MS-MPPE-Recv-Key = 0x3373da01475488084e5f82abae7cbda8
        MS-MPPE-Send-Key = 0xdb408d5d7f18d9fd38e6c1888b8c0b13
        MS-MPPE-Encryption-Policy = 0x00000001
        MS-MPPE-Encryption-Types = 0x00000006
Finished request 0.
Going to the next request
Waking up in 4.9 seconds.
Cleaning up request 0 ID 94 with timestamp +88
Ready to process requests.
rad_recv: Accounting-Request packet from host 127.0.0.1 port 58801, id=95, length=114
        Acct-Session-Id = "5774A890092400"
        User-Name = "ptest1"
        Acct-Status-Type = Start
        Service-Type = Framed-User
        Framed-Protocol = PPP
        Calling-Station-Id = "27.151.123.121"
        Acct-Authentic = RADIUS
        NAS-Port-Type = Async
        Framed-IP-Address = 192.168.222.10
        NAS-IP-Address = 127.0.0.1
        NAS-Port = 0
        Acct-Delay-Time = 0
# Executing section preacct from file /etc/raddb/sites-enabled/default
+group preacct {
++[preprocess] = ok
[acct_unique] WARNING: Attribute NAS-Identifier was not found in request, unique ID MAY be inconsistent
[acct_unique] Hashing 'NAS-Port = 0,,NAS-IP-Address = 127.0.0.1,Acct-Session-Id = "5774A890092400",User-Name = "ptest1"'
[acct_unique] Acct-Unique-Session-ID = "413ac0cc5b5f4759".
++[acct_unique] = ok
[suffix] No '@' in User-Name = "ptest1", looking up realm NULL
[suffix] No such realm "NULL"
++[suffix] = noop
+} # group preacct = ok
# Executing section accounting from file /etc/raddb/sites-enabled/default
+group accounting {
[detail]        expand: %{Packet-Src-IP-Address} -> 127.0.0.1
[detail]        expand: /var/log/radius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d -> /var/log/radius/radacct/127.0.0.1/detail-20160630
[detail] /var/log/radius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d expands to /var/log/radius/radacct/127.0.0.1/detail-20160630
[detail]        expand: %t -> Thu Jun 30 13:05:20 2016
++[detail] = ok
[sql]   expand: %{Stripped-User-Name} -> 
[sql]   ... expanding second conditional
[sql]   expand: %{User-Name} -> ptest1
[sql]   expand: %{%{User-Name}:-DEFAULT} -> ptest1
[sql]   expand: %{%{Stripped-User-Name}:-%{%{User-Name}:-DEFAULT}} -> ptest1
[sql] sql_set_user escaped user --> 'ptest1'
[sql]   expand: %{Acct-Delay-Time} -> 0
[sql]   expand:            INSERT INTO radacct             (acctsessionid,    acctuniqueid,     username,              realm,            nasipaddress,     nasportid,              nasporttype,      acctstarttime,    acctstoptime,              acctsessiontime,  acctauthentic,    connectinfo_start,              connectinfo_stop, acctinputoctets,  acctoutputoctets,              calledstationid,  callingstationid, acctterminatecause,              servicetype,      framedprotocol,   framedipaddress,              acctstartdelay,   acctstopdelay,    xascendsessionsvrkey)           VALUES             ('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}',              '%{SQL-User-Name}',              '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}',              '%{NAS-Port-Type}', '%S', NULL,              '0', '%{Acct-Authentic}', '%{Connect-Info}',              '', '0', '0',              '%{Called-Station-Id}', '%{Calling-Station-Id}', '',              '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}',      
rlm_sql (sql): Reserving sql socket id: 25
rlm_sql (sql): Released sql socket id: 25
++[sql] = ok
++[exec] = noop
[attr_filter.accounting_response]       expand: %{User-Name} -> ptest1
attr_filter: Matched entry DEFAULT at line 12
++[attr_filter.accounting_response] = updated
+} # group accounting = updated
Sending Accounting-Response of id 95 to 127.0.0.1 port 58801
Finished request 1.
Cleaning up request 1 ID 95 with timestamp +94
Going to the next request
Ready to process requests.

2、测试同一个***账号,多终端登录

通过如下sql语句可以看到当前用户的拨号连接情况,很明显通过前面的配置,并没有起到限制的效果。

mysql> SELECT radacctid, acctsessionid, username,nasipaddress, nasportid, framedipaddress, callingstationid, framedprotocol FROM  radacct WHERE username ='yang' AND acctstoptime IS NULL;
mysql> SELECT COUNT(*) from radacct WHERE username ='yang' AND acctstoptime IS NULL;

wKioL1d7GY_iJ_iTAABwRxrgEXc801.png-wh_50

通过修改/etc/raddb/sites-enabled/default文件,注释掉session节的radutmp配置,重启radiusd服务后测试,发现效果符合预期

# vi /etc/raddb/sites-enabled/default 

wKioL1d7Ga7zHRStAAAV5SPkpNc187.png-wh_50

同一个账号的第二个拨号连接就会直接提示验证失败!

wKioL1d7GhHTQcDnAAA98nDwGzA282.jpg-wh_50

wKiom1d7GjHSyiNLAAGLjatTeWI572.png-wh_50

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值