DHCP āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ FreeRadius āĻĨ⧇āϕ⧇ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āϏ⧇āϟāĻŋāĻ‚āϏ

DHCP āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ FreeRadius āĻĨ⧇āϕ⧇ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āϏ⧇āϟāĻŋāĻ‚āϏ
āĻ•āĻžāϜāϟāĻŋ āĻ—ā§āϰāĻžāĻšāĻ•āĻĻ⧇āϰ āφāχāĻĒāĻŋ āĻ āĻŋāĻ•āĻžāύāĻž āĻĒā§āϰāĻĻāĻžāύ⧇āϰ āĻŦā§āϝāĻŦāĻ¸ā§āĻĨāĻž āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻĒ⧌āρāϛ⧇āϛ⧇āĨ¤ āϏāĻŽāĻ¸ā§āϝāĻžāϰ āĻļāĻ°ā§āϤ:

  • āĻ…āύ⧁āĻŽā§‹āĻĻāύ⧇āϰ āϜāĻ¨ā§āϝ āφāĻŽāϰāĻž āφāĻĒāύāĻžāϕ⧇ āφāϞāĻžāĻĻāĻž āϏāĻžāĻ°ā§āĻ­āĻžāϰ āĻĻ⧇āĻŦ āύāĻž - āφāĻĒāύāĻŋ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύ 😉
  • āĻ—ā§āϰāĻžāĻšāĻ•āĻĻ⧇āϰ āĻ…āĻŦāĻļā§āϝāχ DHCP āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āϏ⧇āϟāĻŋāĻ‚āϏ āĻ—ā§āϰāĻšāĻŖ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇
  • āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ•āϟāĻŋ āĻ­āĻŋāĻ¨ā§āύāϧāĻ°ā§āĻŽā§€āĨ¤ āĻāϰ āĻŽāĻ§ā§āϝ⧇ āϰāϝāĻŧ⧇āϛ⧇ PON āϏāϰāĻžā§āϜāĻžāĻŽ āĻāĻŦāĻ‚ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ āĻ•āϰāĻž āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ 82 āϏāĻš āύāĻŋāϝāĻŧāĻŽāĻŋāϤ āϏ⧁āχāϚ āĻāĻŦāĻ‚ āĻšāϟāĻ¸ā§āĻĒāϟ āϏāĻš āĻ“āϝāĻŧāĻžāχāĻĢāĻžāχ āĻŦ⧇āϏ
  • āϝāĻĻāĻŋ āĻĄā§‡āϟāĻž āφāχāĻĒāĻŋ āχāĻ¸ā§āϝ⧁ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āϕ⧋āύāĻ“ āĻļāĻ°ā§āϤ⧇āϰ āĻ…āϧ⧀āύ⧇ āύāĻž āĻĒāĻĄāĻŧ⧇ āϤāĻŦ⧇ āφāĻĒāύāĻžāϕ⧇ āĻ…āĻŦāĻļā§āϝāχ "āĻ…āϤāĻŋāĻĨāĻŋ" āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āĻĨ⧇āϕ⧇ āĻāĻ•āϟāĻŋ āφāχāĻĒāĻŋ āχāĻ¸ā§āϝ⧁ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āχāϤāĻŋāĻŦāĻžāϚāĻ• āĻĻāĻŋāĻ• āĻšāϞ⧋: āĻ•āĻŋāϛ⧁ āφāϛ⧇ āϏāĻžāĻ°ā§āĻ­āĻžāϰ FreeBSD-āϤ⧇, āϝ⧇āϟāĻž “āĻ•āĻžāϜ āĻ•āϰāϤ⧇ āĻĒāĻžāĻ°ā§‡â€, āĻ•āĻŋāĻ¨ā§āϤ⧁ āϏ⧇āϟāĻž “āĻ…āύ⧇āĻ• āĻĻā§‚āĻ°ā§‡â€ ;), “āĻ āĻŋāĻ• āĻāχ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ•ā§‡â€ āύāϝāĻŧāĨ¤

Mikrotik āύāĻžāĻŽā§‡ āĻāĻ•āϟāĻŋ āĻŦāĻŋāĻ¸ā§āĻŽāϝāĻŧāĻ•āϰ āϝāĻ¨ā§āĻ¤ā§āϰāĻ“ āϰāϝāĻŧ⧇āϛ⧇āĨ¤ āϏāĻžāϧāĻžāϰāĻŖ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āϚāĻŋāĻ¤ā§āϰāϟāĻŋ āĻāϰāĻ•āĻŽ āĻ•āĻŋāϛ⧁:

DHCP āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ FreeRadius āĻĨ⧇āϕ⧇ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āϏ⧇āϟāĻŋāĻ‚āϏ

āĻ•āĻŋāϛ⧁ āϚāĻŋāĻ¨ā§āϤāĻž āĻ•āϰāĻžāϰ āĻĒāϰ⧇, āĻ—ā§āϰāĻžāĻšāĻ•āĻĻ⧇āϰ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āϏ⧇āϟāĻŋāĻ‚āϏ āχāĻ¸ā§āϝ⧁ āĻ•āϰāϤ⧇ FreeRadius āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āϏāĻŋāĻĻā§āϧāĻžāĻ¨ā§āϤ āύ⧇āĻ“āϝāĻŧāĻž āĻšāϝāĻŧ⧇āĻ›āĻŋāϞāĨ¤ āύ⧀āϤāĻŋāĻ—āϤāĻ­āĻžāĻŦ⧇, āĻ¸ā§āĻ•āĻŋāĻŽāϟāĻŋ āĻ¸ā§āĻŦāĻžāĻ­āĻžāĻŦāĻŋāĻ•: āφāĻŽāϰāĻž āĻŽāĻžāχāĻ•ā§āϰ⧋āϟāĻŋāϕ⧇ DHCP āϏāĻžāĻ°ā§āĻ­āĻžāϰ āĻāĻŦāĻ‚ āĻāϟāĻŋāϤ⧇ āĻŦā§āϝāĻžāϏāĻžāĻ°ā§āϧ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āϟ āϏāĻ•ā§āώāĻŽ āĻ•āϰāĻŋāĨ¤ āφāĻŽāϰāĻž DHCP āϏāĻžāĻ°ā§āĻ­āĻžāϰ -> āĻŦā§āϝāĻžāϏāĻžāĻ°ā§āϧ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āϟ -> āĻŦā§āϝāĻžāϏāĻžāĻ°ā§āϧ āϏāĻžāĻ°ā§āĻ­āĻžāϰ āϏāĻ‚āϝ⧋āĻ— āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ āĻ•āϰāĻŋāĨ¤

