Сетевые настройки из FreeRadius через DHCP

Прилетела задача наладить выдачу IP адресов абонентам. Условия задачи:

  • Отдельного сервера под авторизации не дадим — обойдетесь 😉
  • Абоненты должны получать сетевые настройки по DHCP
  • Сеть разнородная. Это и PON оборудование, и обычные свичи с настроенной Опцией 82 и WiFi базы с точками
  • Если ни под одно из условий выдачи IP данные не попадают — необходимо выдать IP из «гостевой» сети

Из хорошего: есть таки сервер на FreeBSD, который может «поработать», но он «за тридевять земель» ;),  не «прям в этой сети». Ещё есть устройство Mikrotik. Общая схема сети примерно такая:

Чуть поразмышляв, было принято решение использовать для выдачи сетевых настроек абонентам FreeRadius. В принципе схема обычная: на Microtick включаем DHCP сервер, на нем-же Radius Client. Настраиваем  связку DHCP server -> Radius Client -> Radius server.

Вроде бы не сложно. Но! Дьявол кроется в деталях. А именно:

  • При авторизации PON OLT по этой схеме на FreeRadius «прилетает» запрос с User-Name равному МАС адресу головной станции, Agent-Circuit-Id равному МАС PON Onu и пустым паролем.
  • При авторизации со свичей с опцией 82, на FreeRadius приходит запрос с пустым  User-Name равному МАС устройства  абонента и заполнеными дополнительными атрибутами Agent-Circuit-Id и Agent-Remote-Id содержащими соответственно опять же МАС релейного свича и порт к которому подключен абонент.
  • Часть абонентов с WiFI точек авторизуются через PAP-CHAP протоколы
  • Часть абонентов с WIFI точек авторизируются с User-Name равному МАС адресу WIFI точки, без пароля.

Историческая справка: что такое «Option 82» у DHCP

Это дополнительные опции у протокола DHCP которые позволяют передать дополнительную информацию, например в полях Agent-Circuit-Id  и Agent-Remote-Id. Обычно используется для передачи МАС адреса релейного свича и порта к которому подключен абонент. В случае оборудования PON или базовых станций WIFI поле Agent-Circuit-Id полезной информации не несёт (нет порта абонента).  При этом общая схема работы DHCP в этом случае следующая:

Пошагово эта схема работает так:

  1. Абонентское оборудование делает широковещательный DHCP запрос на получение сетевых настроек
  2. Устройство (например свич, базовая станция WiFi или PON) к которому непосредственно подключается абонентское оборудование «перехватывает» этот пакет и изменяет его, внедряя в него дополнительные опции Option 82 и Relay agent IP address,и передает его далее по сети.
  3. DHCP сервер принимает запрос, формирует ответ и отправляет его релейному устройству
  4. Релейное устройство переправляет пакет ответа на абонентское устройство

Так просто всё это конечно не работает, нужна соответствующая настройка сетевого оборудования.

Установка FreeRadius

Настройками конфигурации FreeRadius этого конечно достичь всего можно, но сложно и не понятно…особенно когда сунешься туда через N месяцев «всё работает». Потому было принято решение написать свой модуль авторизации для FreeRadius на Python. Данные для авторизации будем брать из базы MySQL. Структуру её описывать смысла нет, всё равно каждый будет её делать «под себя». В частности я взял структуру которая предлагается с модулем sql для FreeRadius, и чуть изменил, добавив поле mac и port для каждого абонента, помимо логина-пароля.

Итак, для начала устанавливаем FreeRadius:

В настройках отмечаем для установки:

Делаем симлинк на модуль python (т.е. «включаем» его):

Установим для python дополнительный модуль:

В настройках модуля python для FreeRadius, нужно прописать пути поиска модулей в переменную python_path. Например у меня это:

Пути можно узнать запустив интерпретатор python и введя команды:

Если не сделать этот шаг, то скрипты написанные на python и запущенные FreeRadius не найдут те модули, которые перечислены в import. Кроме того, необходимо раскоментировать в настройках модуля функции вызова авторизации и аккаунтинга. Например у меня выглядит данный модуль так:

Скрипт work.py (и все остальные) необходимо положить в /usr/local/etc/raddb/mods-config/python Всего скриптов у меня вышло три.

work.py:

func.py:

radiusd.py:

Как видно по коду, мы всеми доступными способами пытаемся идентифицировать абонента по его заведомо известным абонентским MAC адресам или связке Option 82, и если это не получается, то выдаем самый старый из использованных когда либо IP адресов из «гостевой» сети. Осталось настроить скрипт default в папке sites-enabled, для того чтобы нужные фукции из скрипта на python дергались в обозначенные моменты. Фактически достаточно файл привести к виду:

Пробуем запустить и посмотреть что прилетает в отладочный лог:

Что еще. При настройке FreeRadius удобно тестировать его работу при помощи утилиты radclient. Например авторизация:

Или аккаунтинг:

Хочу предупредить, что применять подобную схему и скрипты «без изменений» в «промышленных» масштабах ну никак нельзя. Как минимум бросаются в глаза:

  • возможна «подделка» MAC адреса. Достаточно абоненту прописать себе чужой MAC и будут проблемы
  • логика выдачи гостевых сетей ниже всякой критики. Нет даже проверки «у может уже есть клиенты с выданным таким IP адресом?»

Это просто «решение на коленке», для того чтобы работало конкретно в моих условиях, не более того. Не судите строго 😉

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.