Jump to content
Калькуляторы

DHCP сервер с поддержкой SQL Написан. Нужны добровольцы-тестеры.

И так... Достаточно продолжительное время я работал в провайдинге, с тех пор зародилась идея что "чего-то не хватает в этом мире для счастья" в отношении DHCP и большого числа клиентов. Погуглив понял что такая идея терзает не одного меня, и наверное надо что-то сделать. Был написан патч к ISC DHCP позволяющий работать с БД через RADIUS (даже где-то темка на этом форуме есть), но реализация честно говоря была очень печальна и не нравилась мне самому. Потому было решено продолжить дело и написать нормальный (на сколько это получится) сервер.

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

 

Базовые возможности сервера:

  • Работа с Ethernet сетями, IP протокол версии 4.
  • Поддерживаемые СУБД: PostgreSQL, MySQL.
  • Поддерживаемые ОС: сборка и базовое тестирование проведены в Linux, FreeBSD, Windows XP

 

Обладает достаточно хорошими возможностью конфигурирования и не привязан жёстко к какой-либо структуре БД.

 

Всем кому это интересно предлагаю ознакомиться с подробной документацией, собрать сервер и помочь в тестировании: http://netpatch.ru/db2dhcp.html

 

Огромная просьба: пока статус кода дико тестовый (об этом написано в документации) - стараться не пиарить на популярных ресурсах (типа опеннета, хабры и т.д.) и не пытаться делать порты/пакеты для включения в дистрибутивы. Не хочется слишком активно делиться со всем миром потенциально проблемным (а местами немного не доделанным) кодом. Да и доку надо английскую ещё написать...

Edited by RomanCh

Share this post


Link to post
Share on other sites

Интересует пара вопросов.

 

1. Есть ли возможность выдачи IP-адресов динамически, не добавляю логику хранения лиз в БД? Т.е. хочется следующего: по IP-адресу relay-агента выделять клиентам динамические адреса из конкретного пула, а по option82 и vendor-class-id выдавать различные опции(для ip-телефонов/voip-шлюзов и stb). Я конечно понимаю, что динамические пулы не сложно реализовать средствами БД - создать таблицу выданных адресов, хранить время аренды, когда выдан и т.д., но это потребует делать INSERT/UPDATE'ы в БД, чего делать не хотелось бы.

2. Каким образом предполагается осуществлять дублирование DHCP-серверов при использовании динамических пулов?(есть ли механизм синхронизации биндингов, аналогичного failover-peer в isc dhcpd?) Или же динамические пулы не предполагаются и ставятся два одинаковых сервера с одинаковыми БД и всё выдаётся статически по связкам mac-ip или option82-ip ?

Share this post


Link to post
Share on other sites
1. Есть ли возможность выдачи IP-адресов динамически, не добавляю логику хранения лиз в БД?
Вы над автором издеваетесь что-ли? Если сервер работает с базой, значит в базе и содержится пул.

 

Каким образом предполагается осуществлять дублирование DHCP-серверов при использовании динамических пулов?(есть ли механизм синхронизации биндингов, аналогичного failover-peer в isc dhcpd?) Или же динамические пулы не предполагаются и ставятся два одинаковых сервера с одинаковыми БД и всё выдаётся статически по связкам mac-ip или option82-ip ?
2 независимых друг от другах DHCP сервера + 2 сервера БД c Master-Master репликацией пула и клиентской базы. этот DHCP сервер то тут причем?

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
1. Есть ли возможность выдачи IP-адресов динамически, не добавляю логику хранения лиз в БД? Т.е. хочется следующего: по IP-адресу relay-агента выделять клиентам динамические адреса из конкретного пула,
Вы мне кажется чего-то очень странного хотите: "Есть такой же, только без крыльев?" :)

Не очень понимаю чем вас так пугает включение этой логики в БД. Благо в этом SQL скрипте есть уже работоспособный пример (функция get_id) позволяющий реализовывать динамический пул в БД. Практический опыт показал что он прекрасно работает. Доработать его для db2dhcp совсем не сложно, может даже сделаю сам в ближайшее время.

