ื”ื’ื“ืจื•ืช ืจืฉืช ืž- FreeRadius ื“ืจืš DHCP

ื”ื’ื“ืจื•ืช ืจืฉืช ืž- FreeRadius ื“ืจืš DHCP
ื”ื’ื™ืขื” ื”ืžืฉื™ืžื” ืœื”ืกื“ื™ืจ ื”ื ืคืงืช ื›ืชื•ื‘ื•ืช IP ืœืžื ื•ื™ื™ื. ืชื ืื™ ื”ื‘ืขื™ื”:

  • ืœื ื ื™ืชืŸ ืœืš ืฉืจืช ื ืคืจื“ ืœื”ืจืฉืื” - ืืชื” ืชืกืชืคืง ๐Ÿ˜‰
  • ืžื ื•ื™ื™ื ื—ื™ื™ื‘ื™ื ืœืงื‘ืœ ื”ื’ื“ืจื•ืช ืจืฉืช ื‘ืืžืฆืขื•ืช DHCP
  • ื”ืจืฉืช ื”ื™ื ื”ื˜ืจื•ื’ื ื™ืช. ื–ื” ื›ื•ืœืœ ืฆื™ื•ื“ PON ื•ืžืชื’ื™ื ืจื’ื™ืœื™ื ืขื ืื•ืคืฆื™ื” 82 ืžื•ื’ื“ืจืช ื•ื‘ืกื™ืกื™ WiFi ืขื ื ืงื•ื“ื•ืช ื—ืžื•ืช
  • ืื ื”ื ืชื•ื ื™ื ืื™ื ื ื ื•ืคืœื™ื ื‘ืืฃ ืื—ื“ ืžื”ืชื ืื™ื ืœื”ื ืคืงืช IP, ืขืœื™ืš ืœื”ื ืคื™ืง IP ืžืจืฉืช "ืื•ืจื—"

ื‘ืฆื“ ื”ื˜ื•ื‘: ืขื“ื™ื™ืŸ ื™ืฉ ืฉืจืช ื‘-FreeBSD ืฉื™ื›ื•ืœ "ืœืขื‘ื•ื“", ืื‘ืœ ื”ื•ื "ืจื—ื•ืง" ;), ืœื "ืžืžืฉ ื‘ืจืฉืช ื”ื–ื•".

ื™ืฉ ื’ื ืžื›ืฉื™ืจ ื ืคืœื ื‘ืฉื Mikrotik. ื“ื™ืื’ืจืžืช ื”ืจืฉืช ื”ื›ืœืœื™ืช ื”ื™ื ื‘ืขืจืš ื›ืš:

ื”ื’ื“ืจื•ืช ืจืฉืช ืž- FreeRadius ื“ืจืš DHCP

ืœืื—ืจ ืžื—ืฉื‘ื”, ื”ื•ื—ืœื˜ ืœื”ืฉืชืžืฉ ื‘- FreeRadius ื›ื“ื™ ืœื”ื ืคื™ืง ื”ื’ื“ืจื•ืช ืจืฉืช ืœืžื ื•ื™ื™ื. ื‘ืื•ืคืŸ ืขืงืจื•ื ื™, ื”ืกื›ื™ืžื” ื”ื™ื ืจื’ื™ืœื”: ืื ื• ืžืืคืฉืจื™ื ืืช ืฉืจืช ื”-DHCP ื‘-Microtick, ื•ืืช Radius Client ื‘ื•. ืื ื• ืžื’ื“ื™ืจื™ื ืืช ืฉืจืช ื”-DHCP -> Radius Client -> ื—ื™ื‘ื•ืจ ืฉืจืช Radius.

ื–ื” ืœื ื ืจืื” ืงืฉื”. ืื‘ืœ! ื”ืฉื˜ืŸ ื ืžืฆื ื‘ืคืจื˜ื™ื. ื›ืœื•ืžืจ:

  • ื‘ืขืช ื”ืจืฉืืช PON OLT ื‘ืืžืฆืขื•ืช ืกื›ื™ืžื” ื–ื•, ื‘ืงืฉื” ื ืฉืœื—ืช ืœ-FreeRadius ืขื ืฉื ืžืฉืชืžืฉ ื”ืฉื•ื•ื” ืœื›ืชื•ื‘ืช ื”-MAC ืฉืœ ื”-headend, Agent-Circuit-Id ื”ืฉื•ื•ื” ืœ-MAC PON Onu ื•ืกื™ืกืžื” ืจื™ืงื”.
  • ื‘ืขืช ื”ืจืฉืื” ืžืชื’ื™ื ืขื ืืคืฉืจื•ืช 82, FreeRadius ืžืงื‘ืœ ื‘ืงืฉื” ืขื ืฉื ืžืฉืชืžืฉ ืจื™ืง ื”ืฉื•ื•ื” ืœ-MAC ืฉืœ ืžื›ืฉื™ืจ ื”ืžื ื•ื™ ื•ืžืœืื” ื‘ืชื›ื•ื ื•ืช ื ื•ืกืคื•ืช Agent-Circuit-Id ื•-Agent-Remote-Id ื”ืžื›ื™ืœื•ืช, ื‘ื”ืชืืžื”, ืฉื•ื‘ ืืช ื”-MAC ืฉืœ ืžืชื’ ื”ืžืžืกืจ ื•ื”ื™ืฆื™ืื” ืืœื™ื” ืžื—ื•ื‘ืจ ื”ืžื ื•ื™.
  • ื—ืœืง ืžื”ืžื ื•ื™ื™ื ืขื ื ืงื•ื“ื•ืช WiFI ืžื•ืจืฉื™ื ื‘ืืžืฆืขื•ืช ืคืจื•ื˜ื•ืงื•ืœื™ PAP-CHAP
  • ื—ืœืง ืžื”ืžื ื•ื™ื™ื ืžื ืงื•ื“ื•ืช WIFI ืžื•ืจืฉื™ื ืขื ืฉื ืžืฉืชืžืฉ ื”ืฉื•ื•ื” ืœื›ืชื•ื‘ืช ื”-MAC ืฉืœ ื ืงื•ื“ืช ื”-WIFI, ืœืœื ืกื™ืกืžื”.