āĻāϟāĻž āĻ•āĻ āĻŋāύ āĻŽāύ⧇ āĻšāϝāĻŧ āύāĻž. āĻ•āĻŋāĻ¨ā§āϤ⧁! āĻļāϝāĻŧāϤāĻžāύ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āφāϛ⧇. āϝāĻĨāĻž:

  • āĻāχ āĻ¸ā§āĻ•āĻŋāĻŽāϟāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāĻ•āϟāĻŋ PON OLT āĻ…āύ⧁āĻŽā§‹āĻĻāύ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ, āĻšā§‡āĻĄāĻāĻ¨ā§āĻĄā§‡āϰ MAC āĻ āĻŋāĻ•āĻžāύāĻžāϰ āϏāĻŽāĻžāύ āĻāĻ•āϟāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀-āύāĻžāĻŽ, MAC PON Onu-āĻāϰ āϏāĻŽāĻžāύ āĻāĻ•āϟāĻŋ Agent-Circuit-Id āĻāĻŦāĻ‚ āĻāĻ•āϟāĻŋ āĻ–āĻžāϞāĻŋ āĻĒāĻžāϏāĻ“āϝāĻŧāĻžāĻ°ā§āĻĄ āϏāĻš FreeRadius-āĻ āĻāĻ•āϟāĻŋ āĻ…āύ⧁āϰ⧋āϧ āĻĒāĻžāĻ āĻžāύ⧋ āĻšāϝāĻŧāĨ¤
  • āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ 82 āϏāĻš āϏ⧁āχāϚāϗ⧁āϞāĻŋ āĻĨ⧇āϕ⧇ āĻ…āύ⧁āĻŽā§‹āĻĻāύ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ, FreeRadius āĻ—ā§āϰāĻžāĻšāϕ⧇āϰ āĻĄāĻŋāĻ­āĻžāχāϏ⧇āϰ MAC-āĻāϰ āϏāĻŽāĻžāύ āĻāĻ•āϟāĻŋ āĻ–āĻžāϞāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀-āύāĻžāĻŽ āϏāĻš āĻāĻ•āϟāĻŋ āĻ…āύ⧁āϰ⧋āϧ āĻ—ā§āϰāĻšāĻŖ āĻ•āϰ⧇ āĻāĻŦāĻ‚ āϝāĻĨāĻžāĻ•ā§āϰāĻŽā§‡ āĻāĻœā§‡āĻ¨ā§āϟ-āϏāĻžāĻ°ā§āĻ•āĻŋāϟ-āφāχāĻĄāĻŋ āĻāĻŦāĻ‚ āĻāĻœā§‡āĻ¨ā§āϟ-āϰāĻŋāĻŽā§‹āϟ-āφāχāĻĄāĻŋ āϧāĻžāϰāĻŖāĻ•āĻžāϰ⧀ āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ⧇ āĻĒā§‚āĻ°ā§āĻŖ āĻšāϝāĻŧ, āφāĻŦāĻžāϰ āĻāϰ MAC āϰāĻŋāϞ⧇ āϏ⧁āχāϚ āĻāĻŦāĻ‚ āĻĒā§‹āĻ°ā§āϟ āϝ⧇āĻ–āĻžāύ⧇ āĻ—ā§āϰāĻžāĻšāĻ• āϏāĻ‚āϝ⧁āĻ•ā§āϤ āφāϛ⧇āĨ¤
  • āĻ“āϝāĻŧāĻžāχāĻĢāĻžāχ āĻĒāϝāĻŧ⧇āĻ¨ā§āϟ āϏāĻš āĻ•āĻŋāϛ⧁ āĻ—ā§āϰāĻžāĻšāĻ• PAP-CHAP āĻĒā§āϰ⧋āĻŸā§‹āĻ•āϞ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āĻ…āύ⧁āĻŽā§‹āĻĻāĻŋāϤ
  • WIFI āĻĒāϝāĻŧ⧇āĻ¨ā§āĻŸā§‡āϰ āĻ•āĻŋāϛ⧁ āĻ—ā§āϰāĻžāĻšāĻ•āϕ⧇ āĻĒāĻžāϏāĻ“āϝāĻŧāĻžāĻ°ā§āĻĄ āĻ›āĻžāĻĄāĻŧāĻžāχ WIFI āĻĒāϝāĻŧ⧇āĻ¨ā§āĻŸā§‡āϰ MAC āĻ āĻŋāĻ•āĻžāύāĻžāϰ āϏāĻŽāĻžāύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀-āύāĻžāĻŽ āĻĻāĻŋāϝāĻŧ⧇ āĻ…āύ⧁āĻŽā§‹āĻĻāĻŋāϤ āĻ•āϰāĻž āĻšāϝāĻŧāĨ¤

āϐāϤāĻŋāĻšāĻžāϏāĻŋāĻ• āĻĒāϟāĻ­ā§‚āĻŽāĻŋ: DHCP-āĻ "āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ 82" āĻ•āĻŋ

āĻāϗ⧁āϞāĻŋ DHCP āĻĒā§āϰ⧋āĻŸā§‹āĻ•āϞ⧇āϰ āϜāĻ¨ā§āϝ āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ āϝāĻž āφāĻĒāύāĻžāϕ⧇ āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āϤāĻĨā§āϝ āĻ¸ā§āĻĨāĻžāύāĻžāĻ¨ā§āϤāϰ āĻ•āϰāϤ⧇ āĻĻ⧇āϝāĻŧ, āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ āĻāĻœā§‡āĻ¨ā§āϟ-āϏāĻžāĻ°ā§āĻ•āĻŋāϟ-āφāχāĻĄāĻŋ āĻāĻŦāĻ‚ āĻāĻœā§‡āĻ¨ā§āϟ-āϰāĻŋāĻŽā§‹āϟ-āφāχāĻĄāĻŋ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇āĨ¤ āϏāĻžāϧāĻžāϰāĻŖāϤ āϰāĻŋāϞ⧇ āϏ⧁āχāĻšā§‡āϰ MAC āĻ āĻŋāĻ•āĻžāύāĻž āĻāĻŦāĻ‚ āĻ—ā§āϰāĻžāĻšāĻ• āϝ⧇ āĻĒā§‹āĻ°ā§āĻŸā§‡ āϏāĻ‚āϝ⧁āĻ•ā§āϤ āĻĨāĻžāϕ⧇ āϤāĻž āĻĒā§āϰ⧇āϰāĻŖ āĻ•āϰāϤ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧāĨ¤ PON āϏāϰāĻžā§āϜāĻžāĻŽ āĻŦāĻž WIFI āĻŦ⧇āϏ āĻ¸ā§āĻŸā§‡āĻļāύ⧇āϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇, Agent-Circuit-Id āĻĢāĻŋāĻ˛ā§āĻĄā§‡ āĻĻāϰāĻ•āĻžāϰ⧀ āϤāĻĨā§āϝ āĻĨāĻžāϕ⧇ āύāĻž (āϕ⧋āύ āĻ—ā§āϰāĻžāĻšāĻ• āĻĒā§‹āĻ°ā§āϟ āύ⧇āχ)āĨ¤ āĻāχ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ DHCP āĻ…āĻĒāĻžāϰ⧇āĻļāύ⧇āϰ āϏāĻžāϧāĻžāϰāĻŖ āĻ¸ā§āĻ•āĻŋāĻŽāϟāĻŋ āύāĻŋāĻŽā§āύāϰ⧂āĻĒ:

DHCP āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ FreeRadius āĻĨ⧇āϕ⧇ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āϏ⧇āϟāĻŋāĻ‚āϏ

āϧāĻžāĻĒ⧇ āϧāĻžāĻĒ⧇ āĻāχ āĻ¸ā§āĻ•āĻŋāĻŽāϟāĻŋ āĻāĻ­āĻžāĻŦ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇:

  1. āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϏāϰāĻžā§āϜāĻžāĻŽ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āϏ⧇āϟāĻŋāĻ‚āϏ āĻĒā§āϰāĻžāĻĒā§āϤ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ DHCP āϏāĻŽā§āĻĒā§āϰāϚāĻžāϰ āĻ…āύ⧁āϰ⧋āϧ āĻ•āϰ⧇
  2. āĻĄāĻŋāĻ­āĻžāχāϏāϟāĻŋ (āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, āĻāĻ•āϟāĻŋ āϏ⧁āχāϚ, āĻ“āϝāĻŧāĻžāχāĻĢāĻžāχ āĻŦāĻž PON āĻŦ⧇āϏ āĻ¸ā§āĻŸā§‡āĻļāύ) āϝ⧇āϟāĻŋāϰ āϏāĻžāĻĨ⧇ āĻ—ā§āϰāĻžāĻšāĻ• āϏāϰāĻžā§āϜāĻžāĻŽ āϏāϰāĻžāϏāϰāĻŋ āϏāĻ‚āϝ⧁āĻ•ā§āϤ āĻĨāĻžāϕ⧇ āĻāχ āĻĒā§āϝāĻžāϕ⧇āϟāϟāĻŋ "āχāĻ¨ā§āϟāĻžāϰāϏ⧇āĻĒā§āϟ" āĻ•āϰ⧇ āĻāĻŦāĻ‚ āĻāϟāĻŋāϕ⧇ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧇, āĻāϤ⧇ āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ 82 āĻāĻŦāĻ‚ āϰāĻŋāϞ⧇ āĻāĻœā§‡āĻ¨ā§āϟ āφāχāĻĒāĻŋ āĻ āĻŋāĻ•āĻžāύāĻž āĻĒā§āϰāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧇ āĻāĻŦāĻ‚ āĻāϟāĻŋāϕ⧇ āφāϰāĻ“ āωāĻĒāϰ⧇ āĻĒā§āϰ⧇āϰāĻŖ āĻ•āϰ⧇āĨ¤ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ•.
  3. DHCP āϏāĻžāĻ°ā§āĻ­āĻžāϰ āĻ…āύ⧁āϰ⧋āϧāϟāĻŋ āĻ—ā§āϰāĻšāĻŖ āĻ•āϰ⧇, āĻāĻ•āϟāĻŋ āĻĒā§āϰāϤāĻŋāĻ•ā§āϰāĻŋāϝāĻŧāĻž āϤ⧈āϰāĻŋ āĻ•āϰ⧇ āĻāĻŦāĻ‚ āϰāĻŋāϞ⧇ āĻĄāĻŋāĻ­āĻžāχāϏ⧇ āĻĒāĻžāĻ āĻžāϝāĻŧ
  4. āϰāĻŋāϞ⧇ āĻĄāĻŋāĻ­āĻžāχāϏāϟāĻŋ āϏāĻžāĻŦāĻ¸ā§āĻ•ā§āϰāĻžāχāĻŦāĻžāϰ āĻĄāĻŋāĻ­āĻžāχāϏ⧇ āĻĒā§āϰāϤāĻŋāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻĒā§āϝāĻžāϕ⧇āϟ āĻĢāϰ⧋āϝāĻŧāĻžāĻ°ā§āĻĄ āĻ•āϰ⧇