И ещё - совсем не понимаю как вы представляете себе такую реализацию в сервере (прописывать диапазон в конфигах что-ли? Тогда теряется суть идеи сервера - всё хранить в БД).

 

2. Каким образом предполагается осуществлять дублирование DHCP-серверов при использовании динамических пулов?
Примерно так как нам подсказывает terrible - master <-> master репликация между базами.

 

breusovok, "предыдущее творение" честно говоря было ужасно с точки зрения конфигурабельности и я сам до сих пор удивляюсь когда узнаю что некоторые в нём сумели разобраться и даже выпустить в продакшн. Если разобрались в нём, то в db2dhcp всё покажется совсем простым.

В отношении стабильности - да в общем-то думаю ничего страшного не должно случиться. Сейчас буду код в порядок приводить. Больше всего боюсь гипотетически возможных взаимных блокировок потоков, потому очень хотелось бы что бы кто-нибудь потестировал работу сервера на нескольких прослушиваемых DHCP интерфейсах. У меня пока что такой возможности нет, но по идее ничего там отломаться не должно.

Share this post


Link to post
Share on other sites

RomanCh

Беда в том, что multimaster в postgresql делается жуткими костылями типа pgpool, а mysql не использую по религиозным соображениям, поэтому и спросил есть ли аналог isc-шного механизма синхронизации биндингов. В приниципе, если отказаться от динамических пулов, то можно делать 2 postgres'а в режиме master-slave(в версии 9.0 это делается штатными механизмами). Я правильно понимаю, что в этом случае(статические связки mac-ip или option82-ip) никаких insert'ов и update'ов не требуется и можно спокойно выполнять селекты на slave-сервере?

Share this post


Link to post
Share on other sites
RomanCh

Беда в том, что multimaster в postgresql делается жуткими костылями типа pgpool, а mysql не использую по религиозным соображениям

Эх, так и не допилили нормально репликацию в PgSQL... MySQL сам жутко не люблю.

 

В приниципе, если отказаться от динамических пулов, то можно делать 2 postgres'а в режиме master-slave(в версии 9.0 это делается штатными механизмами). Я правильно понимаю, что в этом случае(статические связки mac-ip или option82-ip) никаких insert'ов и update'ов не требуется и можно спокойно выполнять селекты на slave-сервере?
Да, правильно. Только SELECT, если вы не хотите конечно обновлять в базе информацию о времени выдачи IP адреса клиенту (но мне кажется это совсем ненужным, есть же лог сервера если очень надо).

 

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

Share this post


Link to post
Share on other sites

А нельзя ли реализовать бепкапный коннект к серверу? То есть указываем в конфиге и мастер и слейв, в нормальном режиме запросы шлются на мастер, при его падении все переключается на слейв. Тогда можно будет нормально сделать апдейты/инсерты внутри функций постгреса (тоже юзаем только его) и красиво сделать репликацию.

Share this post


Link to post
Share on other sites
А нельзя ли реализовать бепкапный коннект к серверу?
Будет обязательно. Смотрите раздел "Планируемые доработки".

 

Тогда можно будет нормально сделать апдейты/инсерты внутри функций постгреса (тоже юзаем только его) и красиво сделать репликацию.
Не очень понял как это связано.

Share this post


Link to post
Share on other sites

Не получается использовать процедуру mysql в качестве запроса (что-то вроде CALL get_dhcp_params('3123413123','001e58a829a8','17')), похоже из-за этого http://bugs.mysql.com/bug.php?id=24485

Edited by [-Alt-]

Share this post


Link to post
Share on other sites

Не получается использовать процедуру mysql в качестве запроса (что-то вроде CALL get_dhcp_params('3123413123','001e58a829a8','17')), похоже из-за этого http://bugs.mysql.com/bug.php?id=24485

Я правильно понимаю что у вас процедура пытается вернуть набор значений? Если да, то предлагаю сделать по другому - разнести данные по IP адресам и подсетям по отдельным таблицам и получать их через:

SELECT ... FROM ... WHERE id = get_id(<вот тут ваши аргументы>) -- тут возвращается одно единственное число по которому мы получаем только IP адрес клиента, разумеется поле id должно иметь уникальное значение для каждого адреса, AUTOINCREMENT хорошо подходит для решения.
UNION
SELECT ... FROM ... WHERE ... <перечисление тех же аргугментов но по отдельности в условиях> -- а тут уже обычным WHERE получаем всю остальную необходимую конфигурацию.

Share this post


Link to post
Share on other sites

Да, она пытается вернуть набор значений. В принципе можно решить и без процедур, но с ними оно как-то надежнее, я просто хочу еще некоторые таблица апдейтить в запросе, и реализовать логику выдачи нескольких адресов в одном порту при использовании 82 опции.

 

<br />
<br />Не получается использовать процедуру mysql в качестве запроса (что-то вроде CALL get_dhcp_params('3123413123','001e58a829a8','17')), похоже из-за этого <a href="http://bugs.mysql.com/bug.php?id=24485" target="_blank">http://bugs.mysql.com/bug.php?id=24485</a>
<br />Я правильно понимаю что у вас процедура пытается вернуть набор значений? Если да, то предлагаю сделать по другому - разнести данные по IP адресам и подсетям по отдельным таблицам и получать их через: <br />
SELECT ... FROM ... WHERE id = get_id(<вот тут ваши аргументы>) -- тут возвращается одно единственное число по которому мы получаем только IP адрес клиента, разумеется поле id должно иметь уникальное значение для каждого адреса, AUTOINCREMENT хорошо подходит для решения.<br />
UNION<br />
SELECT ... FROM ... WHERE ... <перечисление тех же аргугментов но по отдельности в условиях> -- а тут уже обычным WHERE получаем всю остальную необходимую конфигурацию.

<br />

<br /><br /><br />

Share this post


Link to post
Share on other sites
-Alt- нашёл ваше письмо в почте, ответил. Давайте попробуем решить проблему, итоговый результат обнародуем.

Share this post


Link to post
Share on other sites

В принципе все сводится к этому http://dev.mysql.com/doc/refman/5.0/en/c-a...le-queries.html, в ответном письме как смог расписал, жаль с СИ у меня не очень, я понимаю что нужно сделать

но не понимаю как :)

 

Share this post


Link to post
Share on other sites

Новая версия доступна: http://netpatch.ru/projects/db2dhcp/db2dhcp-0.1.a.1.tar.bz2

Изменения:

  • Важно: добавлена директива User для смены UID при запуске.
  • Сделан обработчик сигналов (про это ещё надо доку на сайте дописать): корректное завершение всех потоков по получению SIGTERM/SIGINT, переоткрытие лог-файла по SIGUSR1.
  • Мелкий рефакторинг кода.

-Alt - получил письмо, вроде ничего сложного. Немного позже займусь.

Share this post


Link to post
Share on other sites

-Alt- ну собственно, вот: http://netpatch.ru/projects/db2dhcp/db2dhcp-0.1.a.2.tar.bz2

 

Гоняю сейчас под профилировщиком (valgrind) с двумя прослушиваемыми интефрейсами натравив на сервер синтетически несколько клиентов и отключив кэширование - получается где-то 2-4 DHCP запроса в секунду. Проблем не отмечено, в самоблокировки не впадает, в памяти "не туда" не ходит. Правда вроде бы очень медленно где-то подтекает память. Изучу позже этот момент.

Share this post


Link to post
Share on other sites

Добрый день!

Чудесный проект, весьма благодарен автору, по началу хотел для этого извращаться с FreeRADIUS.

 

Хочется сделать с помощью этого аналог ISG на Linux с инициацией/терминацией сессии по DHCPACK/RELEASE. Собственно, фичареквест. Можно ли сделать выполнения shell-команд на данных событиях?

Share this post


Link to post
Share on other sites
Можно ли сделать выполнения shell-команд на данных событиях?

Это же можно делать из базы данных. В случае pgsql надо поставить pgperl и из него уже вызывать скрипты.

Share this post


Link to post
Share on other sites
Можно ли сделать выполнения shell-команд на данных событиях?

Это же можно делать из базы данных. В случае pgsql надо поставить pgperl и из него уже вызывать скрипты.

Не в случае, когда база на другом сервере (центральном радиусе, допустим).

Share this post


Link to post
Share on other sites

Хочется сделать с помощью этого аналог ISG на Linux с инициацией/терминацией сессии по DHCPACK/RELEASE. Собственно, фичареквест. Можно ли сделать выполнения shell-команд на данных событиях?

Т.е. что бы при отправке/получении этих запросов сервер грубо говоря вызывал system(<comman>, ...<some-args>...)? В общем-то можно на любой запрос/ответ повесить без особых проблем. В аргументы команды полагаю нужно уметь передавать переменные из запросов (mac/ip клиента например)?

Share this post


Link to post
Share on other sites

Спасибо большое за замечательный продукт.

 

Установил версию 0.1.a. Биллинг NetUP. В динамике осталась одна подсеть, поэтому, чтобы не плодить базы, сделал такой запрос к БД нетапа:

QueryDiscover = SELECT 1, 5, '255.255.128.0' \
                UNION \
                SELECT 3, 5, '10.10.127.254' \
                UNION \
                SELECT 6, 5, '10.10.12.2' \
                UNION \
                SELECT 15, 4, 'one.net' \
                UNION \
                SELECT 51, 5, 72000 \
                UNION \
                SELECT 1009, 5, inet_ntoa(ip+4294967296) \
                FROM ip_groups \
                WHERE mac=(CONCAT_WS(":", SUBSTR('$CLI-ETHER-ADDR$',1,2), \
                SUBSTR('$CLI-ETHER-ADDR$',3,2),SUBSTR('$CLI-ETHER-ADDR$',5,2), \
                SUBSTR('$CLI-ETHER-ADDR$',7,2),SUBSTR('$CLI-ETHER-ADDR$',9,2), \
                SUBSTR('$CLI-ETHER-ADDR$',11,2))) \
                AND is_deleted=0 \
                AND inet_ntoa(ip+4294967296) NOT LIKE '10.20.%'

 

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

 

Есть один вопрос. Можно как-нибудь отдать клиенту два DNS сервера? Пробовал указать два DNS в запросе, таким образом:

                SELECT 6, 5, '10.10.12.2' \
                UNION \
                SELECT 6, 5, '10.10.12.3' \
                UNION \

отдает только последний.

Edited by Voronok

Share this post


Link to post
Share on other sites
Есть один вопрос. Можно как-нибудь отдать клиенту два DNS сервера? Пробовал указать два DNS в запросе, таким образом:

                SELECT 6, 5, '10.10.12.2' \
                UNION \
                SELECT 6, 5, '10.10.12.3' \
                UNION \

отдает только последний.

На самом деле в документации про типы db2dhcp про это написано ;)

 

Всё что имеет имеет тип IPADDRS (значение 5) может содержать список IP адресов в принципе произвольной длины. IP адреса указываются через запятую. Т.е. нужно сделать: : SELECT 6, 5, '10.10.12.2,10.10.12.3'

 

UPD: и поставьте уж последнюю версию. Там полезные доработки есть, да и негоже под root'ом гонять софт если он может обойтись без этого.

Edited by RomanCh

Share this post


Link to post
Share on other sites
На самом деле в документации про типы db2dhcp про это написано ;)
Простите мою невнимательность (

Спасибо.

Share this post


Link to post
Share on other sites

Freebsd 8.2

Интерфейс lagg0 поверх него vlan500

Сегфолтится, если указать оба интерфейса, если только один то пашет.

 

linux 2.6.37

Интерфейс eth0 поверх него vlan500

Указываю оба все замечательно работает.

 

Share this post


Link to post
Share on other sites

Фичареквест: прикрутить возможность работы с Oracle

Наш дебиллинг крутится именно под Oracle и вопрос

с инициацией/терминацией сессии по DHCPACK/RELEASE
в нашем случае решится элементарно

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this