PPTP-***第三章——用戶流量與併發數限制

在前面兩篇文章中詳細介紹了pptp ***的安裝與使用,以及如何配置用戶認證存入mysql數據庫。本文將在前面兩篇文章的基礎上介紹如何對用戶的流量作限制,同時限制相同帳號的用戶,同一時刻的在線數爲1html

前文傳送門地址:mysql

PPTP-×××部署與簡單使用   http://ylw6006.blog.51cto.com/470441/1794577sql

PPTP-×××使用mysql進行用戶登陸認證 http://ylw6006.blog.51cto.com/470441/1795201數據庫

 

1、向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分鐘記錄當前流量;session

Max-Monthly-Traffic是每個月最大流量,這裏是20G(單位是M;socket

radgroupcheck表的Simultaneous-Use表示單個用戶的同時鏈接數目;
ide

這裏要格外注意的是,許多網絡上的文章介紹Max-Monthly-Traffic單位爲字節,數值爲5368709102,換算一下大概5G左右,而若是咱們也精確到字節,數值設爲20G,也就是21474836480,則用戶撥入進行身份驗證的時候將會報錯。於是這次咱們將流量限制的精度單位修改成M。詳細可參考以下連接介紹:http://www.xj123.info/2856.html
oop

wKioL1d7GMzRpnRJAABzg6gARtU427.png-wh_50

2、修改配置文件post

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"

3、重啓服務

# /etc/init.d/radiusd stop

# /etc/init.d/pptpd restart

4、測試

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.

二、測試同一個×××帳號,多終端登陸

經過以下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

相關文章
相關標籤/搜索