DHCP ಮೂಲಕ FreeRadius ನಿಂದ ನೆಟ್‌ವರ್ಕ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು

DHCP ಮೂಲಕ FreeRadius ನಿಂದ ನೆಟ್‌ವರ್ಕ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು
ಚಂದಾದಾರರಿಗೆ IP ವಿಳಾಸಗಳ ವಿತರಣೆಯನ್ನು ವ್ಯವಸ್ಥೆಗೊಳಿಸಲು ಕಾರ್ಯವು ಬಂದಿತು. ಸಮಸ್ಯೆಯ ಪರಿಸ್ಥಿತಿಗಳು:

  • ದೃಢೀಕರಣಕ್ಕಾಗಿ ನಾವು ನಿಮಗೆ ಪ್ರತ್ಯೇಕ ಸರ್ವರ್ ಅನ್ನು ನೀಡುವುದಿಲ್ಲ - ನೀವು ಮಾಡುತ್ತೀರಿ 😉
  • ಚಂದಾದಾರರು DHCP ಮೂಲಕ ನೆಟ್ವರ್ಕ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಬೇಕು
  • ಜಾಲವು ವೈವಿಧ್ಯಮಯವಾಗಿದೆ. ಇದು PON ಉಪಕರಣಗಳು ಮತ್ತು ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾದ ಆಯ್ಕೆ 82 ಜೊತೆಗೆ ಸಾಮಾನ್ಯ ಸ್ವಿಚ್‌ಗಳು ಮತ್ತು ಹಾಟ್‌ಸ್ಪಾಟ್‌ಗಳೊಂದಿಗೆ ವೈಫೈ ಬೇಸ್‌ಗಳನ್ನು ಒಳಗೊಂಡಿದೆ
  • IP ಅನ್ನು ನೀಡುವ ಯಾವುದೇ ಷರತ್ತುಗಳ ಅಡಿಯಲ್ಲಿ ಡೇಟಾ ಬರದಿದ್ದರೆ, ನೀವು "ಅತಿಥಿ" ನೆಟ್ವರ್ಕ್ನಿಂದ IP ಅನ್ನು ನೀಡಬೇಕು

ಉತ್ತಮ ಭಾಗದಲ್ಲಿ: FreeBSD ನಲ್ಲಿ "ಕೆಲಸ" ಮಾಡಬಹುದಾದ ಸರ್ವರ್ ಇನ್ನೂ ಇದೆ, ಆದರೆ ಅದು "ದೂರದಲ್ಲಿದೆ" ;), "ಈ ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ಬಲ" ಅಲ್ಲ.

Mikrotik ಎಂಬ ಅದ್ಭುತ ಸಾಧನವೂ ಇದೆ. ಸಾಮಾನ್ಯ ನೆಟ್ವರ್ಕ್ ರೇಖಾಚಿತ್ರವು ಈ ರೀತಿಯಾಗಿದೆ:

DHCP ಮೂಲಕ FreeRadius ನಿಂದ ನೆಟ್‌ವರ್ಕ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು

ಸ್ವಲ್ಪ ಚಿಂತನೆಯ ನಂತರ, ಚಂದಾದಾರರಿಗೆ ನೆಟ್ವರ್ಕ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ನೀಡಲು FreeRadius ಅನ್ನು ಬಳಸಲು ನಿರ್ಧರಿಸಲಾಯಿತು. ತಾತ್ವಿಕವಾಗಿ, ಯೋಜನೆಯು ಸಾಮಾನ್ಯವಾಗಿದೆ: ನಾವು ಮೈಕ್ರೋಟಿಕ್‌ನಲ್ಲಿ DHCP ಸರ್ವರ್ ಮತ್ತು ಅದರ ಮೇಲೆ ರೇಡಿಯಸ್ ಕ್ಲೈಂಟ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತೇವೆ. ನಾವು DHCP ಸರ್ವರ್ -> ರೇಡಿಯಸ್ ಕ್ಲೈಂಟ್ -> ತ್ರಿಜ್ಯದ ಸರ್ವರ್ ಸಂಪರ್ಕವನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡುತ್ತೇವೆ.

