В данной статье я расскажу как все же заставить работать isc-dhcpd с биллинговой системой UTM5 от компании NetUP (Российская Федерация).
Данный костыль не рассчитывает быть полноценным, но его можно использовать на первое время, если у вас не особо то и сегментированная сеть. Если же вы используете в своей сети opt82 (выдача ip-адреса по порту коммутатора), то придется писать немного другой скриптик, но об этом в другой раз
Приступим.
На сервере dhcp должны быть установлены следующие программы и модули:
Далее создаем каталог dhcp в /usr/local/etc/. Мне было удобно именно в этой папке, там же лежит и dhcpd.conf.
Далее создаем в этой же папке /usr/local/etc/dhcp/ файл dhcp.sh следующего содержания:
И ставим этот файл на запуск в крон. Как вашей душе угодно
я выставил каждые 10 минут.
Все данные пишутся в файл /etc/dhcpd.hosts в виде:
Дальше нам остается добавить в /usr/local/etc/dhcpd.conf в конец конфига строчку: include "/etc/dhcpd.hosts".
В общем то и все
Конфиг dhcpd.conf:
Естественно все ip-адреса и mac-адреса вымышленные
Удачи! 
Еще добавлю, для защиты от dhcp-snooping, на порту коммутатора (у меня cisco) нужно указать следующие опции:
Данный костыль не рассчитывает быть полноценным, но его можно использовать на первое время, если у вас не особо то и сегментированная сеть. Если же вы используете в своей сети opt82 (выдача ip-адреса по порту коммутатора), то придется писать немного другой скриптик, но об этом в другой раз
Приступим.
На сервере dhcp должны быть установлены следующие программы и модули:
| 1. isc-dhcp30-relay-3.0.7 2. isc-dhcp30-server-3.0.7_5 3. p5-DBD-mysql50-4.013 4. p5-DBI-1.60.9 5. p5-Storable-2.21 6. perl-5.10.1 |
Далее создаем каталог dhcp в /usr/local/etc/. Мне было удобно именно в этой папке, там же лежит и dhcpd.conf.
В /usr/local/etc/dhcp/ кладем вот такой файл на перле:
| #!/usr/bin/perl use DBI; use DBD::mysql; #use lib '/cktv/perl'; #use cktv::logger; # Инициализация #loginfo "Обновление DHCPD"; $dbh = DBI->connect("DBI:mysql:UTM5;192.168.1.1", "login", "password", {'RaiseError' => 1}) or die crit msg "Can't connect to DB!"; open F, ">", "/tmp/dhcpd.hosts.new"; # Получаем данные (192.168.xx.xx) my $items = $dbh->selectall_arrayref( "SELECT inet_ntoa(ip & 0xFFFFFFFF) as ip, ip_groups.mac, accounts.is_blocked FROM ip_groups,iptraffic_service_links, service_links, users, accounts WHERE ip_groups.mac!='' AND accounts.id=users.basic_account AND service_links.user_id=users.id AND service_links.is_deleted='0' AND ip_groups.is_deleted='0' AND iptraffic_service_links.ip_group_id=ip_groups.ip_group_id AND service_links.id=iptraffic_service_links.id GROUP BY ip_groups.ip ORDER BY ip_groups.ip" ); # Таблица для поиска дублей my ( %MAC, %IP ) = (); for my $item ( @$items ) { my ( $ip, $mac ) = @$item; $mac =~ s/^\s+//; $mac =~ s/\s+$//; $mac = uc $mac; # Проверяем мак unless ( $mac ) { # DHCP не нужен next; } elsif ( $mac =~ /^[0-9A-F]{2}(?::[0-9A-F]{2}){5}$/ ) { # Мак правильный } elsif ( $mac =~ /([0-9A-F]{2})([0-9A-F]{2})\.? ([0-9A-F]{2})([0-9A-F]{2})\.? ([0-9A-F]{2})([0-9A-F]{2})/x ) { # Цисковский или просто числа $mac = "$1:$2:$3:$4:$5:$6"; #crit msg "Fixed: $ip $mac"; print "Fixed: $ip $mac"; } else { #msg "Wrong: $ip $mac"; print "Wrong: $ip $mac"; next; } # Проверка на дубликаты if ( $MAC{$mac} ) { #crit msg "Duplicate MAC: $ip $mac"; # print 12; print "Duplicate MAC: $ip $mac"; next; } if ( $IP{$ip} ) { #crit msg "Duplicate IP: $ip $mac"; print "Duplicate IP: $ip $mac"; next; } $IP{$ip} = 1; $MAC{$mac} = 1; # Сохраняем в конфиг $ip =~ /^(\d+\.\d+)\.(\d+)\.(\d+)$/; my $opt = ''; # if ( $ip =~ /^123\.123\.123\./ ) { # # Внешний адрес нашего C-класса # $opt .= sprintf "option host-name pc_%03s_%03s; ", $2, $3; # } if ( $ip =~ /^123\.123\.123\./ ) { # Внешний адрес нашего C-класса $opt .= sprintf "option host-name host-%0s-%0s.broadband.domain.ru; ", $2, $3; } # printf F "host pc_%03s_%03s { hardware ethernet %s; fixed-address %s; option routers %s; }\n", # $2, $3, $mac, $ip, "$1.$2.1",$opt; # printf F "host $ip { hardware ethernet %s; fixed-address %s; option routers %s; }\n", # $mac, $ip, "$1.$2.1",$opt; printf F "host $ip { hardware ethernet %s; fixed-address %s; }\n", $mac, $ip; } # Отключаемся $dbh->disconnect; close F; |
Далее создаем в этой же папке /usr/local/etc/dhcp/ файл dhcp.sh следующего содержания:
| #!/bin/sh /usr/local/etc/dhcp/dhcp.pl diff /etc/dhcpd.hosts /tmp/dhcpd.hosts.new > /dev/null >> /var/log/dhcpd_updater || (/usr/local/sbin/dhcpd -t -cf /usr/local/etc/dhcpd.conf 2>&1 && cp /tmp/dhcpd.hosts.new /etc/dhcpd.hosts && /usr/local/etc/rc.d/isc-dhcpd forcerestart 2>&1 && echo Reboot: \`date\` >> /var/log/dhcpd_updater); |
И ставим этот файл на запуск в крон. Как вашей душе угодно
Все данные пишутся в файл /etc/dhcpd.hosts в виде:
host 192.168.10.2 { hardware ethernet 00:00:00:00:00:00; fixed-address 192.168.10.2; }
|
Дальше нам остается добавить в /usr/local/etc/dhcpd.conf в конец конфига строчку: include "/etc/dhcpd.hosts".
В общем то и все
Конфиг dhcpd.conf:
| # /usr/local/etc/dhcpd.conf # # Конфигурация для isc-dhcp сервера # # Глобальные параметры #======================================================== # Доменый суффикс, который будет присвоен клиентам option domain-name "domain.ru"; # Список DNS серверов, которые должен использовать клиент option domain-name-servers 192.168.1.1; server-name "domain"; # На какое время выдавать клиентам настройки (в секундах) 86400сек=1день default-lease-time 86400; # На какое максимальное время выдавать клиентам настройки (в секундах) max-lease-time 172800; # Минимально на сколько выдается IP-адрес min-lease-time 86400; #======================================================== #Параметр определяет, будет ли DHCP-сервер пытаться обновить DNS при выдаче конфигурационной информации ddns-update-style none; #ddns-update-style interim; # Данный параметр говорит, что мы будем обновлять DNS зону (т.к. мы уже выбрали, что не будем ее обновлять, то комментируем эту строчку) #ddns-update-style ad-hoc; # Включаем IP-Forwarding option ip-forwarding on; #ddns-fwd-name ns.domain.ru; # Объявляем, что наш DHCP-сервер самый авторитетный (т.е. главный в сети) authoritative; # Логи которые отправляет DHCP-сервер log-facility local7; ignore client-updates; deny bootp; deny client-updates; deny duplicates; ignore declines; # Локальные параметры сети (настройка сети) #========================================== shared-network domain { subnet 192.168.10.0 netmask 255.255.255.0 { # Сеть которую объявляем и маска данной сети option subnet-mask 255.255.255.0; option routers 192.168.10.1; option broadcast-address 192.168.10.255; option domain-name-servers 192.168.1.1; pool { range 192.168.10.2 192.168.10.254; deny unknown-clients; # Запретить выдачу IP-адресов не известным клиентам # deny client-updates; # deny bootp; # deny duplicates; # ignore declines; } option netbios-node-type 8; option ntp-servers 192.168.1.1; # Сервер синхронизации времени default-lease-time 86400; # Поумолчанию на сколько выдается IP-адрес max-lease-time 172800; # Максимально на сколько выдается IP-адрес, после чего мы его сами забираем } subnet 192.168.11.0 netmask 255.255.255.0 { # Сеть которую объявляем и маска данной сети option subnet-mask 255.255.255.0; option routers 192.168.11.1; option broadcast-address 192.168.11.255; option domain-name-servers 192.168.1.1; pool { range 192.168.11.2 192.168.11.254; deny unknown-clients; # Запретить выдачу IP-адресов не известным клиентам # deny client-updates; # not authoritative; # deny bootp; # deny duplicates; # ignore declines; } option netbios-node-type 8; option ntp-servers 192.168.1.1; # Сервер синхронизации времени default-lease-time 86400; # Поумолчанию на сколько выдается IP-адрес max-lease-time 172800; # Максимально на сколько выдается IP-адрес, после чего мы его сами забираем } include "/etc/dhcpd.hosts"; } |
Естественно все ip-адреса и mac-адреса вымышленные
Еще добавлю, для защиты от dhcp-snooping, на порту коммутатора (у меня cisco) нужно указать следующие опции:
| switchport access vlan xx #VLAN в котором сидит dhcp switchport mode access no cdp enable ip dhcp snooping limit rate 500 #Лимит запросов ip dhcp snooping trust #Объявляем, что наш dhcp самый главный в сети (так называемая защита от подмены запросов) |