ืจืงืข ื”ื™ืกื˜ื•ืจื™: ืžื”ื™ "ืื•ืคืฆื™ื” 82" ื‘-DHCP

ืืœื• ื”ืŸ ืืคืฉืจื•ื™ื•ืช ื ื•ืกืคื•ืช ืขื‘ื•ืจ ืคืจื•ื˜ื•ืงื•ืœ DHCP ื”ืžืืคืฉืจื•ืช ืœืš ืœื”ืขื‘ื™ืจ ืžื™ื“ืข ื ื•ืกืฃ, ืœืžืฉืœ ื‘ืฉื“ื•ืช Agent-Circuit-Id ื•-Agent-Remote-Id. ืžืฉืžืฉ ื‘ื“ืจืš ื›ืœืœ ืœื”ืขื‘ืจืช ื›ืชื•ื‘ืช ื”-MAC ืฉืœ ืžืชื’ ื”ืžืžืกืจ ื•ื”ื™ืฆื™ืื” ืืœื™ื” ืžื—ื•ื‘ืจ ื”ืžื ื•ื™. ื‘ืžืงืจื” ืฉืœ ืฆื™ื•ื“ PON ืื• ืชื—ื ื•ืช ื‘ืกื™ืก WIFI, ื”ืฉื“ื” Agent-Circuit-Id ืื™ื ื• ืžื›ื™ืœ ืžื™ื“ืข ืฉื™ืžื•ืฉื™ (ืื™ืŸ ื™ืฆื™ืืช ืžื ื•ื™). ื”ืกื›ื™ืžื” ื”ื›ืœืœื™ืช ืฉืœ ืคืขื•ืœืช DHCP ื‘ืžืงืจื” ื–ื” ื”ื™ื ื›ื“ืœืงืžืŸ:

ื”ื’ื“ืจื•ืช ืจืฉืช ืž- FreeRadius ื“ืจืš DHCP

ืฉืœื‘ ืื—ืจ ืฉืœื‘ ืชื›ื ื™ืช ื–ื• ืคื•ืขืœืช ื›ืš:

  1. ืฆื™ื•ื“ ื”ืžืฉืชืžืฉ ืžื‘ืฆืข ื‘ืงืฉืช ืฉื™ื“ื•ืจ DHCP ื›ื“ื™ ืœืงื‘ืœ ื”ื’ื“ืจื•ืช ืจืฉืช
  2. ื”ืžื›ืฉื™ืจ (ืœื“ื•ื’ืžื”, ืžืชื’, ืชื—ื ืช ื‘ืกื™ืก WiFi ืื• PON) ืฉืืœื™ื• ืžื—ื•ื‘ืจ ืฆื™ื•ื“ ื”ืžื ื•ื™ ื™ืฉื™ืจื•ืช "ืžื™ื™ืจื˜" ืืช ื”ื—ื‘ื™ืœื” ื”ื–ื• ื•ืžืฉื ื” ืื•ืชื”, ื•ืžื›ื ื™ืก ืœืชื•ื›ื” ืืคืฉืจื•ื™ื•ืช ื ื•ืกืคื•ืช ืื•ืคืฆื™ื” 82 ื•ื›ืชื•ื‘ืช IP ืฉืœ ืกื•ื›ืŸ ืžืžืกืจ, ื•ืžืฉื“ืจ ืื•ืชื” ื‘ื”ืžืฉืš ื”ืจืฉืช.
  3. ืฉืจืช ื”-DHCP ืžืงื‘ืœ ืืช ื”ื‘ืงืฉื”, ื™ื•ืฆืจ ืชื’ื•ื‘ื” ื•ืฉื•ืœื— ืื•ืชื” ืœื”ืชืงืŸ ื”ืžืžืกืจ
  4. ืžื›ืฉื™ืจ ื”ืžืžืกืจ ืžืขื‘ื™ืจ ืืช ื—ื‘ื™ืœืช ื”ืชื’ื•ื‘ื” ืœืžื›ืฉื™ืจ ื”ืžื ื•ื™

ื›ืžื•ื‘ืŸ, ื”ื›ืœ ืœื ืขื•ื‘ื“ ื›ืœ ื›ืš ื‘ืงืœื•ืช; ืืชื” ืฆืจื™ืš ืœื”ื’ื“ื™ืจ ืืช ืฆื™ื•ื“ ื”ืจืฉืช ืฉืœืš ื‘ื”ืชืื.

