Перейти к содержимому
Калькуляторы

DHCP server with SQL support on Perl DHCP сервер с базой SQL на Perl, с опцией 82, маршрутами и прочим

Документация: http://www.netlab.linkpc.net/wiki/ru:software:perl:dhcp_server

Скачать: http://netlab.linkpc.net/download/software/perl/dhcp_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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

спасибо ! попробуем - что то похожее по функционалу на перле сами реализируем!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Обновил скрипт.

 

 

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

 

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 можно продублировать здесь и считать их главнее

Время обновляется при получении/продлении аренды, адрес в зависимости от настроек.

 

 

Это минимальная примерная логика обычных дхцп серверов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Почему скл-запросы убрали? Можно было бы вместе скрипт дальше разрабатывать. А сейчас это равносильно написанию по-новому...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

По новому - это вы преувеличиваете.

Здесь остаётся только дописать запросы к базе и подправить под себя их распихивание по параметрам ответа, вся обвязка есть и работает.

 

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

Остался один запрос: для маршрутов ибо оно универсально. Притом, те у кого используюется prefixlen вместо subnetmask получат небольшой прирост, а в коде достаточно заменить название функции.

Если посмотрите предыдущий пост, то там описаны примерные таблицы под "традиционную" работу дхцп сервера.

Позже я напишу запросы/базу по схеме из моего предыдущего поста.

Так же попробую сделать кеш запросов и может быть работу без релей агентов - тогда будет полноценный дхцп сервер.

 

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

 

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

 

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

Изменено пользователем aivanzipper

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо, работает. Как раз заморачиваюсь переходом на IPoE. Сейчас фрирадиус использую в качестве дхцп, но ваш скрипт как то ближе к телу, буду его под себя пилить.

 

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

 

в функции db_data_to_reply опечатка

    if (index($_[1], DHO_DOMAIN_NAME) != -1) {
        $_[1]->addOptionValue(DHO_DOMAIN_NAME, $_[0]->{domain});
    }

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

Изменено пользователем dwemer

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Фрирадиус я тоже пробовал.

 

Впечатления от него не очень, не для этого он:

- анлэнг на котором почти ничего нельзя сделать

- иногда падал в корку

- менее гибко при использовании перл орбработчика, чем сразу на перле

- под фряху тоже не умел биндится на интерфейс: те работал как мой скрипт - на обычном юдп сокете.

 

Были и плюсы:

- быстро отфутболивал левые запросы

- по отдельным параметрам запроса можно было фильтровать в анлэнге до перла, это тоже быстро

- можно было в простых случаях слать простые запросы в базу без перла (типа освобождение лизы - пометить что свободна)

 

 

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

 

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

Надеюсь что для обновления скрипта будет достаточно только копировать свои функции-обёртки к базе в самом низу скрипта.

 

Качните заного, только что обновил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

 

 

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

Тестируйте, пишите под себя запросы, можно и сразу веб интерфейс админки и будет счастье.

 

И чисто теоритически:

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

После этого можно будет переписать на си и навесить рюшек.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Позволю себе вмешаться.

 

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

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

 

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

 

можно написать запросы в базу что бы прилетало в ответе: код опции - содержимое, и динамически это в скрипте упаковывать, а так же перенести часть логики в базу, тогда можно будет всё конфигурить только с базы, не трогая код что бы добавить опцию или что бы кому то отдавать по 82 опции а кому то просто по маку а кому то вообще статику.
Мне кажется, или где-то я это уже видел?.. ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

 

 

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

 

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

 

Заменить кучу конструкций вида:

    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});
    }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

 

Для себя выделил такие типы и флаги в 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 получилось, для которых уникальная обработка.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

 

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

 

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

 

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

Непорядок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Т.к. топикстартер на форум не реагирует, сделана копия исходников

по адресу http://sources.homelink.ru/rozhuk.org.ru/

 

whois rozhuk.org.ru | grep nserver

nslookup rozhuk.org.ru free01.editdns.net >> /etc/hosts; wget ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

большое спасибо, отличная работа. чуть подправил под себя.

кому интересно вот ссылки.

сам сервер 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хочу сказать спасибо за программулину! Очень помогла!

У меня работает с opt82.

 

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

 

Может кто знает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

 

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

dhcpsql.log.txt

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

тут похоже уже сделана какая-то перокидоровка с потерей информации. Сделайте дамп tcpdump'ом, посмотрите хотя бы в какой кодировке приходят такие запросы

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

тут похоже уже сделана какая-то перокидоровка с потерей информации. Сделайте дамп tcpdump'ом, посмотрите хотя бы в какой кодировке приходят такие запросы

Да, это я уже пробовал encode("cp1251",$dhcpreq->getOptionRaw(DHO_HOST_NAME())).. забыл убрать.

Также пробовал koi8-r и utf8. Результат тот же..

 

Как посмотреть кодировку с помощью tcpdump?

 

Смотрю

tcpdump -ni vlan10 -X -s 310 port 67 or port 68

Непонятно..

 

Вот так без encode:

dhcpsql.log.2.txt

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

$ cat dhcpsql.log | iconv -f cp866 -t utf8

[31/May/2011 19:40:04] 810281452 DHCPTYPE = 3;HOST_NAME = жоппа

[31/May/2011 19:40:17] 3329464208 DHCPTYPE = 8;HOST_NAME = Маша-ПК

 

 

Привет от 640Кб памяти

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

$ cat dhcpsql.log | iconv -f cp866 -t utf8

[31/May/2011 19:40:04] 810281452 DHCPTYPE = 3;HOST_NAME = жоппа

[31/May/2011 19:40:17] 3329464208 DHCPTYPE = 8;HOST_NAME = Маша-ПК

 

 

Привет от 640Кб памяти

 

Ооо.. Большое спасибо!

А то что это cp866 как определяется? Только перебором?

Изменено пользователем versen

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ограниченным перебором. на русской винде используются cp866, cp1251 и utf16. Если у кого-нибудь будет немецкая винда, то вы увидете мусор вместо их национальных символов, предполагая что используется cp866

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.