αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž”αžŽαŸ’αžαžΆαž‰αž–αžΈ FreeRadius αžαžΆαž˜αžšαž™αŸˆ DHCP

αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž”αžŽαŸ’αžαžΆαž‰αž–αžΈ FreeRadius αžαžΆαž˜αžšαž™αŸˆ DHCP
αž—αžΆαžšαž€αž·αž…αŸ’αž…αž”αžΆαž“αž˜αž€αžŠαž›αŸ‹αžŠαžΎαž˜αŸ’αž”αžΈαžšαŸ€αž”αž…αŸ†αž€αžΆαžšαž…αŸαž‰αž’αžΆαžŸαž™αžŠαŸ’αž‹αžΆαž“ IP αžŠαž›αŸ‹αž’αžαž·αžαž·αž‡αž“αŸ” αž›αž€αŸ’αžαžαžŽαŸ’αžŒαž“αŸƒαž”αž‰αŸ’αž αžΆαŸ–

  • αž™αžΎαž„αž“αžΉαž„αž˜αž·αž“αž•αŸ’αžαž›αŸ‹αž±αŸ’αž™αž’αŸ’αž“αž€αž“αžΌαžœαž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸαžŠαžΆαž…αŸ‹αžŠαŸ„αž™αž‘αŸ‚αž€αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž’αž“αž»αž‰αŸ’αž‰αžΆαžαž‘αŸ - αž’αŸ’αž“αž€αž“αžΉαž„αž’αŸ’αžœαžΎαžœαžΆπŸ˜‰
  • αž’αžαž·αžαž·αž‡αž“αžαŸ’αžšαžΌαžœαžαŸ‚αž‘αž‘αž½αž›αž”αžΆαž“αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž”αžŽαŸ’αžαžΆαž‰αžαžΆαž˜αžšαž™αŸˆ DHCP
  • αž”αžŽαŸ’αžαžΆαž‰αž‚αžΊαžαž»αžŸαž‚αŸ’αž“αžΆαŸ” αž“αŸαŸ‡αžšαž½αž˜αž”αž‰αŸ’αž…αžΌαž›αž‘αžΆαŸ†αž„αž§αž”αž€αžšαžŽαŸ PON αž“αž·αž„αž€αž»αž„αžαžΆαž€αŸ‹αž’αž˜αŸ’αž˜αžαžΆαž‡αžΆαž˜αž½αž™αž“αžΉαž„αž‡αž˜αŸ’αžšαžΎαžŸ 82 αžŠαŸ‚αž›αž”αžΆαž“αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’ αž“αž·αž„αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αžœαŸ‰αžΆαž™αž αŸ’αžœαžΆαž™αž‡αžΆαž˜αž½αž™αž αžαžŸαŸ’αž–αž
  • αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž‘αž·αž“αŸ’αž“αž“αŸαž™αž˜αž·αž“αžŸαŸ’αžαž·αžαž“αŸ…αž€αŸ’αžšαŸ„αž˜αž›αž€αŸ’αžαžαžŽαŸ’αžŒαžŽαžΆαž˜αž½αž™αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž…αŸαž‰ IP αž‘αŸ αž’αŸ’αž“αž€αžαŸ’αžšαžΌαžœαžαŸ‚αž…αŸαž‰ IP αž–αžΈαž”αžŽαŸ’αžαžΆαž‰ "αž—αŸ’αž‰αŸ€αžœ"

αž“αŸ…αž•αŸ’αž“αŸ‚αž€αž›αŸ’αž’αŸ– αž“αŸ…αžαŸ‚αž˜αžΆαž“αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸαž“αŸ…αž›αžΎ FreeBSD αžŠαŸ‚αž›αž’αžΆαž… "αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš" αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžœαžΆ "αž†αŸ’αž„αžΆαž™" ;) αž˜αž·αž“αž˜αŸ‚αž“ "αž“αŸ…αž›αžΎαž”αžŽαŸ’αžαžΆαž‰αž“αŸαŸ‡" αž‘αŸαŸ”

αžœαžΆαž€αŸαž˜αžΆαž“αž§αž”αž€αžšαžŽαŸαžŠαŸαž’αžŸαŸ’αž…αžΆαžšαŸ’αž™αž˜αž½αž™αžŠαŸ‚αž›αž˜αžΆαž“αžˆαŸ’αž˜αŸ„αŸ‡αžαžΆ Mikrotik αŸ” αžŠαŸ’αž™αžΆαž€αŸ’αžšαžΆαž˜αž”αžŽαŸ’αžαžΆαž‰αž‘αžΌαž‘αŸ…αž‚αžΊαžŠαžΌαž…αž“αŸαŸ‡αŸ–

αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž”αžŽαŸ’αžαžΆαž‰αž–αžΈ FreeRadius αžαžΆαž˜αžšαž™αŸˆ DHCP

αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž–αžΈαž€αžΆαžšαž‚αž·αžαž˜αž½αž™αž…αŸ†αž“αž½αž“ αžœαžΆαžαŸ’αžšαžΌαžœαž”αžΆαž“αžŸαž˜αŸ’αžšαŸαž…αž…αž·αžαŸ’αžαž”αŸ’αžšαžΎ FreeRadius αžŠαžΎαž˜αŸ’αž”αžΈαž…αŸαž‰αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž”αžŽαŸ’αžαžΆαž‰αžŠαž›αŸ‹αž’αžαž·αžαž·αž‡αž“αŸ” αž‡αžΆαž‚αŸ„αž›αž€αžΆαžšαžŽαŸ αž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαž‚αžΊαž’αž˜αŸ’αž˜αžαžΆαŸ– αž™αžΎαž„αž”αžΎαž€αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸ DHCP αž“αŸ…αž›αžΎ Microtick αž“αž·αž„ Radius Client αž“αŸ…αž›αžΎαžœαžΆαŸ” αž™αžΎαž„αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸ DHCP -> Radius Client -> Radius server connection αŸ”

αžœαžΆαž αžΆαž€αŸ‹αžŠαžΌαž…αž‡αžΆαž˜αž·αž“αž–αž·αž”αžΆαž€αž‘αŸαŸ” αžαŸ‚! αž’αžΆαžšαž€αŸ’αžŸαžŸαŸ’αžαž·αžαž“αŸ…αž€αŸ’αž“αž»αž„αž–αŸαžαŸŒαž˜αžΆαž“αž›αž˜αŸ’αž’αž·αžαŸ” αž–αŸ„αž›αž‚αžΊαŸ–

  • αž“αŸ…αž–αŸαž›αž’αž“αž»αž‰αŸ’αž‰αžΆαž PON OLT αžŠαŸ„αž™αž”αŸ’αžšαžΎαž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαž“αŸαŸ‡ αžŸαŸ†αžŽαžΎαžαŸ’αžšαžΌαžœαž”αžΆαž“αž•αŸ’αž‰αžΎαž‘αŸ… FreeRadius αžŠαŸ‚αž›αž˜αžΆαž“ User-Name αžŸαŸ’αž˜αžΎαž“αžΉαž„αž’αžΆαžŸαž™αžŠαŸ’αž‹αžΆαž“ MAC αž“αŸƒ headend αž—αŸ’αž“αžΆαž€αŸ‹αž„αžΆαžš-Circuit-Id αžŸαŸ’αž˜αžΎαž“αžΉαž„ MAC PON Onu αž“αž·αž„αž–αžΆαž€αŸ’αž™αžŸαž˜αŸ’αž„αžΆαžαŸ‹αž‘αž‘αŸαŸ”
  • αž“αŸ…αž–αŸαž›αž•αŸ’αžαž›αŸ‹αžŸαž·αž‘αŸ’αž’αž·αž–αžΈαž§αž”αž€αžšαžŽαŸαž”αŸ’αžαžΌαžšαž‡αžΆαž˜αž½αž™αž‡αž˜αŸ’αžšαžΎαžŸ 82 FreeRadius αž‘αž‘αž½αž›αž”αžΆαž“αžŸαŸ†αžŽαžΎαžŠαŸ‚αž›αž˜αžΆαž“αžˆαŸ’αž˜αŸ„αŸ‡αž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž‘αž‘αŸαžŸαŸ’αž˜αžΎαž“αžΉαž„ MAC αž“αŸƒαž§αž”αž€αžšαžŽαŸαžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αž‡αžΆαžœ αž αžΎαž™αž”αŸ†αž–αŸαž‰αžŠαŸ„αž™αž‚αž»αžŽαž›αž€αŸ’αžαžŽαŸˆαž”αž“αŸ’αžαŸ‚αž˜ Agent-Circuit-Id αž“αž·αž„ Agent-Remote-Id αžŠαŸ‚αž›αž˜αžΆαž“αžšαŸ€αž„αž‚αŸ’αž“αžΆαž˜αŸ’αžαž„αž‘αŸ€αž MAC αž“αŸƒ αž€αž»αž„αžαžΆαž€αŸ‹αž”αž‰αŸ’αž‡αžΌαž“αž αž“αž·αž„αž…αŸ’αžšαž€αžŠαŸ‚αž›αž’αžαž·αžαž·αž‡αž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αž—αŸ’αž‡αžΆαž”αŸ‹αŸ”
  • αž’αžαž·αžαž·αž‡αž“αž˜αž½αž™αž…αŸ†αž“αž½αž“αžŠαŸ‚αž›αž˜αžΆαž“αž…αŸ†αžŽαž»αž… WiFI αžαŸ’αžšαžΌαžœαž”αžΆαž“αž’αž“αž»αž‰αŸ’αž‰αžΆαžαžαžΆαž˜αžšαž™αŸˆαž–αž·αž’αžΈαž€αžΆαžš PAP-CHAP
  • αž’αžαž·αžαž·αž‡αž“αž˜αž½αž™αž…αŸ†αž“αž½αž“αž–αžΈαž…αŸ†αžŽαž»αž… WIFI αžαŸ’αžšαžΌαžœαž”αžΆαž“αž’αž“αž»αž‰αŸ’αž‰αžΆαžαžŠαŸ„αž™αžˆαŸ’αž˜αŸ„αŸ‡αž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αžŸαŸ’αž˜αžΎαž“αžΉαž„αž’αžΆαžŸαž™αžŠαŸ’αž‹αžΆαž“ MAC αž“αŸƒαž…αŸ†αžŽαž»αž… WIFI αžŠαŸ„αž™αž‚αŸ’αž˜αžΆαž“αž–αžΆαž€αŸ’αž™αžŸαž˜αŸ’αž„αžΆαžαŸ‹αŸ”