ื”ืชืงื ืช FreeRadius

ื›ืžื•ื‘ืŸ ืฉื ื™ืชืŸ ืœื”ืฉื™ื’ ื–ืืช ืขื ื”ื’ื“ืจื•ืช ื”ืชืฆื•ืจื” ืฉืœ FreeRadius, ืื‘ืœ ื–ื” ืงืฉื” ื•ืœื ื‘ืจื•ืจ... ื‘ืžื™ื•ื—ื“ ื›ืฉืืชื” ื”ื•ืœืš ืœืฉื ืื—ืจื™ N ื—ื•ื“ืฉื™ื ื•"ื”ื›ืœ ืขื•ื‘ื“". ืœื›ืŸ, ื”ื—ืœื˜ื ื• ืœื›ืชื•ื‘ ืžื•ื“ื•ืœ ื”ืจืฉืื•ืช ืžืฉืœื ื• ืขื‘ื•ืจ FreeRadius ื‘-Python. ืื ื• ื ื™ืงื— ื ืชื•ื ื™ ื”ืจืฉืื•ืช ืžืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ MySQL. ืื™ืŸ ื˜ืขื ืœืชืืจ ืืช ื”ืžื‘ื ื” ืฉืœื•; ื‘ื›ืœ ืžืงืจื”, ื›ืœ ืื—ื“ ื™ืขืฉื” ืืช ื–ื” "ืœืขืฆืžื•". ื‘ืคืจื˜, ืœืงื—ืชื™ ืืช ื”ืžื‘ื ื” ื”ืžื•ืฆืข ืขื ืžื•ื“ื•ืœ sql ืขื‘ื•ืจ FreeRadius, ื•ืฉื™ื ื™ืชื™ ืื•ืชื• ืžืขื˜ ืขืœ ื™ื“ื™ ื”ื•ืกืคืช ืฉื“ื” ืžืง ื•ืคื•ืจื˜ ืขื‘ื•ืจ ื›ืœ ืžื ื•ื™, ื‘ื ื•ืกืฃ ืœืกื™ืกืžืช ื”ื›ื ื™ืกื”.

ืื–, ืจืืฉื™ืช, ื”ืชืงืŸ ืืช FreeRadius:

cd /usr/ports/net/freeradius3
make config
make
install clean

ื‘ื”ื’ื“ืจื•ืช, ื‘ื—ืจ ืœื”ืชืงื ื”:

ื”ื’ื“ืจื•ืช ืจืฉืช ืž- FreeRadius ื“ืจืš DHCP

ืื ื• ื™ื•ืฆืจื™ื ืงื™ืฉื•ืจ ืกื™ืžื•ืœ ืœืžื•ื“ื•ืœ ืคื™ืชื•ืŸ (ื›ืœื•ืžืจ "ื”ืคืขืœ" ืื•ืชื•):

ln -s /usr/local/etc/raddb/mods-available/python /usr/local/etc/raddb/mods-enabled

ื‘ื•ืื• ื ืชืงื™ืŸ ืžื•ื“ื•ืœ ื ื•ืกืฃ ืขื‘ื•ืจ python:

pip install mysql-connector

ื‘ื”ื’ื“ืจื•ืช ืžื•ื“ื•ืœ python ืขื‘ื•ืจ FreeRadius, ืขืœื™ืš ืœืฆื™ื™ืŸ ืืช ื ืชื™ื‘ื™ ื”ื—ื™ืคื•ืฉ ืฉืœ ื”ืžื•ื“ื•ืœ ื‘ืžืฉืชื ื” python_path. ืœื“ื•ื’ืžื ื™ืฉ ืœื™ ืืช ื–ื”:

python_path="/usr/local/etc/raddb/mods-config/python:/usr/local/lib/python2.7:/usr/local/lib/python27.zip:/usr/local/lib/python2.7:/usr/local/lib/python2.7/plat-freebsd12:/usr/local/lib/python2.7/lib-tk:/usr/local/lib/python2.7/lib-old:/usr/local/lib/python2.7/lib-dynload:/usr/local/lib/python2.7/site-packages"

ืืชื” ื™ื›ื•ืœ ืœื’ืœื•ืช ืืช ื”ื ืชื™ื‘ื™ื ืขืœ ื™ื“ื™ ื”ืคืขืœืช ืžืชื•ืจื’ืžืŸ python ื•ื”ื–ื ืช ื”ืคืงื•ื“ื•ืช:

root@phaeton:/usr/local/etc/raddb/mods-enabled# python
Python 2.7.15 (default, Dec  8 2018, 01:22:25) 
[GCC 4.2.1 Compatible FreeBSD Clang 6.0.1 (tags/RELEASE_601/final 335540)] on freebsd12
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/usr/local/lib/python27.zip', '/usr/local/lib/python2.7', '/usr/local/lib/python2.7/plat-freebsd12', '/usr/local/lib/python2.7/lib-tk', '/usr/local/lib/python2.7/lib-old', '/usr/local/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/site-packages']
>

