Jump to content

DHCP + SQL БД. Сабж при помощи патча к dhcpd.

Пробовал. DHCP начинает слушать на lo0 но пакеты так и не приходят. Причем похоже что они не проходят сквозь BPF.

Хм... Но ведь в исходном варианте от ISC (где баги не пофиксены) - работает. Надо ещё покопать. У меня пока к сожалению времени нету. На выходных попробую глянуть если не разберётесь раньше.

Share this post


Link to post
Share on other sites

Возможно авторам будет интересен вот этот тред: https://lists.freeradius.org/pipermail/free...e/msg00144.html

и вот это письмо https://lists.freeradius.org/pipermail/free...e/msg00172.html :)

Share this post


Link to post
Share on other sites

На данный момент меня устраивает работа и через USE_SOCKETS.

Т.к. этот DHCP предназначен для работы с коммутаторми (dhcp-snooping + option 82) то возможность слушать на нескольких интерфейсах для меня не принципиальна. Главное чтоб слушал на том интерфейсе который мне нужен.

Было бы неплохо добавить в DHCP возможность "прасить" option 82 (в данный момент это делается питоновским скриптом в радиусе)

На пример каталист выдает opt 82 в таком виде:

0x0106000407d00016020c010a61676772656761746531

Состоит оно из двух частей

Circuit ID

0106000407d00016 - 01060004 где 1 байт - идентифиактор(01), 1 байт - длина+2(06). 1 байт - непомню что (00). 1 байт - длинна данных (04), 4 байта - данные о влане и порте

07d00016 - 2 байта влан 07d0=2000 влан, 1 байт номер модуля (00), 1 байт номер порта (16=22) т.к счет с нуля то надо добавлять 1.

В итоге получается 2000 влан и порт 0/23

 

Agent Remote ID

020c010a61676772656761746531

020c010a - первые 4 байта по аналогии с circuit id (02 - идентификатор, 0с - длинна+2, 01 -..., 0a - длинна данных)

в данных указывается hostname коммутатора (можно настроить на выдачу мак адреса)

61676772656761746531 - aggregate1

Самый простой вариант воспользоваться встроенными в DHCPD функциями binary-to-ascii, substring, prefix и тд и добавить возможность результаты работы этих функций передавать в радиус какими либо атрибутами.

Share this post


Link to post
Share on other sites

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

Но в принципе идея о том что её нужно распарсить имеет полное право на существование и оставлялась на потом. Стукните в жабера - обсудим подробности. JID как мой ник на форуме + @jabber.ru

Share this post


Link to post
Share on other sites

Было бы неплохо добавить в DHCP возможность "прасить" option 82 (в данный момент это делается питоновским скриптом в радиусе)

Самый простой вариант воспользоваться встроенными в DHCPD функциями binary-to-ascii, substring, prefix и тд и добавить возможность результаты работы этих функций передавать в радиус какими либо атрибутами.

Ну, это просто более-менее стандартный формат option82, никто не запрещает его модифицировать. У той же cisco вместо mac'а в remote id отлично настраивается выдача произвольной строки, и формат circuit id легко меняется..

Share this post


Link to post
Share on other sites

Привет, собрал стенд. Сервер FreeBSD 7.2 на нем isc-dhcpd и база pgsql, радиус на другом сервере, клиент FreeBSD 6.2. Начал стресс тестирование утилитой dhcperf. Кеширование убрал, все адреса динамические, лимиты на общее число запросов и запросов от одного клиента повысил до 1000. Запросы к базе упростил, т.е. никаких проверок и т.п., со стороны связки radius+pgsql проблем нет. Начиная где-то с 12 запросов в секунду начинают проскакивать сообщения вида

 

WARN: Can't find request info for client 00:00:00:00:00:5f from interface 172.22.255.12 (218044076)

 

при этом результаты dhcperf

 

