Вы Гость ( Вход | Регистрация )

DHCP server with SQL support on Perl DHCP сервер с базой SQL на Perl, с опцией 82, маршрутами и прочим
  • (16 Страниц)
  • +
  • 1
  • 2
  • 3
  • »
опции темы

Пользователь офлайн Ivan_83
11 марта 2011 - 00:50
Сообщение #1

Звание: Мой статус
Группа: VIP
Сообщений: 8 939
Регистрация: 18 октября 08
Город: Msk
Документация: http://www.netlab.li...erl:dhcp_server
Скачать: http://netlab.linkpc...cp_srv/dhcpd.pl
DHCP снифер для винды: http://www.netlab.li...n:net:dhcp_tool

Предлагаю обсуждать, предлагать фичи и патчи.

Сейчас есть готовый скелет, который будучи заряжен правильными SQL запросами вполне себе работает:
- отдаёт адреса и параметры взятые с базы через релей агентов (но не на прямые запросы), пишет в базу лог,
- обновляет в базе лизы
- многопоточный
- умеет миррорить запросы и ответы на указанный IP
- работать демоном (стартовый скрипт не написал, пишется шаблонно)
- несколько уровней вывода отладочной инфы: 1 - от кого, кому, время обработки, 2 - тоже что и 1 и декодинг содержимого пакетов

Кто немного знает перл и умеет писать запросы сможет быстро адаптировать под себя.
Все данные: статические и SQL запросы являющиеся приватными удалены.


КодUsage: dhcpd [options]
-b <ip> ip address to bind (def: 0.0.0.0)
-sp <port> port bind (def: 67)
-cp <port> port to send reply directly to client (def: 68)
-id <ip> ip addr DHCP server ID, REQUIRED!, MUST be real IP of server
-m <ip> ip address to mirror all packets on 67 port
-t <threads> number of thread, recomended: CPU cores * 2, (default 4)
-dbs database data source: DriverName:database=database_name;host=hostname;port=port
-dbl data base login
-dbp data base password
-P <path> name of PID-file for spawned process
-v <level> print debug info, levels: 1, 2 (def: off)
-d daemon mode

Соответственно, чтобы напустится нужно:
- дописать запросы, местами можно и закоментить (release, decline)
- перл с потоками + пакеты/порты указанные в комментах в начале скрипта

запускаю обычно: dhcpd.pl -id 192.168.0.1 -m 192.168.0.2 -t 2 -v 1
192.168.0.1 - адрес дхцп сервера (настроенный в релеях) к которому должны обращаться клиенты
192.168.0.2 - адрес куда миррорятся все пакеты, смотрю их под виндой этим: DHCPTool
2 - потока
1 - выводить минимум инфы о запросах: от кого получено, кому отправлено, сколько времени заняло
(для собственного удобства у меня все параметры: логин, пароль, адрес - для подключения к базе прописаны в скрипте)

Биндить лучше на 0.0.0.0, потому как если забиндить на конкретный IP то ответы будут уходить только с него, в случае нескольких адаптеров/алиасов остальные задействованны не будут. В таких случаях сервер будет получать, обрабатывать запрос но ответ уходить не будет.

Сообщение отредактировал Ivan_83: 20 мая 2015 - 23:29

 
Пользователь офлайн Lynx10
11 марта 2011 - 13:31
Сообщение #2

Звание: Аспирант
Группа: Активный участник
Сообщений: 977
Регистрация: 29 марта 09
Город: Ukraine
спасибо ! попробуем - что то похожее по функционалу на перле сами реализируем!
 
Пользователь офлайн Ivan_83
11 марта 2011 - 20:31
Сообщение #3

Звание: Мой статус
Группа: VIP
Сообщений: 8 939
Регистрация: 18 октября 08
Город: Msk
Обновил скрипт.


Немного логики, тем кто захочет писать запросы.

1. приходит запрос, в запросе есть:
82.Vlan ID
82.Unit ID (номер коммутатора в стёке)
82.Port ID
82.Chassis ID (мак коммутатора)
giaddr (relay agent IP)
DHCP Client ID - а это вообще генерирует клиент

опция 82 и giaddr могут не приходить при попытке продления клиентом времени аренды, тк клиент уже имеет IP адрес и пытается слать запрос напрямую серверу. Зависит от коммутатора, его настроек и его глючности.
Соответственно клиент потеряет аренду если не получит от него запроса на продление, и клиент начнёт по новой получать адрес.