ืื ืœื ืชื‘ืฆืข ืืช ื”ืฆืขื“ ื”ื–ื”, ืื– ืกืงืจื™ืคื˜ื™ื ืฉื ื›ืชื‘ื• ื‘-python ื•ื”ื•ืฉืงื• ืขืœ ื™ื“ื™ FreeRadius ืœื ื™ืžืฆืื• ืืช ื”ืžื•ื“ื•ืœื™ื ื”ืจืฉื•ืžื™ื ื‘ื™ื‘ื•ื. ื‘ื ื•ืกืฃ, ืขืœื™ืš ืœื‘ื˜ืœ ื”ืขืจื•ืช ืœืคื•ื ืงืฆื™ื•ืช ืœืงืจื™ืืช ื”ืจืฉืื” ื•ื—ืฉื‘ื•ื ืื•ืช ื‘ื”ื’ื“ืจื•ืช ื”ืžื•ื“ื•ืœ. ืœื“ื•ื’ืžื”, ืžื•ื“ื•ืœ ื–ื” ื ืจืื” ื›ืš:

python {
    python_path="/usr/local/etc/raddb/mods-config/python:/usr/local/lib/python2.7:/usr/local/lib/python2.7/site-packages:/usr/local/lib/python27.zip:/usr/local/lib/python2.7:/usr/local/lib/python2.7/plat-freebsd12:/usr/local/lib/python2.7/lib-tk:/usr/local/lib/python2.7/lib-old:/usr/local/lib/python2.7/lib-dynload:/usr/local/lib/python2.7/site-packages"
    module = work
    mod_instantiate = ${.module}
    mod_detach = ${.module}

    mod_authorize = ${.module}
    func_authorize = authorize

    mod_authenticate = ${.module}
    func_authenticate = authenticate

    mod_preacct = ${.module}
    func_preacct = preacct

    mod_accounting = ${.module}
    func_accounting = accounting

    mod_checksimul = ${.module}
    mod_pre_proxy = ${.module}
    mod_post_proxy = ${.module}
    mod_post_auth = ${.module}
    mod_recv_coa = ${.module}
    mod_send_coa = ${.module}

}

ื™ืฉ ืœืžืงื ืืช ื”ืกืงืจื™ืคื˜ work.py (ื•ื›ืœ ื”ืื—ืจื™ื) ื‘- /usr/local/etc/raddb/mods-config/python ื™ืฉ ืœื™ ืฉืœื•ืฉื” ืกืงืจื™ืคื˜ื™ื ื‘ืกืš ื”ื›ืœ.

work.py:

#!/usr/local/bin/python
# coding=utf-8
import radiusd
import func
import sys
from pprint import pprint
mysql_host="localhost"
mysql_username="ัƒะบะฐั†ัƒะบ"
mysql_password="ั‹ัƒะบะฐั‹ัƒะบะฐั‹ัƒะบ"
mysql_base="ั‹ัƒะบะฐั‹ะบัƒะฐั‹ัƒ"
def instantiate(p):
print ("*** instantiate ***")
print (p)
# return 0 for success or -1 for failure
def authenticate(p):
print ("*** ะัƒั‚ะตะฝั„ะธะบะฐั†ะธั!!***")
print (p)
def authorize(p):
radiusd.radlog(radiusd.L_INFO, '*** radlog call in authorize ***')    
conn=func.GetConnectionMysql(mysql_host, mysql_username, mysql_password, mysql_base);
param=func.ConvertArrayToNames(p);
pprint(param)
print ("*** ะะฒั‚ะพั€ะธะทะฐั†ะธั ***")
reply = ()
conf = ()
cnt=0
username="";mac="";
# ัะฝะฐั‡ะฐะปะฐ ะฟั€ะพะฒะตั€ัะตะผ "ะบะฐะบ ะฟะพะปะพะถะตะฝะพ", ะฟะพ ัะฒัะทะบะต ะปะพะณะธะฝ/ะฟะฐั€ะพะปัŒ
if ("User-Name" in param) and ("User-Password" in param) :
print ("ะ’ะฐั€ะธะฐะฝั‚ ะฐะฒั‚ะพั€ะธะทะฐั†ะธะธ (1): ะตัั‚ัŒ ะปะพะณะธะฝ-ะฟะฐั€ะพะปัŒ")
pprint(param["User-Name"])
pprint(param["User-Password"])
pprint(conn)
print(sys.version_info)
print (radiusd.config)
sql="select radreply.attribute,radreply.value from radcheck inner join radreply on radreply.username=radcheck.username where radcheck.username=%s and radcheck.value=%s"
print(sql)
cursor = conn.cursor(dictionary=True,buffered=True)
cursor.execute(sql,[param["User-Name"], param["User-Password"]]);
row = cursor.fetchone()	
while row is not None:    
cnt=cnt+1
username=row["username"]
reply = reply+((str(row["attribute"]),str(row["value"])), )
row = cursor.fetchone()	          
# ะฒะฐั€ะธะฐะฝั‚, ั‡ั‚ะพ User-Name - ัั‚ะพ ะœะะก ะฐะดั€ะตั ะ‘ะก,ะฟะฐั€ะพะปั ะธ ะฟะพั€ั‚ะฐ ะฝะตั‚                
if ("User-Name" in param)  and ("User-Password" in param) and (cnt==0):
if param["User-Password"] =='':
if ":" in param["User-Name"]:
pprint(param["User-Name"])            
print ("ะ’ะฐั€ะธะฐะฝั‚ ะฐะฒั‚ะพั€ะธะทะฐั†ะธะธ (2): User-Name - ัั‚ะพ MAC ะฐะดั€ะตั ะฑะฐะทะพะฒะพะน ัั‚ะฐะฝั†ะธะธ, ะฟะพั€ั‚ะฐ ะธ ะฟะฐั€ะพะปั ะฝะตั‚")
sql="select radreply.username,radreply.attribute,radreply.value from radcheck inner join radreply on radreply.username=radcheck.username where REPLACE(radcheck.mac,':','') = REPLACE(REPLACE('"+str(param["User-Name"])+"','0x',''),':','') and radcheck.sw_port=''"
print (sql)
cursor = conn.cursor(dictionary=True,buffered=True)
cursor.execute(sql);
row = cursor.fetchone()	
while row is not None:                  
cnt=cnt+1
username=row["username"]
mac=param["User-Name"]
reply = reply+((str(row["attribute"]),str(row["value"])), )
row = cursor.fetchone()	          
if ("Agent-Remote-Id" in param)  and ("User-Password" in param) and (cnt==0):
if param["User-Password"] =='':
pprint(param["Agent-Remote-Id"])            
print ("ะ’ะฐั€ะธะฐะฝั‚ ะฐะฒั‚ะพั€ะธะทะฐั†ะธะธ (2.5): Agent-Remote-Id - ัั‚ะพ MAC ะฐะดั€ะตั PON ะพะฑะพั€ัƒะดะพะฒะฐะฝะธั")
sql="select radreply.username,radreply.attribute,radreply.value from radcheck inner join radreply on radreply.username=radcheck.username where REPLACE(radcheck.mac,':','') = REPLACE(REPLACE('"+str(param["Agent-Remote-Id"])+"','0x',''),':','') and radcheck.sw_port=''"
print (sql)
cursor = conn.cursor(dictionary=True,buffered=True)
cursor.execute(sql);
row = cursor.fetchone()	
while row is not None:                  
cnt=cnt+1
username=row["username"]
mac=param["User-Name"]
reply = reply+((str(row["attribute"]),str(row["value"])), )
row = cursor.fetchone()	          
#ะ’ะฐั€ะธะฐะฝั‚, ั‡ั‚ะพ Agent-Remote-Id - ัั‚ะพ ะœะะก ะฐะดั€ะตั ะ‘ะก,ะฟะฐั€ะพะปั ะธ ะฟะพั€ั‚ะฐ ะฝะตั‚ ะธ ะฟั€ะตะดั‹ะดัƒั‰ะธะต ะฒะฐั€ะธะฐะฝั‚ั‹ ะฟะพะธัะบะฐ IP ั€ะตะทัƒะปัŒั‚ะฐั‚ะฐ ะฝะต ะดะฐะปะธ                
if ("Agent-Remote-Id" in param)  and ("User-Password" not in param) and (cnt==0):
pprint(param["Agent-Remote-Id"])            
print ("ะ’ะฐั€ะธะฐะฝั‚ ะฐะฒั‚ะพั€ะธะทะฐั†ะธะธ (3): Agent-Remote-Id - ะœะะก ะฑะฐะทะพะฒะพะน ัั‚ะฐะฝั†ะธะธ/ะฟะพะฝ. ะŸะพั€ั‚ะฐ ะฒ ะฑะธะปะปะธะฝะณะต ะฝะตั‚")
sql="select radreply.username,radreply.attribute,radreply.value from radcheck inner join radreply on radreply.username=radcheck.username where REPLACE(radcheck.mac,':','') = REPLACE(REPLACE('"+str(param["Agent-Remote-Id"])+"','0x',''),':','') and radcheck.sw_port=''"
print(sql)
cursor = conn.cursor(dictionary=True,buffered=True)
cursor.execute(sql);
row = cursor.fetchone()	
while row is not None:    
cnt=cnt+1
mac=param["Agent-Remote-Id"]
username=row["username"]
reply = reply+((str(row["attribute"]),str(row["value"])), )
row = cursor.fetchone()	          
#ะ’ะฐั€ะธะฐะฝั‚, ั‡ั‚ะพ ะฟั€ะตะดั‹ะดัƒั‰ะธะต ะฟะพะฟั‹ั‚ะบะธ ั€ะตะทัƒะปัŒั‚ะฐั‚ะฐ ะฝะต ะดะฐะปะธ, ะฝะพ ะตัั‚ัŒ Agent-Remote-Id ะธ Agent-Circuit-Id
if ("Agent-Remote-Id" in param)  and ("Agent-Circuit-Id" in param) and (cnt==0):
pprint(param["Agent-Remote-Id"])            
pprint(param["Agent-Circuit-Id"])            
print ("ะ’ะฐั€ะธะฐะฝั‚ ะฐะฒั‚ะพั€ะธะทะฐั†ะธะธ (4): ะฐะฒั‚ะพั€ะธะทะฐั†ะธั ะฟะพ Agent-Remote-Id ะธ Agent-Circuit-Id, ะฒ ะฑะธะปะปะธะฝะณะต ะตัั‚ัŒ ะฟะพั€ั‚/ะผะฐะบ")
sql="select radreply.username,radreply.attribute,radreply.value from radcheck inner join radreply on radreply.username=radcheck.username where upper(radcheck.sw_mac)=upper(REPLACE('"+str(param["Agent-Remote-Id"])+"','0x','')) and upper(radcheck.sw_port)=upper(RIGHT('"+str(param["Agent-Circuit-Id"])+"',2)) and radcheck.sw_port<>''"
print(sql)
cursor = conn.cursor(dictionary=True,buffered=True)
cursor.execute(sql);
row = cursor.fetchone()	
while row is not None:    
cnt=cnt+1
mac=param["Agent-Remote-Id"]
username=row["username"]
reply = reply+((str(row["attribute"]),str(row["value"])), )
row = cursor.fetchone()	          
# ะตัะปะธ ั‚ะฐะบ ะดะพ ัะธั… ะฟะพั€ IP ะฝะต ะฟะพะปัƒั‡ะตะฝ, ั‚ะพ ะฒั‹ะดะฐัŽ ะธะตะณะพ ะธะท ะณะพัั‚ะตะฒะพะน ัะตั‚ะธ..
if cnt==0:      
print ("ะะธ ะพะดะธะฝ ะธะท ะฒะฐั€ะธะฐะฝั‚ะพะฒ ะฐะฒั‚ะพั€ะธะทะฐั†ะธะธ ะฝะต ัั€ะฐะฑะพั‚ะฐะป, ะฟะพะปัƒั‡ะฐัŽ IP ะธะท ะณะพัั‚ะตะฒะพะน ัะตั‚ะธ..")
ip=func.GetGuestNet(conn)      
if ip!="": 
cnt=cnt+1;
reply = reply+(("Framed-IP-Address",str(ip)), )
# ะตัะปะธ ัะพะฒัะตะผ ะฒัั‘ ะฟะปะพั…ะพ, ั‚ะพ Reject
if cnt==0:
conf = ( ("Auth-Type", "Reject"), ) 
else:
#ะตัะปะธ ะฐะฒั‚ะพั€ะธะทะฐั†ะธั ัƒัะฟะตัˆะฝะฐั (ะตัั‚ัŒ ั‚ะฐะบะพะน ะฐะฑะพะฝะตะฝั‚), ั‚ะพ ะทะฐะฟะธัˆะตะผ ะธัั‚ะพั€ะธัŽ ะฐะฒั‚ะพั€ะธะทะฐั†ะธะธ
if username!="":
func.InsertToHistory(conn,username,mac, reply);
conf = ( ("Auth-Type", "Accept"), )             
pprint (reply)
conn=None;
return radiusd.RLM_MODULE_OK, reply, conf
def preacct(p):
print ("*** preacct ***")
print (p)
return radiusd.RLM_MODULE_OK
def accounting(p):
print ("*** ะะบะบะฐัƒะฝั‚ะธะฝะณ ***")
radiusd.radlog(radiusd.L_INFO, '*** radlog call in accounting (0) ***')  
print (p)
conn=func.GetConnectionMysql(mysql_host, mysql_username, mysql_password, mysql_base);
param=func.ConvertArrayToNames(p);
pprint(param)  
print("ะฃะดะฐะปะธะผ ัั‚ะฐั€ั‹ะต ัะตััะธะธ (ะฑะพะปะตะต 20 ะผะธะฝัƒั‚ ะฝะตั‚ ะฐะบะบะฐัƒะฝั‚ะธะฝะณะฐ)");
sql="delete from radacct where TIMESTAMPDIFF(minute,acctupdatetime,now())>20"
cursor = conn.cursor(dictionary=True,buffered=True)
cursor.execute(sql);
conn.commit()
print("ะžะฑะฝะพะฒะธะผ/ะดะพะฑะฐะฒะธะผ ะธะฝั„ะพั€ะผะฐั†ะธัŽ ะพ ัะตััะธะธ")
if (("Acct-Unique-Session-Id" in param) and ("User-Name" in param) and ("Framed-IP-Address" in param)):
sql='insert into radacct (radacctid,acctuniqueid,username,framedipaddress,acctstarttime) values (null,"'+str(param['Acct-Unique-Session-Id'])+'","'+str(param['User-Name'])+'","'+str(param['Framed-IP-Address'])+'",now()) ON DUPLICATE KEY update acctupdatetime=now()'
print(sql)
cursor = conn.cursor(dictionary=True,buffered=True)
cursor.execute(sql)
conn.commit()
conn=None;
return radiusd.RLM_MODULE_OK
def pre_proxy(p):
print ("*** pre_proxy ***")
print (p)
return radiusd.RLM_MODULE_OK
def post_proxy(p):
print ("*** post_proxy ***")
print (p)
return radiusd.RLM_MODULE_OK
def post_auth(p):
print ("*** post_auth ***")
print (p)
return radiusd.RLM_MODULE_OK
def recv_coa(p):
print ("*** recv_coa ***")
print (p)
return radiusd.RLM_MODULE_OK
def send_coa(p):
print ("*** send_coa ***")
print (p)
return radiusd.RLM_MODULE_OK
def detach():
print ("*** ะะฐ ัั‚ะพะผ ะฒัั‘ ะดะตั‚ะธัˆะตั‡ะบะธ ***")
return radiusd.RLM_MODULE_OK