αž”αŸ’αžšαžœαžαŸ’αžαž·αž”αŸ’αžšαžœαžαŸ’αžαž·αžŸαžΆαžŸαŸ’αžαŸ’αžšαŸ– αž’αŸ’αžœαžΈαž‘αŸ…αž‡αžΆ "αž‡αž˜αŸ’αžšαžΎαžŸαž‘αžΈ ៨្" αž“αŸ…αž€αŸ’αž“αž»αž„ DHCP

αž‘αžΆαŸ†αž„αž“αŸαŸ‡αž‚αžΊαž‡αžΆαž‡αž˜αŸ’αžšαžΎαžŸαž”αž“αŸ’αžαŸ‚αž˜αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž–αž·αž’αžΈαž€αžΆαžš DHCP αžŠαŸ‚αž›αž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž’αŸ’αž“αž€αž•αŸ’αž‘αŸαžšαž–αŸαžαŸŒαž˜αžΆαž“αž”αž“αŸ’αžαŸ‚αž˜ αž§αž‘αžΆαž αžšαžŽαŸαž“αŸ…αž€αŸ’αž“αž»αž„αžœαžΆαž› Agent-Circuit-Id αž“αž·αž„ Agent-Remote-Id αŸ” αž‡αžΆαž’αž˜αŸ’αž˜αžαžΆαžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎαžŠαžΎαž˜αŸ’αž”αžΈαž”αž‰αŸ’αž‡αžΌαž“αž’αžΆαžŸαž™αžŠαŸ’αž‹αžΆαž“ MAC αž“αŸƒαž€αž»αž„αžαžΆαž€αŸ‹αž”αž‰αŸ’αž‡αžΌαž“αž αž“αž·αž„αž…αŸ’αžšαž€αžŠαŸ‚αž›αž’αžαž·αžαž·αž‡αž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αž—αŸ’αž‡αžΆαž”αŸ‹αŸ” αž€αŸ’αž“αž»αž„αž€αžšαžŽαžΈαž§αž”αž€αžšαžŽαŸ PON αž¬αžŸαŸ’αžαžΆαž“αžΈαž™αŸαž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“ WIFI αžœαžΆαž› Agent-Circuit-Id αž˜αž·αž“αž˜αžΆαž“αž–αŸαžαŸŒαž˜αžΆαž“αž˜αžΆαž“αž”αŸ’αžšαž™αŸ„αž‡αž“αŸ (αž˜αž·αž“αž˜αžΆαž“αž…αŸ’αžšαž€αž’αžαž·αžαž·αž‡αž“αž‘αŸ) αŸ” αž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαž‘αžΌαž‘αŸ…αž“αŸƒαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αžΆαžš DHCP αž€αŸ’αž“αž»αž„αž€αžšαžŽαžΈαž“αŸαŸ‡αž˜αžΆαž“αžŠαžΌαž…αžαžΆαž„αž€αŸ’αžšαŸ„αž˜:

αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž”αžŽαŸ’αžαžΆαž‰αž–αžΈ FreeRadius αžαžΆαž˜αžšαž™αŸˆ DHCP

αž˜αž½αž™αž‡αŸ†αž αžΆαž“αž˜αŸ’αžαž„ αŸ— αž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαž“αŸαŸ‡αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŠαžΌαž…αž“αŸαŸ‡αŸ–

  1. αž§αž”αž€αžšαžŽαŸαž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž”αž„αŸ’αž€αžΎαžαžŸαŸ†αžŽαžΎαž•αŸ’αžŸαžΆαž™ DHCP αžŠαžΎαž˜αŸ’αž”αžΈαž‘αž‘αž½αž›αž”αžΆαž“αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž”αžŽαŸ’αžαžΆαž‰
  2. αž§αž”αž€αžšαžŽαŸ (αž§αž‘αžΆαž αžšαžŽαŸ αž€αž»αž„αžαžΆαž€αŸ‹ αžœαŸ‰αžΆαž™αž αŸ’αžœαžΆαž™ αž¬αžŸαŸ’αžαžΆαž“αžΈαž™αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“ PON) αžŠαŸ‚αž›αž§αž”αž€αžšαžŽαŸαž’αžαž·αžαž·αž‡αž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αž—αŸ’αž‡αžΆαž”αŸ‹αžŠαŸ„αž™αž•αŸ’αž‘αžΆαž›αŸ‹ "αžŸαŸ’αž‘αžΆαž€αŸ‹αž…αžΆαž”αŸ‹" αž€αž‰αŸ’αž…αž”αŸ‹αž–αŸαžαŸŒαž˜αžΆαž“αž“αŸαŸ‡ αž αžΎαž™αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαžœαžΆ αžŠαŸ„αž™αžŽαŸ‚αž“αžΆαŸ†αž‡αž˜αŸ’αžšαžΎαžŸαž”αž“αŸ’αžαŸ‚αž˜ Option 82 αž“αž·αž„αž’αžΆαžŸαž™αžŠαŸ’αž‹αžΆαž“ IP αž—αŸ’αž“αžΆαž€αŸ‹αž„αžΆαžšαž”αž‰αŸ’αž‡αžΌαž“αž”αž“αŸ’αžαž‘αŸ…αž€αŸ’αž“αž»αž„αžœαžΆ αž αžΎαž™αž”αž‰αŸ’αž‡αžΌαž“αžœαžΆαž”αž“αŸ’αžαŸ‚αž˜αž‘αŸ€αžαŸ” αž”αžŽαŸ’αžαžΆαž‰αŸ”
  3. αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸ DHCP αž‘αž‘αž½αž›αž™αž€αžŸαŸ†αžŽαžΎ αž”αž„αŸ’αž€αžΎαžαž€αžΆαžšαž†αŸ’αž›αžΎαž™αžαž” αž“αž·αž„αž•αŸ’αž‰αžΎαžœαžΆαž‘αŸ…αž§αž”αž€αžšαžŽαŸαž”αž‰αŸ’αž‡αžΌαž“αž
  4. αž§αž”αž€αžšαžŽαŸαž”αž‰αŸ’αž‡αžΌαž“αž”αž“αŸ’αžαž”αž‰αŸ’αž‡αžΌαž“αž€αž‰αŸ’αž…αž”αŸ‹αž†αŸ’αž›αžΎαž™αžαž”αž‘αŸ…αž§αž”αž€αžšαžŽαŸαž’αŸ’αž“αž€αž‡αžΆαžœ

αž‡αžΆαž€αžΆαžšαž–αž·αžαžŽαžΆαžŸαŸ‹ αžœαžΆαž˜αž·αž“αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž™αŸ‰αžΆαž„αž„αžΆαž™αžŸαŸ’αžšαž½αž›αž“αŸ„αŸ‡αž‘αŸ αž’αŸ’αž“αž€αžαŸ’αžšαžΌαžœαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž§αž”αž€αžšαžŽαŸαž”αžŽαŸ’αžαžΆαž‰αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αž±αŸ’αž™αžŸαž˜αžŸαŸ’αžšαž”αŸ”

αž€αžΆαžšαžŠαŸ†αž‘αžΎαž„ FreeRadius