ಇದು ಕಷ್ಟ ಅನಿಸುವುದಿಲ್ಲ. ಆದರೆ! ದೆವ್ವವು ವಿವರಗಳಲ್ಲಿದೆ. ಅವುಗಳೆಂದರೆ:

  • ಈ ಸ್ಕೀಮ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು PON OLT ಅನ್ನು ಅಧಿಕೃತಗೊಳಿಸುವಾಗ, ಹೆಡೆಂಡ್‌ನ MAC ವಿಳಾಸಕ್ಕೆ ಸಮಾನವಾದ ಬಳಕೆದಾರ-ಹೆಸರು, MAC PON ಓನುಗೆ ಸಮಾನವಾದ ಏಜೆಂಟ್-ಸರ್ಕ್ಯೂಟ್-ಐಡಿ ಮತ್ತು ಖಾಲಿ ಪಾಸ್‌ವರ್ಡ್‌ನೊಂದಿಗೆ ವಿನಂತಿಯನ್ನು FreeRadius ಗೆ ಕಳುಹಿಸಲಾಗುತ್ತದೆ.
  • ಆಯ್ಕೆ 82 ನೊಂದಿಗೆ ಸ್ವಿಚ್‌ಗಳಿಂದ ಅಧಿಕೃತಗೊಳಿಸುವಾಗ, FreeRadius ಚಂದಾದಾರರ ಸಾಧನದ MAC ಗೆ ಸಮಾನವಾದ ಖಾಲಿ ಬಳಕೆದಾರ-ಹೆಸರಿನೊಂದಿಗೆ ವಿನಂತಿಯನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ ಮತ್ತು ಹೆಚ್ಚುವರಿ ಗುಣಲಕ್ಷಣಗಳನ್ನು ಹೊಂದಿರುವ ಏಜೆಂಟ್-ಸರ್ಕ್ಯೂಟ್-ಐಡಿ ಮತ್ತು ಏಜೆಂಟ್-ರಿಮೋಟ್-ಐಡಿಯನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ, ಮತ್ತೆ MAC ರಿಲೇ ಸ್ವಿಚ್ ಮತ್ತು ಚಂದಾದಾರರು ಸಂಪರ್ಕಗೊಂಡಿರುವ ಪೋರ್ಟ್.
  • ವೈಫೈ ಪಾಯಿಂಟ್‌ಗಳನ್ನು ಹೊಂದಿರುವ ಕೆಲವು ಚಂದಾದಾರರನ್ನು PAP-CHAP ಪ್ರೋಟೋಕಾಲ್‌ಗಳ ಮೂಲಕ ಅಧಿಕೃತಗೊಳಿಸಲಾಗುತ್ತದೆ
  • WIFI ಪಾಯಿಂಟ್‌ಗಳಿಂದ ಕೆಲವು ಚಂದಾದಾರರು ಪಾಸ್‌ವರ್ಡ್ ಇಲ್ಲದೆಯೇ, WIFI ಪಾಯಿಂಟ್‌ನ MAC ವಿಳಾಸಕ್ಕೆ ಸಮಾನವಾದ ಬಳಕೆದಾರ-ಹೆಸರಿನೊಂದಿಗೆ ಅಧಿಕೃತರಾಗಿದ್ದಾರೆ.

ಐತಿಹಾಸಿಕ ಹಿನ್ನೆಲೆ: DHCP ಯಲ್ಲಿ "ಆಯ್ಕೆ 82" ಎಂದರೇನು

ಇವುಗಳು DHCP ಪ್ರೋಟೋಕಾಲ್‌ಗಾಗಿ ಹೆಚ್ಚುವರಿ ಆಯ್ಕೆಗಳಾಗಿವೆ, ಇದು ಹೆಚ್ಚುವರಿ ಮಾಹಿತಿಯನ್ನು ವರ್ಗಾಯಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ, ಉದಾಹರಣೆಗೆ ಏಜೆಂಟ್-ಸರ್ಕ್ಯೂಟ್-ಐಡಿ ಮತ್ತು ಏಜೆಂಟ್-ರಿಮೋಟ್-ಐಡಿ ಕ್ಷೇತ್ರಗಳಲ್ಲಿ. ರಿಲೇ ಸ್ವಿಚ್‌ನ MAC ವಿಳಾಸ ಮತ್ತು ಚಂದಾದಾರರು ಸಂಪರ್ಕಗೊಂಡಿರುವ ಪೋರ್ಟ್ ಅನ್ನು ರವಾನಿಸಲು ಸಾಮಾನ್ಯವಾಗಿ ಬಳಸಲಾಗುತ್ತದೆ. PON ಉಪಕರಣಗಳು ಅಥವಾ ವೈಫೈ ಬೇಸ್ ಸ್ಟೇಷನ್‌ಗಳ ಸಂದರ್ಭದಲ್ಲಿ, ಏಜೆಂಟ್-ಸರ್ಕ್ಯೂಟ್-ಐಡಿ ಕ್ಷೇತ್ರವು ಉಪಯುಕ್ತ ಮಾಹಿತಿಯನ್ನು ಹೊಂದಿರುವುದಿಲ್ಲ (ಯಾವುದೇ ಚಂದಾದಾರರ ಪೋರ್ಟ್ ಇಲ್ಲ). ಈ ಸಂದರ್ಭದಲ್ಲಿ DHCP ಕಾರ್ಯಾಚರಣೆಯ ಸಾಮಾನ್ಯ ಯೋಜನೆ ಹೀಗಿದೆ:

DHCP ಮೂಲಕ FreeRadius ನಿಂದ ನೆಟ್‌ವರ್ಕ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು

ಹಂತ ಹಂತವಾಗಿ ಈ ಯೋಜನೆಯು ಈ ರೀತಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ:

  1. ನೆಟ್‌ವರ್ಕ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಪಡೆಯಲು ಬಳಕೆದಾರರ ಉಪಕರಣವು DHCP ಪ್ರಸಾರ ವಿನಂತಿಯನ್ನು ಮಾಡುತ್ತದೆ
  2. ಚಂದಾದಾರರ ಉಪಕರಣವು ನೇರವಾಗಿ ಸಂಪರ್ಕಗೊಂಡಿರುವ ಸಾಧನವು (ಉದಾಹರಣೆಗೆ, ಸ್ವಿಚ್, ವೈಫೈ ಅಥವಾ PON ಬೇಸ್ ಸ್ಟೇಷನ್) ಈ ಪ್ಯಾಕೆಟ್ ಅನ್ನು "ಪ್ರತಿಬಂಧಿಸುತ್ತದೆ" ಮತ್ತು ಅದನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ, ಹೆಚ್ಚುವರಿ ಆಯ್ಕೆಗಳಾದ ಆಯ್ಕೆ 82 ಮತ್ತು ರಿಲೇ ಏಜೆಂಟ್ IP ವಿಳಾಸವನ್ನು ಪರಿಚಯಿಸುತ್ತದೆ ಮತ್ತು ಅದನ್ನು ಮತ್ತಷ್ಟು ರವಾನಿಸುತ್ತದೆ. ಜಾಲಬಂಧ.
  3. DHCP ಸರ್ವರ್ ವಿನಂತಿಯನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ, ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆ ಮತ್ತು ಅದನ್ನು ರಿಲೇ ಸಾಧನಕ್ಕೆ ಕಳುಹಿಸುತ್ತದೆ
  4. ರಿಲೇ ಸಾಧನವು ಪ್ರತಿಕ್ರಿಯೆ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಚಂದಾದಾರರ ಸಾಧನಕ್ಕೆ ಫಾರ್ವರ್ಡ್ ಮಾಡುತ್ತದೆ

ಸಹಜವಾಗಿ, ಎಲ್ಲವೂ ಅಷ್ಟು ಸುಲಭವಾಗಿ ಕೆಲಸ ಮಾಡುವುದಿಲ್ಲ; ಅದಕ್ಕೆ ಅನುಗುಣವಾಗಿ ನಿಮ್ಮ ನೆಟ್‌ವರ್ಕ್ ಉಪಕರಣಗಳನ್ನು ನೀವು ಕಾನ್ಫಿಗರ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.

FreeRadius ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ

ಸಹಜವಾಗಿ, ಇದನ್ನು FreeRadius ಕಾನ್ಫಿಗರೇಶನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳೊಂದಿಗೆ ಸಾಧಿಸಬಹುದು, ಆದರೆ ಇದು ಕಷ್ಟಕರ ಮತ್ತು ಅಸ್ಪಷ್ಟವಾಗಿದೆ ... ವಿಶೇಷವಾಗಿ ನೀವು N ತಿಂಗಳ ನಂತರ ಅಲ್ಲಿಗೆ ಹೋದಾಗ ಮತ್ತು "ಎಲ್ಲವೂ ಕೆಲಸ ಮಾಡುತ್ತದೆ." ಆದ್ದರಿಂದ, ನಾವು ಪೈಥಾನ್‌ನಲ್ಲಿ FreeRadius ಗಾಗಿ ನಮ್ಮದೇ ಆದ ದೃಢೀಕರಣ ಮಾಡ್ಯೂಲ್ ಅನ್ನು ಬರೆಯಲು ನಿರ್ಧರಿಸಿದ್ದೇವೆ. ನಾವು MySQL ಡೇಟಾಬೇಸ್‌ನಿಂದ ಅಧಿಕೃತ ಡೇಟಾವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತೇವೆ. ಅದರ ರಚನೆಯನ್ನು ವಿವರಿಸುವುದರಲ್ಲಿ ಯಾವುದೇ ಅರ್ಥವಿಲ್ಲ; ಹೇಗಾದರೂ, ಪ್ರತಿಯೊಬ್ಬರೂ ಅದನ್ನು "ತಮಗಾಗಿ" ಮಾಡುತ್ತಾರೆ. ನಿರ್ದಿಷ್ಟವಾಗಿ ಹೇಳುವುದಾದರೆ, FreeRadius ಗಾಗಿ sql ಮಾಡ್ಯೂಲ್‌ನೊಂದಿಗೆ ನೀಡಲಾದ ರಚನೆಯನ್ನು ನಾನು ತೆಗೆದುಕೊಂಡಿದ್ದೇನೆ ಮತ್ತು ಲಾಗಿನ್-ಪಾಸ್‌ವರ್ಡ್‌ಗೆ ಹೆಚ್ಚುವರಿಯಾಗಿ ಪ್ರತಿ ಚಂದಾದಾರರಿಗೆ ಮ್ಯಾಕ್ ಮತ್ತು ಪೋರ್ಟ್ ಕ್ಷೇತ್ರವನ್ನು ಸೇರಿಸುವ ಮೂಲಕ ಅದನ್ನು ಸ್ವಲ್ಪ ಬದಲಾಯಿಸಿದೆ.