func.py:

#!/usr/bin/python2.7
# coding=utf-8
import mysql.connector
from mysql.connector import Error
# ะคัƒะฝะบั†ะธั ะฒะพะทะฒั€ะฐั‰ะฐะตั‚ ัะพะตะดะธะฝะตะฝะธะต ั MySQL
def GetConnectionMysql(mysql_host, mysql_username, mysql_password, mysql_base):    
try:
conn = mysql.connector.connect(host=mysql_host,database=mysql_base,user=mysql_username,password=mysql_password)
if conn.is_connected(): print('---cะพะตะดะธะฝะตะฝะธะต ั ะ‘ะ” '+mysql_base+' ัƒัั‚ะฐะฝะพะฒะปะตะฝะพ')
except Error as e:
print("ะžัˆะธะฑะบะฐ: ",e);
exit(1);       
return conn
def ConvertArrayToNames(p):
mass={};
for z in p:
mass[z[0]]=z[1]
return mass
# ะคัƒะฝะบั†ะธั ะทะฐะฟะธัั‹ะฒะฐะตั‚ ะธัั‚ะพั€ะธัŽ ัะพะตะดะธะฝะตะฝะธั ะฟะพ ะธะทะฒะตัั‚ะฝั‹ะผ ะดะฐะฝะฝั‹ะผ
def InsertToHistory(conn,username,mac, reply):
print("--ะทะฐะฟะธัั‹ะฒะฐัŽ ะดะปั ะธัั‚ะพั€ะธะธ")
repl=ConvertArrayToNames(reply)
if "Framed-IP-Address" in repl:
sql='insert into radpostauth (username,reply,authdate,ip,mac,session_id,comment) values ("'+username+'","Access-Accept",now(),"'+str(repl["Framed-IP-Address"])+'","'+str(mac)+'","","")'
print(sql)
cursor = conn.cursor(dictionary=True,buffered=True)          
cursor.execute(sql);
conn.commit()
# ะคัƒะฝะบั†ะธั ะฒั‹ะดะฐะตั‚ ะฟะพัะปะตะดะฝะธะน ะฟะพ ะดะฐั‚ะต ะฒั‹ะดะฐั‡ะธ IP ะฐะดั€ะตั ะธะท ะณะพัั‚ะตะฒะพะน ัะตั‚ะธ        
def GetGuestNet(conn):
ip="";id=0
sql="select * from guestnet order by dt limit 1"
print (sql)
cursor = conn.cursor(dictionary=True,buffered=True)          
cursor.execute(sql);
row = cursor.fetchone()	
while row is not None:    
ip=row["ip"]
id=row["id"]
row = cursor.fetchone()	          
if id>0:
sql="update guestnet set dt=now() where id="+str(id)
print (sql)
cursor = conn.cursor(dictionary=True,buffered=True)          
cursor.execute(sql);
conn.commit()
return ip         