Из этого многообразия нужно определить что будем использовать для идентификации клиента и сети клиента.
RFC2141 говорит что мы должны полагаться на DHCP Client ID, если её нет то на аппаратный адрес, при идентификации клиента.


2. На основании выбранного идентификатора из п1 ищем в базе настройки для сети:
[scope id] - некоторая информация по которой будем искать из п1 (к примеру: 82.vlan id)
DHCP enabled
Lease time
Renew time
Rebind Time
Subnet mask
Routers (default gateways)
Domain Name servers
Static routes
Classless routes (можно держать net_id и по нему делать выборку с др таблицы)
Domain name
...


3. Лиза клиента
[client id] (тут может быть, к примеру: 82.vlan id + 82.port id или DHCP Client ID, те кто привязывает адрес к порту должны либо настраивать коммутаторы чтобы опция82 добавлялась всегда, либо организовывать логику с учётом того что после получения адреса, клиент запрос для продления аренды будет слать на прямую серверу и он не всегда релееится - те приходит без опции 82)
End Lease Time
IP
...
параметры из п2 можно продублировать здесь и считать их главнее
Время обновляется при получении/продлении аренды, адрес в зависимости от настроек.


Это минимальная примерная логика обычных дхцп серверов.
 
Пользователь офлайн aivanzipper
15 марта 2011 - 14:04
Сообщение #4

Звание: Абитуриент
Группа: Участник
Сообщений: 12
Регистрация: 22 декабря 09
Город: Kyiyv
Почему скл-запросы убрали? Можно было бы вместе скрипт дальше разрабатывать. А сейчас это равносильно написанию по-новому...
 
Пользователь офлайн Ivan_83
15 марта 2011 - 15:53
Сообщение #5

Звание: Мой статус
Группа: VIP
Сообщений: 8 939
Регистрация: 18 октября 08
Город: Msk
По новому - это вы преувеличиваете.
Здесь остаётся только дописать запросы к базе и подправить под себя их распихивание по параметрам ответа, вся обвязка есть и работает.

Запросы были под самописный биллинг, более того там есть некоторая специфика выдачи адресов, потому эти запросы общественности совершенно бесполезны.
Остался один запрос: для маршрутов ибо оно универсально. Притом, те у кого используюется prefixlen вместо subnetmask получат небольшой прирост, а в коде достаточно заменить название функции.
Если посмотрите предыдущий пост, то там описаны примерные таблицы под "традиционную" работу дхцп сервера.
Позже я напишу запросы/базу по схеме из моего предыдущего поста.
Так же попробую сделать кеш запросов и может быть работу без релей агентов - тогда будет полноценный дхцп сервер.

Сейчас ведётся работа на гостевыми подсетями, когда заработает - я опишу логику здесь.


Вечером обновлю скрипт: вся логика работы с базой окончательно вынесена в отдельные функции, все параметры теперь передаются по ссылкам.
 
Пользователь офлайн aivanzipper
15 марта 2011 - 17:27
Сообщение #6

Звание: Абитуриент
Группа: Участник
Сообщений: 12
Регистрация: 22 декабря 09
Город: Kyiyv
Ivan_83, если Вы его "допилите" вам будут безмерно благодарны сотни администраторов сетей, так как нормального решения DHCP+MySQL на сег. день не существует.

Может, нужна помощь? Готов взять на тестирование.

Сообщение отредактировал aivanzipper: 15 марта 2011 - 17:34

 
Пользователь офлайн dwemer
16 марта 2011 - 07:32
Сообщение #7

Звание: Студент
Группа: Активный участник
Сообщений: 134
Регистрация: 02 февраля 07
Спасибо, работает. Как раз заморачиваюсь переходом на IPoE. Сейчас фрирадиус использую в качестве дхцп, но ваш скрипт как то ближе к телу, буду его под себя пилить.

Работа без релей агентов вряд ли понадобится.

в функции db_data_to_reply опечатка
Код
    if (index($_[1], DHO_DOMAIN_NAME) != -1) {
        $_[1]->addOptionValue(DHO_DOMAIN_NAME, $_[0]->{domain});
    }
$_[2]->addOptionValue Если вдруг кому неочевидно )

Сообщение отредактировал dwemer: 16 марта 2011 - 07:33

 
Пользователь офлайн Ivan_83
16 марта 2011 - 14:35
Сообщение #8

