Ivan_83 Опубликовано 10 марта, 2011 (изменено) · Жалоба Документация: 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 то ответы будут уходить только с него, в случае нескольких адаптеров/алиасов остальные задействованны не будут. В таких случаях сервер будет получать, обрабатывать запрос но ответ уходить не будет. Изменено 20 мая, 2015 пользователем Ivan_83 Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Lynx10 Опубликовано 11 марта, 2011 · Жалоба спасибо ! попробуем - что то похожее по функционалу на перле сами реализируем! Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 11 марта, 2011 · Жалоба Обновил скрипт. Немного логики, тем кто захочет писать запросы. 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 можно продублировать здесь и считать их главнее Время обновляется при получении/продлении аренды, адрес в зависимости от настроек. Это минимальная примерная логика обычных дхцп серверов. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
aivanzipper Опубликовано 15 марта, 2011 · Жалоба Почему скл-запросы убрали? Можно было бы вместе скрипт дальше разрабатывать. А сейчас это равносильно написанию по-новому... Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 15 марта, 2011 · Жалоба По новому - это вы преувеличиваете. Здесь остаётся только дописать запросы к базе и подправить под себя их распихивание по параметрам ответа, вся обвязка есть и работает. Запросы были под самописный биллинг, более того там есть некоторая специфика выдачи адресов, потому эти запросы общественности совершенно бесполезны. Остался один запрос: для маршрутов ибо оно универсально. Притом, те у кого используюется prefixlen вместо subnetmask получат небольшой прирост, а в коде достаточно заменить название функции. Если посмотрите предыдущий пост, то там описаны примерные таблицы под "традиционную" работу дхцп сервера. Позже я напишу запросы/базу по схеме из моего предыдущего поста. Так же попробую сделать кеш запросов и может быть работу без релей агентов - тогда будет полноценный дхцп сервер. Сейчас ведётся работа на гостевыми подсетями, когда заработает - я опишу логику здесь. Вечером обновлю скрипт: вся логика работы с базой окончательно вынесена в отдельные функции, все параметры теперь передаются по ссылкам. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
aivanzipper Опубликовано 15 марта, 2011 (изменено) · Жалоба Ivan_83, если Вы его "допилите" вам будут безмерно благодарны сотни администраторов сетей, так как нормального решения DHCP+MySQL на сег. день не существует. Может, нужна помощь? Готов взять на тестирование. Изменено 15 марта, 2011 пользователем aivanzipper Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
dwemer Опубликовано 16 марта, 2011 (изменено) · Жалоба Спасибо, работает. Как раз заморачиваюсь переходом на IPoE. Сейчас фрирадиус использую в качестве дхцп, но ваш скрипт как то ближе к телу, буду его под себя пилить. Работа без релей агентов вряд ли понадобится. в функции db_data_to_reply опечатка if (index($_[1], DHO_DOMAIN_NAME) != -1) { $_[1]->addOptionValue(DHO_DOMAIN_NAME, $_[0]->{domain}); } $_[2]->addOptionValue Если вдруг кому неочевидно ) Изменено 16 марта, 2011 пользователем dwemer Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 16 марта, 2011 · Жалоба Фрирадиус я тоже пробовал. Впечатления от него не очень, не для этого он: - анлэнг на котором почти ничего нельзя сделать - иногда падал в корку - менее гибко при использовании перл орбработчика, чем сразу на перле - под фряху тоже не умел биндится на интерфейс: те работал как мой скрипт - на обычном юдп сокете. Были и плюсы: - быстро отфутболивал левые запросы - по отдельным параметрам запроса можно было фильтровать в анлэнге до перла, это тоже быстро - можно было в простых случаях слать простые запросы в базу без перла (типа освобождение лизы - пометить что свободна) $_[2]->addOptionValue Если вдруг кому неочевидно )Заметил по ругани в выводе :) db_data_to_reply - сейчас с зачатками гостевых подсетей, а вообще видимо уже менятся её вызов не будет. Надеюсь что для обновления скрипта будет достаточно только копировать свои функции-обёртки к базе в самом низу скрипта. Качните заного, только что обновил. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 16 марта, 2011 · Жалоба Ivan_83, если Вы его "допилите" вам будут безмерно благодарны сотни администраторов сетей, так как нормального решения DHCP+MySQL на сег. день не существует.dhcpsql есть давно, и соседний топик про тоже самое только с нуля.А нет потому что у всех потребности разные, и упихать в бинарник такую гибкость чтобы всем стало хорошо - сложно. Может, нужна помощь? Готов взять на тестирование.Если только тыкать меня где я в перле не прав или можно было лучше/оптимальнее.Тестируйте, пишите под себя запросы, можно и сразу веб интерфейс админки и будет счастье. И чисто теоритически: можно написать запросы в базу что бы прилетало в ответе: код опции - содержимое, и динамически это в скрипте упаковывать, а так же перенести часть логики в базу, тогда можно будет всё конфигурить только с базы, не трогая код что бы добавить опцию или что бы кому то отдавать по 82 опции а кому то просто по маку а кому то вообще статику. После этого можно будет переписать на си и навесить рюшек. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
RomanCh Опубликовано 16 марта, 2011 · Жалоба Позволю себе вмешаться. 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 опции а кому то просто по маку а кому то вообще статику.Мне кажется, или где-то я это уже видел?.. ;) Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 16 марта, 2011 · Жалоба Не лукавьте. Вы сами пробовали 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}); } } Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
RomanCh Опубликовано 16 марта, 2011 · Жалоба Идея выбирать с базы номера опций, вместо названий пришла пока писал и дозрела до момента написания этого сообщения. Может и так. Просто "в соседнем топике" обсуждается сервер который именно так и делает (+ выборка типа данных) ;) Думаю вы уже заметили, коли достаточно бдительно смотрели в код. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 17 марта, 2011 · Жалоба Может и так. Просто "в соседнем топике" обсуждается сервер который именно так и делает (+ выборка типа данных) ;) Думаю вы уже заметили, коли достаточно бдительно смотрели в код.Смотрел на то что знаю: сеть и кеш :) Для себя выделил такие типы и флаги в 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 получилось, для которых уникальная обработка. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ilya Evseev Опубликовано 24 апреля, 2011 · Жалоба Срок регистрации домена rozhuk.org.ru закончился Услуга по регистрации доменного имени rozhuk.org.ru временно не предоставляется. Продлить домен Если администратор домена не продлит регистрацию, домен освободится. Непорядок. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ilya Evseev Опубликовано 28 апреля, 2011 · Жалоба Т.к. топикстартер на форум не реагирует, сделана копия исходников по адресу http://sources.homelink.ru/rozhuk.org.ru/ whois rozhuk.org.ru | grep nserver nslookup rozhuk.org.ru free01.editdns.net >> /etc/hosts; wget ... Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
maxxch Опубликовано 12 мая, 2011 (изменено) · Жалоба большое спасибо, отличная работа. чуть подправил под себя. кому интересно вот ссылки. сам сервер 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 клиентах. если кто сможет красиво и удобно доработать буду только рад. Изменено 13 мая, 2011 пользователем maxxch Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 20 мая, 2011 · Жалоба Добавил функционал чтобы опции хранить в базе по номерам, но пока до конца не оттестил, возможно к концу следующей недели выложу. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
versen Опубликовано 31 мая, 2011 · Жалоба Хочу сказать спасибо за программулину! Очень помогла! У меня работает с opt82. Только ни как не могу заставить в логи читабельно писать getOptionRaw(DHO_HOST_NAME()) (или getOptionValue(DHO_HOST_NAME())) русские названия. Может кто знает? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
s.lobanov Опубликовано 31 мая, 2011 · Жалоба кусок логов с русскими буквами выложите в виде файла Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
versen Опубликовано 31 мая, 2011 · Жалоба кусок логов с русскими буквами выложите в виде файла tail -n 1000 /var/log/dhcpsql.log | grep -a HOST > ~versen/WORK/dhcpsql.log.txt dhcpsql.log.txt Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
s.lobanov Опубликовано 31 мая, 2011 · Жалоба тут похоже уже сделана какая-то перокидоровка с потерей информации. Сделайте дамп tcpdump'ом, посмотрите хотя бы в какой кодировке приходят такие запросы Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
versen Опубликовано 31 мая, 2011 · Жалоба тут похоже уже сделана какая-то перокидоровка с потерей информации. Сделайте дамп 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 Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
s.lobanov Опубликовано 31 мая, 2011 · Жалоба $ 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Кб памяти Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
versen Опубликовано 1 июня, 2011 (изменено) · Жалоба $ 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 как определяется? Только перебором? Изменено 1 июня, 2011 пользователем versen Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
s.lobanov Опубликовано 1 июня, 2011 · Жалоба ограниченным перебором. на русской винде используются cp866, cp1251 и utf16. Если у кого-нибудь будет немецкая винда, то вы увидете мусор вместо их национальных символов, предполагая что используется cp866 Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...