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

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

Для тех кто не силен в перле, нашел реализацию на php

Интересная штука. Но автор писал это как просто эксперемент.

Как я понял он может работать без релея?

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


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

Интересная штука. Но автор писал это как просто эксперемент.

Как я понял он может работать без релея?

Как я понял, перловый, Иван писал, тоже не для того чтобы в продакшн ставить ;) Но получилось же :)

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


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

Но автор писал это как просто эксперемент.

Требовался дхцп сервер с опцией 82 и работой с mysql, как первый этап перехода на IPoE.

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

Оно у нас в продакшене больше, чем существует этот топик. И писалось для этого.

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

 

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

Ещё была мысль как оптимизировать функции конвертации длинны префикса в маску и обратно.

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


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

Требовался дхцп сервер с опцией 82 и работой с mysql

Если бы были вменяемые сервера, позволяющие подключать внешние скрипты для "разбора полетов", то наверное, вы не стали изобретать велосипед :)

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


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

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

У мну гостевой адрес генерится на основе коммутатор+порт.

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

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


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

Даже если взять 10/8, то как в 3 байта всё упихать?

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


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

У мну гостевой адрес генерится на основе коммутатор+порт.

Даже если взять 10/8, то как в 3 байта всё упихать?

Ну наверное если один порт одна квартира, то и по /28 дать реально(А может pppoetest дает даже по /32 - один провод, один ip, а остальное проблемы пользователя). Тогда в диапазон 10/8 будет несколько десятков тысяч свичей и миллион портов... А еще для гостей можно дать одни и те же адреса в разных районах...

Мы даем пул на интерфейс L3. Которых, благодаря ip unnumbered по штуке на десяток тысяч абонентов.

 

Несколько сообщений выше написал алгоритм для пула - он уже тестово работает:

1)Сначала проверить на зарегистрированный ли аб. Если да, выдать из базы.

2)Потом, выдавали ли мы какой ни будь адрес для MAC, VLAN, port, switch. Если да, выдать из базы и обновить время лизы.

3)Если нет, выдать наиболее древний для данного VLAN, port, switch и пометить его временем(Пометив в базе гостевых ip мак).

 

Пример запросов(Из кода удалил свою логику - если опечатался, простите)

sub db_get_requested_data {
       #my $dbh = $_[0];
       #my $dhcpreq = $_[1];
       #my $dhcpresp = $_[2];

       my ($sth, $dhcpreqparams,$result);
       my ($client_mac, $requested_ip);
       my ($dhcp_opt82_CID, $dhcp_opt82_RID,$agent_vlan,$agent_port);
       my $good_find=0;


       $dhcpreqparams = $_[1]->getOptionValue(DHO_DHCP_PARAMETER_REQUEST_LIST());
       $client_mac = FormatMAC(substr($_[1]->chaddr(), 0, (2 * $_[1]->hlen())));

       if (GetCIDandRID($_[1], $dhcp_opt82_CID, $dhcp_opt82_RID,$agent_vlan,$agent_port)) {
       # try find ip by opt82 info, then give some free addr
           $sth = $_[0]->prepare("SELECT `IP` FROM `USERS` WHERE `MAC`='$client_mac' AND `VLAN`='$agent_vlan' AND `PORT`='$agent_port'");
           if ($sth->execute() && $sth->rows()>0) { #find valid user
               $good_find=1;
               $sth->finish();
               $sth = $_[0]->prepare("UPDATE `USERS` SET `LEASE_TIME`=NOW() WHERE `MAC`='$client_mac' AND `VLAN`='$agent_vlan' AND `PORT`='$agent_port'");
               $sth->execute();
               $sth->finish();
           }else{
               $sth = $_[0]->prepare("SELECT `IP` FROM `UNAUTH_IP` WHERE `RID`='$dhcp_opt82_RID' AND `MAC`='$client_mac' AND `VLAN`='$agent_vlan' AND `PORT`='$agent_port'");
               if ($sth->execute() && $sth->rows()>0) { #find before used ip, for this guest user
                   $result = $sth->fetchrow_hashref();
                   $_[2]->yiaddr($result->{IP});
                   $good_find=1;
                   $sth->finish();

                   $sth = $_[0]->prepare("UPDATE `UNAUTH_IP` SET `LEASE_TIME`=NOW() WHERE `IP`='".$_[2]->yiaddr()."'");
                   $sth->execute();
                   $sth->finish();
               }else{
                   $sth = $_[0]->prepare("SELECT `IP` FROM `UNAUTH_IP` WHERE `RID`='$dhcp_opt82_RID' AND LEASE_TIME<DATE_SUB(NOW(),INTERVAL $dhcp_lease_time*2 SECOND) ORDER BY LEASE_TIME LIMIT 1");
                   if ($sth->execute() && $sth->rows()>0) { #find long time non used ip for this RID for non auth user
                       $result = $sth->fetchrow_hashref();
                       $_[2]->yiaddr($result->{IP});
                       $good_find=1;
                       $sth->finish();

                       $sth = $_[0]->prepare("UPDATE `UNAUTH_IP` SET `LEASE_TIME`=NOW(),`MAC`='$client_mac',`CID`='$dhcp_opt82_CID', `VLAN`='$agent_vlan', `PORT`='$agent_port' WHERE `IP`='".$_[2]->yiaddr()."'");
                       $sth->execute();
                       $sth->finish();
                   }
                   else{
                       logger("Don't find free ip address for RID='$dhcp_opt82_RID'");
                   }
               }
           }


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

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


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

Тогда в диапазон 10/8 будет несколько десятков тысяч свичей и миллион портов... А еще для гостей можно дать одни и те же адреса в разных районах...

В ПГТ на 60k рож? Было бы неплохо =)

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


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

В ПГТ на 60k рож? Было бы неплохо =)

 

Что такое ПГТ ? и вообще о чем сообщение?

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


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

Поселок Городского Типа

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


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

Ну наверное если один порт одна квартира, то и по /28 дать реально(А может pppoetest дает даже по /32 - один провод, один ip, а остальное проблемы пользователя). Тогда в диапазон 10/8 будет несколько десятков тысяч свичей и миллион портов... А еще для гостей можно дать одни и те же адреса в разных районах...

Мы даем пул на интерфейс L3. Которых, благодаря ip unnumbered по штуке на десяток тысяч абонентов.

 

Несколько сообщений выше написал алгоритм для пула - он уже тестово работает:

1)Сначала проверить на зарегистрированный ли аб. Если да, выдать из базы.

2)Потом, выдавали ли мы какой ни будь адрес для MAC, VLAN, port, switch. Если да, выдать из базы и обновить время лизы.

3)Если нет, выдать наиболее древний для данного VLAN, port, switch и пометить его временем(Пометив в базе гостевых ip мак).

 

Пример запросов(Из кода удалил свою логику - если опечатался, простите)

#

 

За информацию спасибо.

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

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


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

Столкнулся с проблемой:

 

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

 

На клиент смотрит один интерфейс, он является шлюзом для клиента. Там же и стоит релей-агент. Возможно, проблема из-за этого. Как думаете, может надо вынести релей-агент на отдельный интерфейс (влан) без ip-адреса и объеденить интерфейсы бриджом? Поможет-ли это избавиться от дублирования запросов?

 

Пока решил таким образом на сервере:

 

case DHCPREQUEST { #-> DHCPACK/DHCPNAK
 if ($dhcpreq->ciaddr() ne '0.0.0.0' && $dhcpreq->giaddr() ne '0.0.0.0'){}
 else {
   db_log_detailed($dbh, $dhcpreq, 'DHCPREQUEST');
   handle_request($dbh, $fromaddr, $dhcpreq);
 }
}

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

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


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

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

Не должен вообще-то..

 

На клиент смотрит один интерфейс, он является шлюзом для клиента. Там же и стоит релей-агент. Возможно, проблема из-за этого. Как думаете, может надо вынести релей-агент на отдельный интерфейс (влан) без ip-адреса и объеденить интерфейсы бриджом? Поможет-ли это избавиться от дублирования запросов?

Лучше с рилеем разобраться. У меня такого не наблюдается, рилей на лине, dhcprelay-0.3.1.

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


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

Лучше с рилеем разобраться. У меня такого не наблюдается, рилей на лине, dhcprelay-0.3.1.

 

Я тоже склоняюсь к решению на самом релее.

Не должен, тем не менее такое происходит :(

 

isc-dhcp42-relay-4.2.3 The ISC Dynamic Host Configuration Protocol relay

Флаги: dhcrelay_flags="-a -D"

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


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

http://www.strongsec.com/freeswan/dhcprelay/ попробуйте. ISC - говнокодистый сильно ИМХО (посмотрите на досуге, они в dhcpd вкрячили тарболл с bind в полном обїеме - лишь для того, чтобі дернуть с него какую-то либу. Заломав на корню кросс-компиляцию ессно.)

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


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

Спасибо.

Попробую собрать его под фряхой, по результату отпишусь.

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


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

Поставил, потестил.

 

dhcprelay-1.2_1 Lightweight DHCP Relay Agent with GIF tunnel support

 

Тоже самое, правда вместо трех запросов уже приходят два (я думаю, это потому что у ICS указывается 2 интерфейса, а у этого один - внутренний).

 

Дамп данных таблицы atacc_dhcp_log

datetime client_mac client_ip relay_ip client_ident requested_ip hostname opt82_iface type

2013-03-13 13:28:00 00:02:3f:32:ed:df 192.168.199.5 0.0.0.0 0100023f32eddf star DHCPREQUEST

2013-03-13 13:28:00 00:02:3f:32:ed:df 192.168.199.5 192.168.199.1 0100023f32eddf star DHCPREQUEST

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

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


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

Нашел в портах еще один релей:

# dhcprelya -h

DHCP relay. Yandex edition. 2007-2009.

Version 3.0.

 

Та же фигня - перехватывает unicast

 

Похоже это баг релеев (а может и фича), вот подобная тема:

 

http://www.mentby.com/Group/dhcp-users/dhcp-relay-duplicate-packets-for-dhcprelease-and-dhcprequest.html

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

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


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

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

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

Или в самом коде дхцп сервера запретить обработку пакетов без адреса релей агента.

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


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

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

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

Или в самом коде дхцп сервера запретить обработку пакетов без адреса релей агента.

 

А как Вы у себя делаете?

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


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

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

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


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

У нас коммутаторы релеят.

Конкретно про два запроса - у нас специально не фильтруется ни где, и как оно долетает или нет не мониторили.

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


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

А можете подсказать, как запустить некое событие если у клиента изменился мак?

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


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

А можете подсказать, как запустить некое событие если у клиента изменился мак?

 

Наверное, для сервера это будет уже другой клиент.

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


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

А можете подсказать, как запустить некое событие если у клиента изменился мак?

Если речь о Option82, и Вы клиента можете идентифицировать не только по mac-у, то Вам нужно при получении запроса настроек, смотреть от какого mac-а пришёл этот запрос, основываясь на option82, и если MAC в базе для этой option82, отличается от MAC-а с которого прилетел запрос с этой option82, выполнять какое либо действие....

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


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

Join the conversation

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

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

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

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

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

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

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