Звание: Мой статус
Группа: VIP
Сообщений: 8 939
Регистрация: 18 октября 08
Город: Msk
Фрирадиус я тоже пробовал.

Впечатления от него не очень, не для этого он:
- анлэнг на котором почти ничего нельзя сделать
- иногда падал в корку
- менее гибко при использовании перл орбработчика, чем сразу на перле
- под фряху тоже не умел биндится на интерфейс: те работал как мой скрипт - на обычном юдп сокете.

Были и плюсы:
- быстро отфутболивал левые запросы
- по отдельным параметрам запроса можно было фильтровать в анлэнге до перла, это тоже быстро
- можно было в простых случаях слать простые запросы в базу без перла (типа освобождение лизы - пометить что свободна)


Просмотр сообщенияdwemer (16 марта 2011 - 07:32) писал:

$_[2]->addOptionValue Если вдруг кому неочевидно )
Заметил по ругани в выводе :)

db_data_to_reply - сейчас с зачатками гостевых подсетей, а вообще видимо уже менятся её вызов не будет.
Надеюсь что для обновления скрипта будет достаточно только копировать свои функции-обёртки к базе в самом низу скрипта.

Качните заного, только что обновил.
 
Пользователь офлайн Ivan_83
16 марта 2011 - 15:17
Сообщение #9

Звание: Мой статус
Группа: VIP
Сообщений: 8 939
Регистрация: 18 октября 08
Город: Msk

Просмотр сообщенияaivanzipper (15 марта 2011 - 17:27) писал:

Ivan_83, если Вы его "допилите" вам будут безмерно благодарны сотни администраторов сетей, так как нормального решения DHCP+MySQL на сег. день не существует.
dhcpsql есть давно, и соседний топик про тоже самое только с нуля.
А нет потому что у всех потребности разные, и упихать в бинарник такую гибкость чтобы всем стало хорошо - сложно.


Просмотр сообщенияaivanzipper (15 марта 2011 - 17:27) писал:

Может, нужна помощь? Готов взять на тестирование.
Если только тыкать меня где я в перле не прав или можно было лучше/оптимальнее.
Тестируйте, пишите под себя запросы, можно и сразу веб интерфейс админки и будет счастье.

И чисто теоритически:
можно написать запросы в базу что бы прилетало в ответе: код опции - содержимое, и динамически это в скрипте упаковывать, а так же перенести часть логики в базу, тогда можно будет всё конфигурить только с базы, не трогая код что бы добавить опцию или что бы кому то отдавать по 82 опции а кому то просто по маку а кому то вообще статику.
После этого можно будет переписать на си и навесить рюшек.
 
Пользователь офлайн RomanCh
16 марта 2011 - 18:18
Сообщение #10

Звание: Студент
Группа: Активный участник
Сообщений: 108
Регистрация: 07 июня 09
Позволю себе вмешаться.

Просмотр сообщенияIvan_83 (16 марта 2011 - 15:17) писал:

Просмотр сообщенияaivanzipper (15 марта 2011 - 17:27) писал:

Ivan_83, если Вы его "допилите" вам будут безмерно благодарны сотни администраторов сетей, так как нормального решения DHCP+MySQL на сег. день не существует.
dhcpsql есть давно, и соседний топик про тоже самое только с нуля.
Не лукавьте. Вы сами пробовали dhcpsql который "есть давно"? Помнится я пытался его когда-то запустить:
1. Конфигурабельности - 0. Даже configure не задумано. И настроить гибко на работу с базой тоже вроде не тривиально (давно было, но хороших впечатлений не осталось).
2. Работает только с MySQL.
3. Сборка в FreeBSD:
Код
$ make
"Makefile", line 32: Need an operator
**** много таких строчек ****
make: fatal errors encountered -- cannot continue

Так что это - не "тоже самое только с нуля".

Просмотр сообщенияIvan_83 (16 марта 2011 - 15:17) писал:

А нет потому что у всех потребности разные, и упихать в бинарник такую гибкость чтобы всем стало хорошо - сложно.
Ну... Мы об этом уже говорили.

Просмотр сообщенияIvan_83 (16 марта 2011 - 15:17) писал:

можно написать запросы в базу что бы прилетало в ответе: код опции - содержимое, и динамически это в скрипте упаковывать, а так же перенести часть логики в базу, тогда можно будет всё конфигурить только с базы, не трогая код что бы добавить опцию или что бы кому то отдавать по 82 опции а кому то просто по маку а кому то вообще статику.
Мне кажется, или где-то я это уже видел?.. ;)
 