radiusd.py:

#!/usr/bin/python2.7
# coding=utf-8
# from modules.h
RLM_MODULE_REJECT = 0
RLM_MODULE_FAIL = 1
RLM_MODULE_OK = 2
RLM_MODULE_HANDLED = 3
RLM_MODULE_INVALID = 4
RLM_MODULE_USERLOCK = 5
RLM_MODULE_NOTFOUND = 6
RLM_MODULE_NOOP = 7
RLM_MODULE_UPDATED = 8
RLM_MODULE_NUMCODES = 9
# from log.h
L_AUTH = 2
L_INFO = 3
L_ERR = 4
L_WARN = 5
L_PROXY = 6
L_ACCT = 7
L_DBG = 16
L_DBG_WARN = 17
L_DBG_ERR = 18
L_DBG_WARN_REQ = 19
L_DBG_ERR_REQ = 20
# log function
def radlog(level, msg):
import sys
sys.stdout.write(msg + 'n')
level = level

ื›ืคื™ ืฉื ื™ืชืŸ ืœืจืื•ืช ืžื”ืงื•ื“, ืื ื• ืžื ืกื™ื ืœื–ื”ื•ืช ืืช ื”ืžื ื•ื™ ื‘ืืžืฆืขื•ืช ื›ืœ ื”ืฉื™ื˜ื•ืช ื”ื–ืžื™ื ื•ืช ืขืœ ื™ื“ื™ ื›ืชื•ื‘ื•ืช ื”-MAC ื”ืžื•ื›ืจื•ืช ืฉืœ ื”ืžื ื•ื™ ืฉืœื• ืื• ืฉื™ืœื•ื‘ ืฉืœ ืื•ืคืฆื™ื” 82, ื•ืื ื–ื” ืœื ืขื•ื‘ื“, ืื ื• ืžื ืคื™ืงื™ื ืืช ื›ืชื•ื‘ืช ื”-IP ื”ื™ืฉื ื” ื‘ื™ื•ืชืจ ืฉืื™ ืคืขื ื”ืฉืชืžืฉื• ื‘ื” ืžื”ืื•ืจื— "ืจืฉืช. ื›ืœ ืžื” ืฉื ื•ืชืจ ื”ื•ื ืœื”ื’ื“ื™ืจ ืืช ืกืงืจื™ืคื˜ ื‘ืจื™ืจืช ื”ืžื—ื“ืœ ื‘ืชื™ืงื™ื” ื”ืžื•ืคืขืœืช ื‘ืืชืจื™ื, ื›ืš ืฉื”ืคื•ื ืงืฆื™ื•ืช ื”ื“ืจื•ืฉื•ืช ืžืกืงืจื™ืคื˜ python ื™ืชืขื•ื•ืช ื‘ืจื’ืขื™ื ื”ืžื™ื•ืขื“ื™ื ืœื›ืš. ืœืžืขืฉื”, ืžืกืคื™ืง ืœื”ื‘ื™ื ืืช ื”ืงื•ื‘ืฅ ืœื˜ื•ืคืก:

ื‘ืจื™ืจืช ืžื—ื“ืœ

server default {
listen {
type = auth
ipaddr = *
port = 0
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
listen {
ipaddr = *
port = 0
type = acct
limit {
}
}
listen {
type = auth
port = 0
limit {
max_connections = 1600
lifetime = 0
idle_timeout = 30
}
}
listen {
ipv6addr = ::
port = 0
type = acct
limit {
}
}
authorize {
python
filter_username
preprocess
expiration
logintime
}
authenticate {
Auth-Type PAP {
pap
python
}
Auth-Type CHAP {
chap
python
}
Auth-Type MS-CHAP {
mschap
python
}
eap
}
preacct {
preprocess
acct_unique
suffix
files
}
accounting {
python
exec
attr_filter.accounting_response
}
session {
}
post-auth {
update {
&reply: += &session-state:
}
exec
remove_reply_message_if_eap
Post-Auth-Type REJECT {
attr_filter.access_reject
eap
remove_reply_message_if_eap
}
Post-Auth-Type Challenge {
}
}
pre-proxy {
}
post-proxy {
eap
}
}

ื‘ื•ื ื ื ืกื” ืœื”ืคืขื™ืœ ืื•ืชื• ื•ืœืจืื•ืช ืžื” ื ื›ื ืก ืœื™ื•ืžืŸ ื”ื‘ืื’ื™ื:

/usr/local/etc/rc.d/radiusd debug

ืžื” ืขื•ื“. ื‘ืขืช ื”ื’ื“ืจืช FreeRadius, ื ื•ื— ืœื‘ื“ื•ืง ืืช ืคืขื•ืœืชื• ื‘ืืžืฆืขื•ืช ื›ืœื™ ื”ืฉื™ืจื•ืช radclient. ืœื“ื•ื’ืžื ื”ืจืฉืื”:

echo "User-Name=4C:5E:0C:2E:7F:15,Agent-Remote-Id=0x9845623a8c98,Agent-Circuit-Id=0x00010006" | radclient -x  127.0.0.1:1812 auth testing123

ืื• ื—ืฉื‘ื•ืŸ:

echo "User-Name=4C:5E:0C:2E:7F:15,Agent-Remote-Id=0x00030f26054a,Agent-Circuit-Id=0x00010002" | radclient -x  127.0.0.1:1813 acct testing123

ืื ื™ ืจื•ืฆื” ืœื”ื–ื”ื™ืจ ืื•ืชืš ืฉื–ื” ื‘ืœืชื™ ืืคืฉืจื™ ืœื—ืœื•ื˜ื™ืŸ ืœื”ืฉืชืžืฉ ื‘ืกื›ื™ืžื” ื•ื‘ืกืงืจื™ืคื˜ื™ื ื›ืืœื” "ืœืœื ืฉื™ื ื•ื™ื™ื" ื‘ืงื ื” ืžื™ื“ื” "ืชืขืฉื™ื™ืชื™". ืœืคื—ื•ืช ืžื•ืจื’ืฉ:

  • ืืคืฉืจ "ืœื–ื™ื™ืฃ" ืืช ื›ืชื•ื‘ืช ื”-MAC. ืžืกืคื™ืง ืฉื”ืžื ื•ื™ ื™ืจืฉื•ื ืืช ื”-MAC ืฉืœ ืžื™ืฉื”ื• ืื—ืจ ื•ื™ื”ื™ื• ื‘ืขื™ื•ืช
  • ื”ื”ื™ื’ื™ื•ืŸ ืฉืœ ื”ื ืคืงืช ืจืฉืชื•ืช ืื•ืจื—ื™ื ื”ื•ื ืžืขื‘ืจ ืœื‘ื™ืงื•ืจืช. ืื™ืŸ ืืคื™ืœื• ืกื™ืžื•ืŸ "ืื•ืœื™ ื™ืฉ ื›ื‘ืจ ืœืงื•ื—ื•ืช ืขื ืื•ืชื” ื›ืชื•ื‘ืช IP?"

ื–ื”ื• ืจืง "ืคืชืจื•ืŸ ืœื—ื•ืชืš ืขื•ื’ื™ื•ืช" ืฉื ื•ืขื“ ืœืขื‘ื•ื“ ื‘ืžื™ื•ื—ื“ ื‘ืชื ืื™ื ืฉืœื™, ืœื ื™ื•ืชืจ. ืืœ ืชืฉืคื•ื˜ ื‘ืงืคื“ื ื•ืช ๐Ÿ˜‰

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”