āĻ…āĻŦāĻļā§āϝāχ, āĻāϟāĻŋ āϏāĻŦ āϏāĻšāĻœā§‡ āĻ•āĻžāϜ āĻ•āϰ⧇ āύāĻž; āφāĻĒāύāĻžāϕ⧇ āϏ⧇āχ āĻ…āύ⧁āϝāĻžāϝāĻŧā§€ āφāĻĒāύāĻžāϰ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āϏāϰāĻžā§āϜāĻžāĻŽāϗ⧁āϞāĻŋ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤

FreeRadius āχāύāĻ¸ā§āϟāϞ āĻ•āϰāĻž āĻšāĻšā§āϛ⧇

āĻ…āĻŦāĻļā§āϝāχ, āĻāϟāĻŋ FreeRadius āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ⧇āĻļāύ āϏ⧇āϟāĻŋāĻ‚āϏ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āĻ…āĻ°ā§āϜāύ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇, āϤāĻŦ⧇ āĻāϟāĻŋ āĻ•āĻ āĻŋāύ āĻāĻŦāĻ‚ āĻ…āĻ¸ā§āĻĒāĻˇā§āϟ... āĻŦāĻŋāĻļ⧇āώ āĻ•āϰ⧇ āϝāĻ–āύ āφāĻĒāύāĻŋ N āĻŽāĻžāϏ āĻĒāϰ⧇ āϏ⧇āĻ–āĻžāύ⧇ āϝāĻžāύ āĻāĻŦāĻ‚ "āϏāĻŦāĻ•āĻŋāϛ⧁ āĻ•āĻžāϜ āĻ•āϰ⧇āĨ¤" āĻ…āϤāĻāĻŦ, āφāĻŽāϰāĻž āĻĒāĻžāχāĻĨāύ⧇ FreeRadius-āĻāϰ āϜāĻ¨ā§āϝ āφāĻŽāĻžāĻĻ⧇āϰ āύāĻŋāϜāĻ¸ā§āĻŦ āĻ…āύ⧁āĻŽā§‹āĻĻāύ āĻŽāĻĄāĻŋāωāϞ āϞ⧇āĻ–āĻžāϰ āϏāĻŋāĻĻā§āϧāĻžāĻ¨ā§āϤ āύāĻŋāϝāĻŧ⧇āĻ›āĻŋāĨ¤ āφāĻŽāϰāĻž āĻŽāĻžāχāĻāϏāĻ•āĻŋāωāĻāϞ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĨ⧇āϕ⧇ āĻ…āύ⧁āĻŽā§‹āĻĻāύ⧇āϰ āĻĄā§‡āϟāĻž āύ⧇āĻŦāĨ¤ āĻāϰ āĻ—āĻ āύ āĻŦāĻ°ā§āĻŖāύāĻž āĻ•āϰāĻžāϰ āϕ⧋āύ āĻŽāĻžāύ⧇ āύ⧇āχ; āϝāĻžāχāĻšā§‹āĻ•, āĻĒā§āϰāĻ¤ā§āϝ⧇āϕ⧇ āĻāϟāĻŋ "āύāĻŋāĻœā§‡āĻĻ⧇āϰ āϜāĻ¨ā§āϝ" āϤ⧈āϰāĻŋ āĻ•āϰāĻŦ⧇āĨ¤ āĻŦāĻŋāĻļ⧇āώ āĻ•āϰ⧇, āφāĻŽāĻŋ 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 āϏāĻ‚āĻŽāĻŋāĻļā§āϰāĻŖ āĻĻā§āĻŦāĻžāϰāĻž āωāĻĒāϞāĻŦā§āϧ āϏāĻŽāĻ¸ā§āϤ āĻĒāĻĻā§āϧāϤāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻ—ā§āϰāĻžāĻšāĻ•āϕ⧇ āϏāύāĻžāĻ•ā§āϤ āĻ•āϰāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĻ›āĻŋ, āĻāĻŦāĻ‚ āϝāĻĻāĻŋ āĻāϟāĻŋ āĻ•āĻžāϜ āύāĻž āĻ•āϰ⧇, āϤāĻžāĻšāϞ⧇ āφāĻŽāϰāĻž "āĻ…āϤāĻŋāĻĨāĻŋ" āĻĨ⧇āϕ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻĒā§āϰāĻžāĻšā§€āύāϤāĻŽ āφāχāĻĒāĻŋ āĻ āĻŋāĻ•āĻžāύāĻžāϟāĻŋ āχāĻ¸ā§āϝ⧁ āĻ•āϰāĻŋ " āĻ…āĻ¨ā§āϤāĻ°ā§āϜāĻžāϞ. āϝāĻž āĻ…āĻŦāĻļāĻŋāĻˇā§āϟ āĻĨāĻžāϕ⧇ āϤāĻž āĻšāϞ āϏāĻžāχāϟ-āϏāĻ•ā§āώāĻŽ āĻĢā§‹āĻ˛ā§āĻĄāĻžāϰ⧇ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ āĻ•āϰāĻž, āϝāĻžāϤ⧇ āĻĒāĻžāχāĻĨāύ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻĨ⧇āϕ⧇ āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧ āĻĢāĻžāĻ‚āĻļāύ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻŽā§āĻšā§āĻ°ā§āϤ⧇ āϟ⧁āχāϚ āĻ•āϰ⧇āĨ¤ āφāϏāϞ⧇, āĻĢāĻžāχāϞāϟāĻŋāϕ⧇ āĻĢāĻ°ā§āĻŽā§‡ āφāύāĻžāϰ āϜāĻ¨ā§āϝ āĻāϟāĻŋ āϝāĻĨ⧇āĻˇā§āϟ:

āĻĄāĻŋāĻĢāĻ˛ā§āϟ

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 āύāĻŋāĻŦāĻ¨ā§āϧāύ āĻ•āϰāĻž āϝāĻĨ⧇āĻˇā§āϟ āĻāĻŦāĻ‚ āϏāĻŽāĻ¸ā§āϝāĻž āĻšāĻŦ⧇
  • āϗ⧇āĻ¸ā§āϟ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āχāĻ¸ā§āϝ⧁ āĻ•āϰāĻžāϰ āϝ⧁āĻ•ā§āϤāĻŋ āϏāĻŽāĻžāϞ⧋āϚāύāĻžāϰ āĻŦāĻžāχāϰ⧇āĨ¤ āĻāĻŽāύāĻ•āĻŋ āĻāĻ•āϟāĻŋ āĻšā§‡āĻ•āĻ“ āύ⧇āχ "āϏāĻŽā§āĻ­āĻŦāϤ āĻāĻ•āχ āφāχāĻĒāĻŋ āĻ āĻŋāĻ•āĻžāύāĻžāϰ āχāϤāĻŋāĻŽāĻ§ā§āϝ⧇āχ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āϟ āφāϛ⧇?"

āĻāϟāĻŋ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻāĻ•āϟāĻŋ "āϕ⧁āĻ•āĻŋ-āĻ•āĻžāϟāĻžāϰ āϏāϞāĻŋāωāĻļāύ" āϝāĻž āĻŦāĻŋāĻļ⧇āώāĻ­āĻžāĻŦ⧇ āφāĻŽāĻžāϰ āĻļāĻ°ā§āϤ⧇ āĻ•āĻžāϜ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻĄāĻŋāϜāĻžāχāύ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇, āφāϰ āĻ•āĻŋāϛ⧁āχ āύāϝāĻŧāĨ¤ āĻ•āĻ ā§‹āϰāĻ­āĻžāĻŦ⧇ āĻŦāĻŋāϚāĻžāϰ āĻ•āϰāĻŦ⧇āύ āύāĻž 😉

āωāĻ¤ā§āϏ: www.habr.com

DDoS āϏ⧁āϰāĻ•ā§āώāĻž, VPS VDS āϏāĻžāĻ°ā§āĻ­āĻžāϰ āϏāĻš āϏāĻžāχāϟāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āύāĻŋāĻ°ā§āĻ­āϰāϝ⧋āĻ—ā§āϝ āĻšā§‹āĻ¸ā§āϟāĻŋāĻ‚ āĻ•āĻŋāύ⧁āύ đŸ”Ĩ DDoS āϏ⧁āϰāĻ•ā§āώāĻž āϏāĻš āύāĻŋāĻ°ā§āĻ­āϰāϝ⧋āĻ—ā§āϝ āĻ“āϝāĻŧ⧇āĻŦāϏāĻžāχāϟ āĻšā§‹āĻ¸ā§āϟāĻŋāĻ‚ āĻ•āĻŋāύ⧁āύ, VPS VDS āϏāĻžāĻ°ā§āĻ­āĻžāϰ | ProHoster