Пользователь офлайн Ivan_83
16 марта 2011 - 23:18
Сообщение #11

Звание: Мой статус
Группа: VIP
Сообщений: 8 939
Регистрация: 18 октября 08
Город: Msk

Просмотр сообщенияRomanCh (16 марта 2011 - 18:18) писал:

Не лукавьте. Вы сами пробовали dhcpsql который "есть давно"? Помнится я пытался его когда-то запустить:
Мне хватило взгляда на исходники что бы понять что это как минимум заброшено и не так гибко как фрирадиус+перл, которые на тот момент у меня уже как то работали.


Просмотр сообщенияRomanCh (16 марта 2011 - 18:18) писал:

Мне кажется, или где-то я это уже видел?.. ;)
хз

Идея выбирать с базы номера опций, вместо названий пришла пока писал и дозрела до момента написания этого сообщения.

Заменить кучу конструкций вида:
Код
    if (index($_[1], DHO_SUBNET_MASK()) != -1 && defined($_[0]->{mask})) {
        $_[2]->addOptionValue(DHO_SUBNET_MASK(), $_[0]->{mask});
    }



на что то типа:
Код
for (my $i = 0; $i < length($_[1]); $i++) {
    $optcode = $_[1][$i];
    if (defined($_[0]->{$optcode})) {
        $_[2]->addOptionValue($optcode, $_[0]->{$optcode});
    }
}
 
Пользователь офлайн RomanCh
17 марта 2011 - 02:13
Сообщение #12

Звание: Студент
Группа: Активный участник
Сообщений: 108
Регистрация: 07 июня 09

Просмотр сообщенияIvan_83 (16 марта 2011 - 23:18) писал:

Идея выбирать с базы номера опций, вместо названий пришла пока писал и дозрела до момента написания этого сообщения.
Может и так. Просто "в соседнем топике" обсуждается сервер который именно так и делает (+ выборка типа данных) ;) Думаю вы уже заметили, коли достаточно бдительно смотрели в код.
 
Пользователь офлайн Ivan_83
17 марта 2011 - 13:42
Сообщение #13

Звание: Мой статус
Группа: VIP
Сообщений: 8 939
Регистрация: 18 октября 08
Город: Msk

Просмотр сообщенияRomanCh (17 марта 2011 - 02:13) писал:

Может и так. Просто "в соседнем топике" обсуждается сервер который именно так и делает (+ выборка типа данных) ;) Думаю вы уже заметили, коли достаточно бдительно смотрели в код.
Смотрел на то что знаю: сеть и кеш :)

Для себя выделил такие типы и флаги в DHCPTool:
Код
#define DHCP_OPTP_T_NONE        0
#define DHCP_OPTP_T_SUBOPTS        1
#define DHCP_OPTP_T_BOOL        2
#define DHCP_OPTP_T_1BYTE        3
#define DHCP_OPTP_T_2BYTE        4
#define DHCP_OPTP_T_2TIME        5
#define DHCP_OPTP_T_4BYTE        6
#define DHCP_OPTP_T_4TIME        7
#define DHCP_OPTP_T_IPADDR        8
#define DHCP_OPTP_T_IPIPADDR    9
#define DHCP_OPTP_T_STR            10
#define DHCP_OPTP_T_STRUTF8        11
#define DHCP_OPTP_T_STRRR        12    // DNS string format
#define DHCP_OPTP_T_BYTES        13
#define DHCP_OPTP_T_ADV            14    // option have specific format
#define DHCP_OPTP_T_PAD            254
#define DHCP_OPTP_T_END            255


#define DHCP_OPTP_F_NONE        0
#define DHCP_OPTP_F_NOLEN        1
#define DHCP_OPTP_F_FIXEDLEN    2
#define DHCP_OPTP_F_MINLEN        4
#define DHCP_OPTP_F_ARRAY        8
// in case (FIXEDLEN + ARRAY), Len = sizeof 1 element


Применительно к серверу DHCP_OPTP_T_IPIPADDR не имеет смысла тк это фактически DHCP_OPTP_T_IPADDR + DHCP_OPTP_F_ARRAY
а для отображения опции 33 и 21 (Policy filter (dst net/mask)) удобнее.
DHCP_OPTP_T_*TIME тоже для удобства декондинга при отображении.
И много опций с DHCP_OPTP_T_ADV получилось, для которых уникальная обработка.
 