αž‡αžΆαž€αžΆαžšαž–αž·αžαžŽαžΆαžŸαŸ‹ αž“αŸαŸ‡αž’αžΆαž…αžŸαž˜αŸ’αžšαŸαž…αž”αžΆαž“αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’ FreeRadius αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžœαžΆαž–αž·αž”αžΆαž€αž“αž·αž„αž˜αž·αž“αž…αŸ’αž”αžΆαžŸαŸ‹αž›αžΆαžŸαŸ‹... αž‡αžΆαž–αž·αžŸαŸαžŸαž“αŸ…αž–αŸαž›αžŠαŸ‚αž›αž’αŸ’αž“αž€αž‘αŸ…αž‘αžΈαž“αŸ„αŸ‡αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž–αžΈ N αžαŸ‚ αž αžΎαž™ "αž’αŸ’αžœαžΈαŸ—αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš"αŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž αžΎαž™ αž™αžΎαž„αž”αžΆαž“αžŸαž˜αŸ’αžšαŸαž…αž…αž·αžαŸ’αžαžŸαžšαžŸαŸαžšαž˜αŸ‰αžΌαžŒαž»αž›αž€αžΆαžšαž’αž“αž»αž‰αŸ’αž‰αžΆαžαž•αŸ’αž‘αžΆαž›αŸ‹αžαŸ’αž›αž½αž“αžšαž”αžŸαŸ‹αž™αžΎαž„αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ FreeRadius αž“αŸ…αž€αŸ’αž“αž»αž„ Python αŸ” αž™αžΎαž„αž“αžΉαž„αž™αž€αž‘αž·αž“αŸ’αž“αž“αŸαž™αž€αžΆαžšαž’αž“αž»αž‰αŸ’αž‰αžΆαžαž–αžΈαž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™ MySQL αŸ” αžœαžΆαž‚αŸ’αž˜αžΆαž“αž“αŸαž™αž’αŸ’αžœαžΈαž‘αŸαž€αŸ’αž“αž»αž„αž€αžΆαžšαž–αž·αž–αžŽαŸŒαž“αžΆαž’αŸ†αž–αžΈαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžšαž”αžŸαŸ‹αžœαžΆ αž‘αŸ„αŸ‡αž”αžΈαž‡αžΆαž™αŸ‰αžΆαž„αžŽαžΆαž€αŸαžŠαŸ„αž™ αž˜αž“αž»αžŸαŸ’αžŸαž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αž“αžΆαž“αžΉαž„αž’αŸ’αžœαžΎαžœαžΆ "αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžαŸ’αž›αž½αž“αž‚αŸ"αŸ” αž‡αžΆαž–αž·αžŸαŸαžŸ αžαŸ’αž‰αž»αŸ†αž”αžΆαž“αž™αž€αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž”αžΆαž“αž•αŸ’αžαž›αŸ‹αž‡αžΌαž“αž‡αžΆαž˜αž½αž™αž˜αŸ‰αžΌαžŒαž»αž› sql αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ FreeRadius αž αžΎαž™αž”αžΆαž“αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαžœαžΆαž”αž“αŸ’αžαž·αž…αžŠαŸ„αž™αž”αž“αŸ’αžαŸ‚αž˜ mac αž“αž·αž„ port field αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž’αžαž·αžαž·αž‡αž“αž˜αŸ’αž“αžΆαž€αŸ‹αŸ— αž”αž“αŸ’αžαŸ‚αž˜αž›αžΎ login-password αŸ”

αžŠαžΌαž…αŸ’αž“αŸαŸ‡αžŠαŸ†αž”αžΌαž„ αžŠαŸ†αž‘αžΎαž„ FreeRadiusαŸ–

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

αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹ αžŸαžΌαž˜αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸαžŠαžΎαž˜αŸ’αž”αžΈαžŠαŸ†αž‘αžΎαž„αŸ–

αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž”αžŽαŸ’αžαžΆαž‰αž–αžΈ FreeRadius αžαžΆαž˜αžšαž™αŸˆ DHCP

αž™αžΎαž„αž”αž„αŸ’αž€αžΎαžαžαŸ†αžŽαž—αŸ’αž‡αžΆαž”αŸ‹αž“αž·αž˜αž·αžαŸ’αžαžŸαž‰αŸ’αž‰αžΆαž‘αŸ…αž˜αŸ‰αžΌαžŒαž»αž› python (ឧ. "αž”αžΎαž€" វអ):

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

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