test# dhcperf --server 172.22.255.10 --discover --test-duration 15 --test-load 12
Wanted 3145728 bytes in output buffer; got 229376.
Wanted 3145728 bytes in input buffer; got 229376.
Beginning DHCPDISCOVER load test.
128/174 successes: 73.6% succeeded.
test#

 

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

 

Share this post


Link to post
Share on other sites

Привет, собрал стенд. Сервер FreeBSD 7.2 на нем isc-dhcpd и база pgsql, радиус на другом сервере, клиент FreeBSD 6.2. Начал стресс тестирование утилитой dhcperf. Кеширование убрал, все адреса динамические, лимиты на общее число запросов и запросов от одного клиента повысил до 1000. Запросы к базе упростил, т.е. никаких проверок и т.п., со стороны связки radius+pgsql проблем нет. Начиная где-то с 12 запросов в секунду начинают проскакивать сообщения вида

WARN: Can't find request info for client 00:00:00:00:00:5f from interface 172.22.255.12 (218044076)

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

 

Вообще в последнее время задумываюсь о том что надо написать с нуля, без костылей и заплаток адекватный DHCP сервер изначально ориентированный на SQL.

 

ЗЫ Обновил патч на сайте. http://www.netpatch.ru/projects/dhcp2radiu...2.patch.tar.bz2 - убрал "лишнюю" функцию can_unicast_without_arp (out) в условии и устранил потенциальную уязвимость при обработке DHCP запросов.

Share this post


Link to post
Share on other sites

skor78

а не поделишься скриптом питона для радиуса? очень охота посмотреть как оно реализовано :)

В данный момент пробую родной ДХЦП из фрирадиуса. Скрипт на перл переписал. От питона отказался по той же причине что и этот человек

sub parse_opt82 {
        if ( $RAD_REQUEST{'NAS-Identifier'} = "catalyst" ) {
                my @relayid = unpack('x10 a4 a2 a2 x8 (a2)*',$RAD_REQUEST{'DHCP-Relay-Agent-Information'});
                for (0 .. (@relayid-1)) {
                        $relayid[$_] =  oct("0x".$relayid[$_]);
                }
                for (3 .. (@relayid-1)) {
                        $relayid[$_] = chr($relayid[$_]);
                }
                $RAD_REQUEST{'DHCP-Relay-Agent-Information'} = $relayid[0]." ".$relayid[1]."/".($relayid[2]+1)." ".join('',@relayid[3 .. (@relayid-1)]);
#               $RAD_REQUEST{'DHCP-Agent-Circuit-Id'} = $relayid[0]." ".$relayid[1]."/".($relayid[2]+1);
#               $RAD_REQUEST{'DHCP-Agent-Remote-Id'} = join('',@relayid[3 .. (@relayid-1)]);
        }
}

Изначальный атрибут DHCP-Relay-Agent-Information заменятся на текст, подобного вида 2007 0/21 aggregate1 (влан, порт, имя агента).

И дальше уже адрес выдается на основе этого атрибута.

Edited by skor78

Share this post


Link to post
Share on other sites

Привет, собрал стенд. Сервер FreeBSD 7.2 на нем isc-dhcpd и база pgsql, радиус на другом сервере, клиент FreeBSD 6.2. Начал стресс тестирование утилитой dhcperf. Кеширование убрал, все адреса динамические, лимиты на общее число запросов и запросов от одного клиента повысил до 1000. Запросы к базе упростил, т.е. никаких проверок и т.п., со стороны связки radius+pgsql проблем нет. Начиная где-то с 12 запросов в секунду начинают проскакивать сообщения вида

WARN: Can't find request info for client 00:00:00:00:00:5f from interface 172.22.255.12 (218044076)

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

 

Вообще в последнее время задумываюсь о том что надо написать с нуля, без костылей и заплаток адекватный DHCP сервер изначально ориентированный на SQL.

 

ЗЫ Обновил патч на сайте. http://www.netpatch.ru/projects/dhcp2radiu...2.patch.tar.bz2 - убрал "лишнюю" функцию can_unicast_without_arp (out) в условии и устранил потенциальную уязвимость при обработке DHCP запросов.

