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

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

День добрый.

 

запустил сервер, но почему то получают ip, только win7,

а хр, маршрутизаторы и sip пристаки не могут получить((

 

куда копать?

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

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


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

вроде ничего не заметил(((

вот лог

 

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

dhcp-log.zip

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


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

Проблема не в этом, странно ведут себя все утройства, получают через раз.

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


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

DHCPdump, tcpdump в помощь.

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

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


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

релеем выступают коммутаторы dlink 1228/me, буду на месте гляну, просто обычный dhcp+option82 работает без проблем, просто задолбались с лизой и перезапусками)

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


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

Делаю пул адресов, по подсказкам Ивана.

Пока как я понял, делаю такое.

в handle_discover

условие db_get_requested_data меняю на

if (db_get_offer_data($_[0], $_[2], $dhcpresp) == 1) {

send_reply($_[1], $_[2], $dhcpresp, $_[0]);

 

//db_lease_offered($_[0], $_[2]);

описываю новую db_get_offer_data все так же как и в db_get_requested_data но в запрос добавляю выборку адреса с пустой арендой или самой старой

$sth = $_[0]->prepare("SELECT `cl_id`,`ip`, `mask`, `gateway`

FROM `clients`, `locations`, `vlans`

WHERE `clients`.`port`=$dhcp_opt82_port_id

AND `locations`.`switch`='$dhcp_opt82_chasis_id'

AND `vlans`.vlan_id=$dhcp_opt82_vlan_id

AND `locations`.`loc_id`=`clients`.`location` AND `clients`.`disabled`=0

AND (`clients`.`lease_time`='' or `clients`.`lease_time`<UNIX_TIMESTAMP()) limit 1");

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

$sth = $_[0]->prepare("UPDATE `dhcp`.`clients` SET `mac`='$mac', `lease_time` = 'UNIX_TIMESTAMP()+10' WHERE `clients`.`cl_id` ='$result->{ip}';");

чтоб адрес застолбить за абонентом, пока идет обмен.

 

Дальше, db_get_requested_data оставил без изменений, должно отработать но надо проверить.

 

Изменил db_lease_release, добавил запрос на обнуления IP по маку:

$sth = $_[0]->prepare("UPDATE `dhcp`.`clients` SET `lease_time` = '' WHERE `clients`.`mac` ='$mac';");

 

добавил запрос в db_lease_success

$sth = $_[0]->prepare("UPDATE `dhcp`.`clients` SET `lease_time` = 'UNIX_TIMESTAMP()+86400' WHERE `clients`.`mac` ='$mac';");

столбим IP абоненту и ставим время аренды сутки

 

Это все что я пока понял из подсказок Ивана :)

Подскажите что может еще упускаю?

 

В базе надо добавить в таблицу клиентов столбец lease_time, на и в админке изменить чтоб на 1 порт повесить кучу адресов, т.к. нужны все адреса в базе с теми же параметрами опции 82

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


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

выкладываю то что получилось.

dhcp.zip

 

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

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


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

еще косяк нашел, не отловил почему, но клиент что просто по опции работает, не получает адрес...

dhcpd.pl.txt

 

П.С. Добавил логирование в syslog даже в режиме демона, при включенной опции -v 1

П.С.С. syslog падает,

Aug 6 21:43:38 server2 kernel: [2953199.986711] dhcpd.pl[3084]: segfault at 4 ip b7264d6f sp bfe35290 error 4 in Syslog.so[b7264000+3000]

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


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

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

dhcpd.pl.txt

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


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

Добрый день!

Моя доработка сервера

request_loop

перед

if (defined($dbh) == 0) {
	logger("Thread ($tid): Could not connect to database: $DBI::errstr");
	thread_exit(1);
}

вставляем

until($dbh = DBI->connect("DBI:".$DBDATASOURCE, $DBLOGIN, $DBPASS)){
	logger("Thread ($tid): Could not connect to database: $DBI::errstr");
	logger("Thread ($tid): Sleeping 10 sec to retry");
	sleep(10);
}

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

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

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


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

кто нить пробовал вариант с пулом адресов? что то у меня кто то получает ИП, кто то нет.

вот так выглядит картина с некоторыми:

log_dhcp.gif

 

Может ли это связано с тем что клиент пытается подключится на гране сигнала ВИФИ точки?

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


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

кто нить пробовал вариант с пулом адресов? что то у меня кто то получает ИП, кто то нет.

вот так выглядит картина с некоторыми:

post-31895-095383300 1408861133_thumb.gif

 

Может ли это связано с тем что клиент пытается подключится на гране сигнала ВИФИ точки?

Думаю врядли...

Покажи более детально изменения свои в скрипте сервера.

Я сейчас делаю изменения для обновления зон dns, а потом выложу скрипт со своими изменениями(для freebsd - rc-script, сам сервер, конфиг, порт сделал, но версия увеличилась но в исходники не засунул).

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


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

выше я выкладывал свой вариант сервера с пулом адресов. отличается от оригинала добавлением и изменением db_get_requested_data/db_get_offer_data

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

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


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

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

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


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

странно все это, надо как то последить...

 

П.С. Глюк с перебором адресов тоже пока не решенный, т.е. 1 клиент может сделать несколько запросов и ему сервер зарезирвирует десяток адресов.

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


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

еще косяк нашел, не отловил почему, но клиент что просто по опции работает, не получает адрес...

dhcpd.pl.txt

 

П.С. Добавил логирование в syslog даже в режиме демона, при включенной опции -v 1

П.С.С. syslog падает,

Aug 6 21:43:38 server2 kernel: [2953199.986711] dhcpd.pl[3084]: segfault at 4 ip b7264d6f sp bfe35290 error 4 in Syslog.so[b7264000+3000]

Падает от частых обращений к syslog!

Не правильно построена функция логирования, решение

переносим код открытия сеанса логирования openlog() в sub startpoit, а closelog() в конец sub main вот и будет постоянно открытый сокет с syslog через который будут идти все логи, а не открывать-закрывать сокет при каждом сообщении!

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


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

Спасибо, приму к сведению.

 

Но так и не получилось сделать 100% рабочий сервер с пулом. Не могу понять что им не нравится и все тут...

вот небольшой дамп ДХЦП запросов

https://yadi.sk/i/B1TPkFvjb744g

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


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

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

постоянно сыпят

DHCPAck и DHCPINFORM или такой набор DHCPREQUEST и DHCPAck

я уже не говорю про DHCPRELEASE штук 30 в сек.

 

По DHCPREQUEST предполагаю что сыпит из за отсутствия 249 (MSFT - Classless route)

 

вот запрос ответ спамера:

 

TIME: 2015-05-31 10:28:03.939

IP: 10.10.100.245 (70:72:cf:30:65:b0) > 10.10.10.2 (48:5b:39:a1:e8:e6)

OP: 1 (BOOTPREQUEST)

HTYPE: 1 (Ethernet)

HLEN: 6

HOPS: 1

XID: e0a484bb

SECS: 0

FLAGS: 0

CIADDR: 172.20.8.1

YIADDR: 0.0.0.0

SIADDR: 0.0.0.0

GIADDR: 10.10.100.245

CHADDR: ac:22:0b:0b:db:8c:00:00:00:00:00:00:00:00:00:00

SNAME: .

FNAME: .

OPTION: 53 ( 1) DHCP message type 8 (DHCPINFORM)

OPTION: 61 ( 7) Client-identifier 01:ac:22:0b:0b:db:8c

OPTION: 12 ( 7) Host name B011114

OPTION: 60 ( 8) Vendor class identifier MSFT 5.0

OPTION: 55 ( 13) Parameter Request List 1 (Subnet mask)

15 (Domainname)

3 (Routers)

6 (DNS server)

44 (NetBIOS name server)

46 (NetBIOS node type)

47 (NetBIOS scope)

31 (Perform router discovery)

33 (Static route)

121 (Classless Static Route)

249 (MSFT - Classless route)

43 (Vendor specific info)

252 (MSFT - WinSock Proxy Auto Detect)

 

OPTION: 82 ( 18) Relay Agent Information

Circuit-ID 00:04:00:d0:01:01

Remote-ID 00:06:70:72:cf:9a:37:9d

---------------------------------------------------------------------------

 

TIME: 2015-05-31 10:28:03.939

IP: 10.10.10.2 (48:5b:39:a1:e8:e6) > 10.10.100.245 (70:72:cf:30:65:b0)

OP: 2 (BOOTPREPLY)

HTYPE: 1 (Ethernet)

HLEN: 6

HOPS: 0

XID: e0a484bb

SECS: 0

FLAGS: 0

CIADDR: 172.20.8.1

YIADDR: 172.20.8.1

SIADDR: 0.0.0.0

GIADDR: 10.10.100.245

CHADDR: ac:22:0b:0b:db:8c:00:00:00:00:00:00:00:00:00:00

SNAME: .

FNAME: .

OPTION: 53 ( 1) DHCP message type 5 (DHCPACK)

OPTION: 54 ( 4) Server identifier 10.10.10.2

OPTION: 51 ( 4) IP address leasetime 84600 (23h30m)

OPTION: 58 ( 4) T1 42300 (11h45m)

OPTION: 59 ( 4) T2 74025 (20h33m45s)

OPTION: 1 ( 4) Subnet mask 255.255.255.0

OPTION: 3 ( 4) Routers 172.20.8.254

OPTION: 6 ( 8) DNS server 8.8.8.8,8.8.4.4

OPTION: 31 ( 1) Perform router discovery 0 (disabled)

OPTION: 43 ( 13) Vendor specific info 0104000000020204 ........

00000001ff .....

OPTION: 46 ( 1) NetBIOS node type 8 (H-node)

OPTION: 121 ( 14) Classless Static Route 100a0aac1408fe10 ........

ac14ac1408fe ......

OPTION: 82 ( 18) Relay Agent Information

Circuit-ID 00:04:00:d0:01:01

Remote-ID 00:06:70:72:cf:9a:37:9d

---------------------------------------------------------------------------

 

 

вопрос с двумя опциями маршрутов.

Я так полагаю вот такие изменения надо внести:

 

 

sub db_get_routing {

#my $dbh = $_[0];

#my $dhcpreqparams = $_[1];

#my $subnet_id = $_[2];

#my $dhcpresp = $_[3];

my $sth;

my $opt33Enbled;

#my $optClasslessRoutesCode;

my $optClasslessRoutesCode121;

my $optClasslessRoutesCode249;

 

# do not add routes if not requested

if (defined($_[1]) == 0) {

return();

}

 

$opt33Enbled = index($_[1], DHO_STATIC_ROUTES());

if ($opt33Enbled == -1) {

$opt33Enbled = undef;

}

 

/*$optClasslessRoutesCode = index($_[1], 121);

if ($optClasslessRoutesCode == -1) {

$optClasslessRoutesCode = index($_[1], 249);

if ($optClasslessRoutesCode == -1) {

$optClasslessRoutesCode = undef;

}else{

$optClasslessRoutesCode = 249;

}

}else{

$optClasslessRoutesCode = 121;

}*/

 

$optClasslessRoutesCode121 = index($_[1], 121);

if ($optClasslessRoutesCode121 == -1) {

$optClasslessRoutesCode121 = undef;

}else{

$optClasslessRoutesCode121 = 121;

}

$optClasslessRoutesCode249 = index($_[1], 249);

if ($optClasslessRoutesCode249 == -1) {

$optClasslessRoutesCode249 = undef;

}else{

$optClasslessRoutesCode249 = 249;

}

if (defined($opt33Enbled) == 0 && (defined($optClasslessRoutesCode121) == 0 || defined($optClasslessRoutesCode249) == 0) ) {

# nothink to do, return

return();

}

 

$sth = $_[0]->prepare("

SELECT

`destination`,

`mask`,

`gateway`

FROM `subnets_routes`

WHERE `subnet_id` = '$_[2]'

LIMIT 30"

);

 

if (defined($DEBUG)) {

logger("db_get_routing");

logger("SELECT `destination`, `mask`, `gateway`FROM `subnets_routes` WHERE `subnet_id` = '$_[2]' LIMIT 30");

}

 

 

$sth->execute();

if ($sth->rows()) {

my $ref;

my $row;

my $opt33_data = undef;# routes to single hosts

my $opt_classless_routes_data = undef;# routes to nets

 

$ref = $sth->fetchall_arrayref;

foreach $row ( @{$ref} ) {

if (defined($opt33Enbled) && @$row[1] eq '255.255.255.255') {

# pack dst

$opt33_data .= pack('CCCC', split(/\./, @$row[0]));

 

# pack gw

$opt33_data .= pack('CCCC', split(/\./, @$row[2]));

}

if (defined($optClasslessRoutesCode121) || defined($optClasslessRoutesCode249)) {

$opt_classless_routes_data .= mk_classless_routes_bin_mask(@$row[0], @$row[1], @$row[2]);

}

}

 

if (defined($opt33_data)) {# add option

$_[3]->addOptionRaw(DHO_STATIC_ROUTES(), $opt33_data);

}

 

if (defined($opt_classless_routes_data) && defined($optClasslessRoutesCode121)) {# add option

$_[3]->addOptionRaw($optClasslessRoutesCode121, $opt_classless_routes_data);

}

if (defined($opt_classless_routes_data) && defined($optClasslessRoutesCode249)) {# add option

$_[3]->addOptionRaw($optClasslessRoutesCode249, $opt_classless_routes_data);

}

}

$sth->finish();

 

}

 

 

П.С. В перле я не силен, проверил, опцию отдает, но спамер не успакаивается.

П.С.С. Еще есть по меньше спамеры, хотят 252 (MSFT - WinSock Proxy Auto Detect). В какое место его впихнуть?

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


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

И чем вам этот "спам" мешает? Если следующий кривой роутер начнет запрашивать еще 157 ненужных опций, тоже их будете допиливать?

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


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

INFORM + 252 (MSFT - WinSock Proxy Auto Detect) - это от службы обнаружения прокси WinHTTP (виндуст апдейт её использует), и от браузеров ИЕ.

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

Если хочешь пропиши туда URL, типа: http://192.168.2.3/wpad.dat

а на 192.168.2.3 подними http сервер и положи wpad.dat в корень с содержимым вида:

function FindProxyForURL(url, host) { return "DIRECT"; }

миме тип должен быть: Content-Type: application/x-ns-proxy-autoconfig

 

Для nginx файл можно не создавать, а добавить в конфиг (секция сервер):

# wpad.dat

# dnsmasq.conf: dhcp-option=252,http://your.server.here:port/wpad.dat

location ^~ /wpad.dat {

more_set_headers 'Content-Type: application/x-ns-proxy-autoconfig';

add_header Cache-Control 'max-age=30, must-revalidate';

return 200 'function FindProxyForURL(url, host) { return "DIRECT"; }';

}

 

или можешь просто дропать INFORM запросы, на работоспособности оно не сказывается, ибо служит только для запроса дополнительных параметров, а производительность дропания очень высокая :)

Можно даже ACL на коммутаторе набросать чтобы отбрасывал INFORM или где то в iptables.

 

Касательно DHCPREQUEST - нужно смотреть кто и что запрашивает.

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


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

 

http://habrahabr.ru/company/mailru/blog/259521/#comment_8450407 - тут говорят это всё кривая венда виновата.

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


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

Решил и я попробовать данный сервер (isc dhcp долго перезагружается).

Дописал все чтобы выдавать из адреса из пула, решил протестить скорость.

Выводы грустные - на 2 ядрах, 2.2Hz (правда вирт машина), скорость обработки запросов используя только 1 Select на запрос(выборка клиента) - около 1000 запросов в секунду, что в общем-то хорошо. (0.0012 c на ответ)

Если же делать так как нужно и выполнять потом еще и update времени лизы при выдаче, то скорость получается 0.008с, что всего около 100-120 ответов сервера в секунду (. (при этом логи в мускул не дописываю)

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

В общем немного грустновато со скоростью, особенно если появится какая-то вирусня или "добрый" пользователь,

проблема в mysql и скорости update.

Кто-то реально мерял у себя скорость работы с mysql?

Еще почему-то иногда, при большом потоке запросов, падает коннект к базе мускула ( почему - еще допроверяю)

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


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

Join the conversation

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

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

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

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

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

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

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