ಆದ್ದರಿಂದ, ಮೊದಲು, FreeRadius ಅನ್ನು ಸ್ಥಾಪಿಸಿ:

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

ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ, ಸ್ಥಾಪಿಸಲು ಆಯ್ಕೆಮಾಡಿ:

DHCP ಮೂಲಕ FreeRadius ನಿಂದ ನೆಟ್‌ವರ್ಕ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು

ನಾವು ಪೈಥಾನ್ ಮಾಡ್ಯೂಲ್‌ಗೆ ಸಿಮ್‌ಲಿಂಕ್ ಮಾಡುತ್ತೇವೆ (ಅಂದರೆ ಅದನ್ನು "ಆನ್" ಮಾಡಿ):

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

ಪೈಥಾನ್‌ಗಾಗಿ ಹೆಚ್ಚುವರಿ ಮಾಡ್ಯೂಲ್ ಅನ್ನು ಸ್ಥಾಪಿಸೋಣ:

pip install mysql-connector

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"

ಪೈಥಾನ್ ಇಂಟರ್ಪ್ರಿಟರ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುವ ಮೂಲಕ ಮತ್ತು ಆಜ್ಞೆಗಳನ್ನು ನಮೂದಿಸುವ ಮೂಲಕ ನೀವು ಮಾರ್ಗಗಳನ್ನು ಕಂಡುಹಿಡಿಯಬಹುದು:

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']
>

ನೀವು ಈ ಹಂತವನ್ನು ತೆಗೆದುಕೊಳ್ಳದಿದ್ದರೆ, ಪೈಥಾನ್‌ನಲ್ಲಿ ಬರೆಯಲಾದ ಮತ್ತು 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 ವಿಳಾಸವನ್ನು ನೀಡುತ್ತೇವೆ. "ನೆಟ್ವರ್ಕ್. ಸೈಟ್‌ಗಳು-ಸಕ್ರಿಯಗೊಳಿಸಿದ ಫೋಲ್ಡರ್‌ನಲ್ಲಿ ಡೀಫಾಲ್ಟ್ ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡುವುದು ಮಾತ್ರ ಉಳಿದಿದೆ, ಆದ್ದರಿಂದ ಪೈಥಾನ್ ಸ್ಕ್ರಿಪ್ಟ್‌ನಿಂದ ಅಗತ್ಯ ಕಾರ್ಯಗಳು ಗೊತ್ತುಪಡಿಸಿದ ಕ್ಷಣಗಳಲ್ಲಿ ಟ್ವಿಚ್ ಆಗುತ್ತವೆ. ವಾಸ್ತವವಾಗಿ, ಫೈಲ್ ಅನ್ನು ಫಾರ್ಮ್ಗೆ ತರಲು ಸಾಕು:

ಡೀಫಾಲ್ಟ್

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 ಅನ್ನು ಹೊಂದಿಸುವಾಗ, ರಾಡ್ಕ್ಲೈಂಟ್ ಉಪಯುಕ್ತತೆಯನ್ನು ಬಳಸಿಕೊಂಡು ಅದರ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ಪರೀಕ್ಷಿಸಲು ಅನುಕೂಲಕರವಾಗಿದೆ. ಉದಾಹರಣೆಗೆ ಅಧಿಕಾರ:

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

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