Роман, прошу прощения, что сразу не ответил на свое же сообщение. Возможно эта ошибка возникает и в случае долгого ответа sql, в моем же случае проблема была в том, что я по незнанию оставил закоментаренным radius-cache-ttl, как в примере в статье, наивно полагая, что это где-то описано как дефолт, в итоге получил время ttl 0. Конечно при этом функция delete_old_xid удаляля все что было в кеше. Т.ч. моя проблема решена, dhcperf показал 32 запроса в секунду.

Share this post


Link to post
Share on other sites

оставил закоментаренным radius-cache-ttl, как в примере в статье, наивно полагая, что это где-то описано как дефолт, в итоге получил время ttl 0.
Честно говоря вы правильно полагали. Вкрался баг. Дефолтное значение должно быть сутки. В ближайшее время выложу фикс.

 

Yuka - маловероятно. Там есть специфика в VSA - длина поля идентификатора атрибута в VSA DHCP от FreeRADIUS составляет 2 байта, тогда как стандартно - 1 байт.

Share this post


Link to post
Share on other sites

Ребята объясните,(несильно разбирался) это DHCP+radius а радиус к SQL прикрутили или?
Прикрутили, но честно - как-то стрёмно. Хоть я сам и прикручивал, но мне самому не нравится.
просто задача.. есть биллинг умеющий выдавать динамически ипы, нужен сервер DHCP с опцией 82 который может общатся с любым Radius(к нетапу прикрутить можно) сервером... Эта примочка поможет решить задачу?
На FreeRADIUS можно. На другой конкретно этот вариант не пойдёт. А если сервер напрямую лезть в MySQL базу - любителей нетапа это выручило бы?

Share this post


Link to post
Share on other sites

skor78

а не поделишься скриптом питона для радиуса? очень охота посмотреть как оно реализовано :)

В данный момент пробую родной ДХЦП из фрирадиуса. Скрипт на перл переписал. От питона отказался по той же причине что и этот человек

sub parse_opt82 {
        if ( $RAD_REQUEST{'NAS-Identifier'} = "catalyst" ) {
                my @relayid = unpack('x10 a4 a2 a2 x8 (a2)*',$RAD_REQUEST{'DHCP-Relay-Agent-Information'});
                for (0 .. (@relayid-1)) {
                        $relayid[$_] =  oct("0x".$relayid[$_]);
                }
                for (3 .. (@relayid-1)) {
                        $relayid[$_] = chr($relayid[$_]);
                }
                $RAD_REQUEST{'DHCP-Relay-Agent-Information'} = $relayid[0]." ".$relayid[1]."/".($relayid[2]+1)." ".join('',@relayid[3 .. (@relayid-1)]);
#               $RAD_REQUEST{'DHCP-Agent-Circuit-Id'} = $relayid[0]." ".$relayid[1]."/".($relayid[2]+1);
#               $RAD_REQUEST{'DHCP-Agent-Remote-Id'} = join('',@relayid[3 .. (@relayid-1)]);
        }
}

Изначальный атрибут DHCP-Relay-Agent-Information заменятся на текст, подобного вида 2007 0/21 aggregate1 (влан, порт, имя агента).

И дальше уже адрес выдается на основе этого атрибута.

Можно поподробней как ты настроил DHCP в freeradiuse с 82 опцией... Очень интересно!!!

Share this post


Link to post
Share on other sites

Т.ч. моя проблема решена, dhcperf показал 32 запроса в секунду.

При каком объёме базы ? 1 запись ? ИМХО всё это умрёт в реальном применении. Некоторые клиенты имеют свойство тупо долбиться по DHCP не понимая что им отвечают, сам видел в сниффере. Если мы тратим на соединение с SQL через промежуточные звенья и выборку пол-секунды, или даже 0.1 секунды, то DDOS с таймаутами при большой сети всё равно обеспечен.

Edited by Saper

Share this post


Link to post
Share on other sites

Вопрос такой есть готовый Dhcp(MysqlPgsql)

кто сколько готов заплатить ??? (смешные цифры не называть ... написав это решение я убил кучу времени поэтому хочу за это денег вроде бы все как должно было бы быть )

решение без костылей готовый сервер тестился на боевой сети 8000 абонентов.

30 - 50 запросов\с предел был 170/c

и не надо бесплатно канючить ... бесплатно юзать можно только грабли которых кучя =) а решать вам.

Edited by ~nix~

Share this post


Link to post
Share on other sites

DHCP - очень простой протокол и написать сервер под определенного провайдера (а не generic на все случаи жизни вроде ISC'шного) - это 1 человек на 2-3 месяца до рабочей бета-версии. Самая сложная часть - обучить сервер понимать нюансы реализации в разном оборудовании (но, учитывая заточку под конкретную ситуацию, большой проблемой не является), тут одними RFC'хами отделаться нельзя - надо стенд под каждую железку.

 

У нас свой сервер (python+mysql) - центральная БД, один веб для управления, несколько серверов, несколько технологий. На этом DHCP >3000 активных пользователей, >200 ед. оборудования, время аренды - час, рабочая нагрузка минимальна.

 

Сначала рассматривался DHCP ISC, но "перегенерить конфиг и перезапустить сервер" - это, мягко говоря, defective by design, а его API было недостаточно для полного управления.

 

Share this post


Link to post
Share on other sites

Мы тоже доработали скрипт dhcp2radius, вместо pgsql стоит perl+mysql. Так как намного гибче. Авторизует как по свитч+порт, так и просто по мак. Все легко настраивается, работает с netup. Механизм такой:

-при запросе ищем абонента по порту и свитчу либо по маку.

Абонента нет - абоненту выдаем временные настройки с fake-dns, который на любой запрос выдает ip сервера авторизации компа. Там абонент вводит Логин/пароль- и его мак или свитч/порт автоматом к его учетке привязываются. После перезагрузки компа ему уже выдаются его настройки.

Share this post


Link to post
Share on other sites

Вопрос такой есть готовый Dhcp(MysqlPgsql)

кто сколько готов заплатить ??? (смешные цифры не называть ... написав это решение я убил кучу времени поэтому хочу за это денег вроде бы все как должно было бы быть )

решение без костылей готовый сервер тестился на боевой сети 8000 абонентов.

30 - 50 запросов\с предел был 170/c

и не надо бесплатно канючить ... бесплатно юзать можно только грабли которых кучя =) а решать вам.

Сколько хотите денег ? Какое оборудование должно стоять в сети ? Как мы его привяжем к нашей базе абонентов которая ведётся пока в MS Access ? Поможете ?

Edited by Saper

Share this post


Link to post
Share on other sites

Вопрос такой есть готовый Dhcp(MysqlPgsql)

кто сколько готов заплатить ??? (смешные цифры не называть ... написав это решение я убил кучу времени поэтому хочу за это денег вроде бы все как должно было бы быть )

решение без костылей готовый сервер тестился на боевой сети 8000 абонентов.

30 - 50 запросов\с предел был 170/c

и не надо бесплатно канючить ... бесплатно юзать можно только грабли которых кучя =) а решать вам.

Сколько хотите денег ? Какое оборудование должно стоять в сети ? Как мы его привяжем к нашей базе абонентов которая ведётся пока в MS Access ? Поможете ?

Решение я оценил в 150 $ полностью рабочее естественно с зашыфрованым исходным кодом ...

Во первых помочь в чём именно ? связать сервер с MS Access ??? за дополнительные деньги можно и в космос полететь.

а что у вас щас стоит ? MS Access и все ????

Share this post


Link to post
Share on other sites

2~nix~

Если не трудно расскажите подробнее о своей разработке.

Можно ли использовать opt82?

Можно ли использовать произвольные option? как в isc-dhcpd?

Структура БД фиксированная или можно гибко адаптировать к своей?

 

Share this post


Link to post
Share on other sites

Join the conversation

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

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.