Пользователь офлайн Ilya Evseev
24 апреля 2011 - 10:13
Сообщение #14

Звание: Доцент
Группа: VIP
Сообщений: 1 954
Регистрация: 15 июля 06
Город: SPb~

Цитата

Срок регистрации домена rozhuk.org.ru закончился

Услуга по регистрации доменного имени rozhuk.org.ru временно не предоставляется.

Продлить домен

Если администратор домена не продлит регистрацию, домен освободится.

Непорядок.
 
Пользователь офлайн Ilya Evseev
28 апреля 2011 - 20:12
Сообщение #15

Звание: Доцент
Группа: VIP
Сообщений: 1 954
Регистрация: 15 июля 06
Город: SPb~
Т.к. топикстартер на форум не реагирует, сделана копия исходников
по адресу http://sources.homel.../rozhuk.org.ru/

whois rozhuk.org.ru | grep nserver
nslookup rozhuk.org.ru free01.editdns.net >> /etc/hosts; wget ...
 
Пользователь офлайн maxxch
12 мая 2011 - 23:54
Сообщение #16

Звание: Абитуриент
Группа: Участник
Сообщений: 14
Регистрация: 17 августа 10
большое спасибо, отличная работа. чуть подправил под себя.
кому интересно вот ссылки.
сам сервер dhcpd.pl
чуть опишу что сделал может кому пригодится
таблица my $table="dhcp_mac_ip";
всего 2 поля mac и ip но в формате bigint, при чем поле mac делаем уникальным.
все это подтачивалось под провайдера с 500 сетями в таблице маршрутизации.
да и кстати один нюанс, таблиц с сетью, броадкастом, рутером в данной реализации не нужно, все расчитывается динамически исходя из 2 обязательных факторов:
1. default route для всех ip является первая ip в сети(к примеру в сети 10.3.7.128/25 шлюзом будет 10.3.7.129)
2. все сети есть в таблице маршрутизации самого сервера.
таблица лога у меня такая
(`created`,`client_mac`,`client_ip`,`gateway_ip`,`client_ident`,`requested_ip`,`hostname`,`message_type`) поле client_mac уникальное.
в итоге очень напоминает вид ip->dhcpserver->leases у микротиков.
еще мелкие файлики для работы с базой
db_list.pl
live.pl
add.pl
и файлики которые помогут выбрать ip mac пары из dhcpd.conf
comments
par.pl
писал как умею так что не ругайте сильно, главное что все это запустил и работает на 5000 клиентах.
если кто сможет красиво и удобно доработать буду только рад.

Сообщение отредактировал maxxch: 13 мая 2011 - 13:54

 
Пользователь офлайн Ivan_83
20 мая 2011 - 23:04
Сообщение #17

Звание: Мой статус
Группа: VIP
Сообщений: 8 939
Регистрация: 18 октября 08
Город: Msk
Добавил функционал чтобы опции хранить в базе по номерам, но пока до конца не оттестил, возможно к концу следующей недели выложу.
 
Пользователь офлайн versen
31 мая 2011 - 18:56
Сообщение #18

Звание: Абитуриент
Группа: Участник
Сообщений: 12
Регистрация: 04 мая 09
Хочу сказать спасибо за программулину! Очень помогла!
У меня работает с opt82.

Только ни как не могу заставить в логи читабельно писать getOptionRaw(DHO_HOST_NAME()) (или getOptionValue(DHO_HOST_NAME())) русские названия.

Может кто знает?
 
Пользователь онлайн s.lobanov
31 мая 2011 - 20:09
Сообщение #19

Звание: Академик
Группа: VIP
Сообщений: 5 668
Регистрация: 23 февраля 10
кусок логов с русскими буквами выложите в виде файла
 
Пользователь офлайн versen
31 мая 2011 - 20:17
Сообщение #20

Звание: Абитуриент
Группа: Участник
Сообщений: 12
Регистрация: 04 мая 09

Просмотр сообщенияs.lobanov (31 мая 2011 - 20:09) писал:

кусок логов с русскими буквами выложите в виде файла


tail -n 1000 /var/log/dhcpsql.log | grep -a HOST > ~versen/WORK/dhcpsql.log.txt

Прикрепленные файлы

 
  • (16 Страниц)
  • +
  • 1
  • 2
  • 3
  • »
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей