1. 程式人生 > >在freeradius中將routeros中的撥號使用者踢下線的方法

在freeradius中將routeros中的撥號使用者踢下線的方法

PHP交流群:294088839,

Python交流群:652376983

先在ros的終端中輸入引用:

/radius incoming set accept=yes這樣將開啟routeros的斷線請求訊息,並監聽在埠udp 1700。
然後使用radclient構造一個踢人的資料包。
格式如下:引用:
echo "Acct-Session-Id=8100000c" > packet.txt
echo "User-Name=gtr" >> packet.txt
echo "Framed-IP-Address = 10.12.255.248" >> packet.txt

cat packet.txt | radclient -x 192.168.50.180:1701 disconnect 123解釋如下:
Acct-Session-Id=8100000c ,8100000c 是freeradius使用的資料庫中radacct表的AcctSessionld欄位的值,表示這個撥號使用者的會話ID。
User-Name=gtr                ,gtr是撥號使用者的使用者名稱。
Framed-IP-Address = 10.12.255.248 ,10.12.255.248是此撥號使用者獲取的IP地址。

radclient -x 192.168.50.180:1701 disconnect 123中,192.168.50.180:1701是routeros的IP地址和監聽的埠,disconnect 表示傳送斷線訊息,123是與radius與routeros 的通訊金鑰。

當執行此命令後,輸出:引用:
[

[email protected] ~]# echo "Acct-Session-Id=8100000c" > packet.txt
[[email protected] ~]# echo "User-Name=gtr" >> packet.txt
[[email protected] ~]# echo "Framed-IP-Address = 10.12.255.248" >> packet.txt
[[email protected] ~]# cat packet.txt | radclient -x 192.168.50.180:1701 disconnect 123
Sending Disconnect-Request of id 83 to 192.168.50.180 port 1701
        Acct-Session-Id = "8100000c"
        User-Name = "gtr"
        Framed-IP-Address = 10.12.255.248
rad_recv: Disconnect-ACK packet from host 192.168.50.180:1701, id=83, length=36
        NAS-Identifier = "MikroTik"
        NAS-IP-Address = 192.168.50.180
[
[email protected]
~]#馬上就可以看到撥號使用者被踢下線


在Steel-Belted-Radius中將routeros中的撥號使用者踢下線的方法查閱了無數次的資料,參照了太美老大的文章,終於在windows下、在Steel-Belted-Radius中實現了將routeros中的撥號使用者踢下線。
  這段時間在給別人做國外VPN代理伺服器管理(通過radius認證實現管理多臺伺服器),VPN伺服器用的是routeros,radius伺服器用的是Steel-Belted-Radius,通過sql server 2000和asp,實現web管理。但是這裡有一個令大家都頭痛的難題,就是:怎樣強制到期使用者下線。看了太美老大的文章後,終於看到了希望。想通過抓包,然後程式設計實現。不過太美老大的文章講的是linux下的實現方法,我不想費勁安裝一個linux,所以在windows下安裝了freeradius for windows,網上找不到配置資料,今天早上瞎搗鼓了半天,終於可以實現認證了,用了太美的方法實現強制斷線,也抓到了udp資料包,終於可以程式設計實現了。不過,我後來發現了更省事的辦法,就是把radclient.exe和cygwin1.dll這2個檔案拷到裝有Steel-Belted-Radius的機器中,同時把freeradius中的etc和share資料夾也拷過去,注意,這些檔案和資料夾一定要按照原來的目錄結構放好,然後就可以以這樣的命令實現強制斷線了:
echo User-Name=ppp7  | radclient.exe -d ../etc/raddb -x 192.168.0.1:1700 disconnect vpn
  命令含義,太美的文章中都有,這裡就是多加了一個引數:-d ../etc/raddb ,是用來說明各種radius裝置的協議標準的檔案所在的目錄的。另外,命令中只需指定需要強制斷線的使用者名稱就行了,其他引數可以省略。
  到這裡,基本功能已經實現,接下來就可以使用簡單的程式設計方法,自動定時到資料庫裡查詢,發現到期使用者,用shell(以VB為例)的方法向VPN伺服器發出命令……
echo User-Name=bbbb | radclient 192.168.8.1:1700 disconnect testing123

======================================
FreeRADIUS+Postgresql+OpenVPN續:流量控制
http://ttz.im/blog/2010/07/272
======================================

實質上很簡單,就是求和+if判斷,枉自研究了半天的rlm_sql_counter

示例的是每月限制流量,針對使用者組

1. 設定限制

radgroupreply組裡面插入一行,命令如下:
insert into radgroupreply (groupname, attribute, op, value) values ('user','Max-Monthly-Traffic', ':=', '5368709120'); 
以上命令表示對使用者組user限制流量為5G,單位是bytes

同時還要加入Acct-Interim-Interval,該引數是定義讓OpenVPN plugin更新流量記錄的間隔,必須是為300-3600秒之間的一個值

2. 判斷命令

修改/etc/freeradius/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) FROM radacct WHERE username='%{User-Name}' AND date_trunc('day', acctstarttime) >= date_trunc ('month', current_date) AND date_trunc('day', acctstoptime) < = last_day(current_date);}" >= "%{sql: SELECT value FROM radgroupreply WHERE groupname='%{Group-Name}' AND attribute='Max-Monthly-Traffic';}") {

reject


該行作用是使用者連線時檢查本月內上下行流量之和(1日-月末,acctinputoctet+acctoutputoctet),與限制相比較,如果相同或超過則拒絕認證。

中間使用了自定義函式last_day,所以需要在pgsql中定義。

3. 定義日期函式

來自http://wiki.postgresql.org/wiki/Date_LastDay
CREATE OR REPLACE FUNCTION last_day(date) RETURNS date AS $$

SELECT (date_trunc('MONTH', $1) + INTERVAL '1 MONTH - 1 day')::date; $$ LANGUAGE 'sql' IMMUTABLE STRICT; 
4. 定義Max-Monthly-Traffic

由於這不是Freeradius自帶的屬性,所以需要在dictionary中定義,否則freeradius不會去讀這個屬性

修改/etc/freeradius/dictionary


加入


Attribute Max-Monthly-Traffic 3003 integer 


重啟大功告成。試驗的話把流量限制改成1,應該會被拒絕連線。



bug:如果使用者一直不斷開連線的話就無法拒絕認證了……FreeRADIUS不能踢人下線的。OpenVPN plugin的作者建議在openvpn.conf里加入reneg-sec xx讓使用者定時重新驗證,同時在radiusplugin.cnf中使用useauthcontrolfile=true讓使用者在驗證時不掉線。不過在實驗中useauthcontrolfile=true這條始終沒成功過,不知道是什麼原因。


ihipop says:

May 23, 2011 at 1:45 pm

啟用useauthcontrolfile有兩個條件

1.OpenVPN (>= 2.1 rc8)
2.tmp-dir對OpenVPN使用者有寫入許可權(預設是openvpn的配置檔案目錄) 

這是文獻 http://ihipop.info/2011/05/2434.html

Reply



ihipop says:

May 25, 2011 at 8:42 am

另外 我測試了 開始useauthcontrolfile=true的情況下 如果Simultaneous-Use 為1 發生重協商 也還是會掉線 Radius會認為你已經線上了 返回You are already logged in - access denied 把reneg-sec設定為0能解決這個問題 但是也犧牲了安全性

Reply



ihipop says:

May 25, 2011 at 8:57 am

而且我還發現一個問題 開啟useauthcontrolfile=true後 即使Simultaneous-Use 為1 發生重協商錯誤掉線後 radius裡面沒記錄了 但是到下次重協商 radius裡面因為已經沒記錄了 所以會通過 但是不會在radius裡面寫入登入狀態 導致radius裡面顯示不線上 實際上他線上。
到這裡 使用useauthcontrolfile=true讓使用者在驗證時不掉線。才真正顯現。不過那樣也就不能讓使用者進行計費了
真糾結。 

Reply



jack says:

July 7, 2011 at 11:11 pm

這種判斷有BUG,當用戶的history>500條時連線就會出現使用者名稱和密碼錯誤,實際上是因為記錄過多select計算延遲導致的

Reply


tony says:

July 8, 2011 at 7:26 am

求更好的方法

Reply


jack says:

July 11, 2011 at 6:42 am

我也再找更好的...

Reply


tony says:

July 11, 2011 at 7:16 am

差不多要每使用者每天>16條記錄(16x30=480<500)才會出現你說的問題,暫時不擔心這個……

Reply





SivaCoHan says:

July 15, 2011 at 1:15 pm

優化資料庫。儘量使用資料庫程式設計而不是通過外部傳入資料庫。能用一個sql完成的儘量不要用兩條。每次建立sql連線都是需要時間的。


===================================
freeradius清除線上使用者 + routeros
http://#.com/coconutnut/item/34d75c45a479b52210ee1ee1
===================================
/radius incoming set accept=yes

幹掉freeradius線上使用者!!
radzap -x -u test 192.168.11.207 routerostesting

把 路由中的線上使用者幹掉:
echo "user-name=test" | radclient -x 192.168.11.1:1700 disconnect routerostesting