*nix
12 March 2015

Практические аспекты использования DHCP relay+option82

From Sandbox
В этой статье я хотел бы осветить практические аспекты использования DHCP relay+option82 как возможность авторизации (в дальнейшем именно эта связка будет иметься ввиду), а так же привести примеры конфигурации свитча Dlink DES-3200-10 и isc-dhcp-server. Практически во всех статьях dhcp relay трактуют так: «можно вынести dhcp-сервер за пределы широковещательного домена». Однако почему-то не упоминают или почти не упоминают, что это хорошая возможность избавиться от широковешательных запросов в пределах того же самого широковешательного домена. И самое главное, на что акцентирую внимание — мы можем быть уверены, благодаря option82, что запрос пришёл именно со свитча с заданным маком и именно с порта с указанным номером, а следовательно — таким образом можно «авторизовать» пользователя.

Я немного позанудствую и напомню, как действует DHCP relay. Он перехватит широковещательный запрос (VLAN-а, на который он настроен), обернёт его в L3 и отправит unicast-ом указанному DHCP-серверу. Ну и не лишним будет напомнить, что делаетoption82. Она добавляет в DHCP-пакет два дополнительных параметра:

DHCP-Relay-Circuit-Id — номер порта с которого пришёл запрос.
DHCP-Relay-Remote-Id — (по умолчанию) макадрес свитча с которого пришёл запрос.


Ещё хочется сказать о методах внедрения этой опции в пакет.В оборудовании Dlink есть два способа:
dhcp_relay — добавляет Option82 и как писалось выше, обернёт его в L3 и отправит unicast-ом указанному DHCP-серверу
dhcp_local_relay (DHCP Snooping) — только добавляет Option82 и пересылает широковещательный пакет дальше.


Немного отклонюсь от темы. Дело в том что конструкцию dhcp_local_relay я нашёл только в оборудовании Dlink. Мне стало интересно, почему же другие производители не внедрили такую замечательную опцию? Оказывается, внедрили, и давно. Называется она DHCP Snooping.

Возможно, у кого-то возникнет вопрос: «зачем нам избавляться от широковещательного трафика»? Дело в том, что на практике я очень часто встречался с таким явлением, что при выходе из строя коммутатора, например, в результате грозы, возникают петли, что приводит к широковещательному шторму. Конечно, как вы уже догадались, от одного широковещательного трафика в IPv4 нам все равно не избавиться — это ARP-трафик. Именно он отвечает за построение таблиц MAC-IP. Конечно, можно это запретить и заполнить таблицы вручную. Но, боюсь что возникшие при этом неудобства сведут на нет все прелести от статических ARP-таблиц.


Во всех статьях указано, что DHCP-клиент и DHCP-сервер могут (должны) находиться в разных подсетях — это неправда. Вот наша схема:

image

Далее я приведу пример конфигураций:

DLINK DES-3200
config vlan default delete 1-10

 #Удаляем из дефолтного VLAN-а все порты
create vlan VLAN7 tag 7
 
#Создаем  VLAN в котором находиться наш DHCP-сервер
config vlan VLAN7 add tagged 9-10 
#Добавляем туда тегированные порты 9 и 10 (смотрят в сторону провайдера)

create vlan VLAN10 tag 10
 
#Создаем  VLAN 10 в котором у нас сидят абоненты
config vlan VLAN10 add tagged 9
-10 
#Добавляем туда тегированные порты 9 и 10 
config vlan VLAN10 add untagged 1-8 
# Добавляем туда не тегированные порты 1-8 (абонентские порты)

config ipif System ipaddress 10.90.90.90/8 
#Задаем IP-адрес свитча                                     

config ipif System vlan VLAN7
#Вешаем его на VLAN7

enable dhcp_relay
#Активируем опцию
config dhcp_relay option_82 policy replace
#Говорим что если информация в пакете уже есть то заменить
config dhcp_relay option_82 remote_id default

#Просто сохраняем параметры по умолчанию (мак)
config dhcp_relay option_82 circuit_id default

#Просто сохраняем параметры по умолчанию (№ порта)
config dhcp_relay add vlanid 10 10.90.90.92
#Говорим что весь трафик с VLAN10 перехватывать и отправлять его на DHCP-сервер с адресом 10.90.90.92
create iproute default 10.90.90.92
#Создаем дефолный маршрут, в данном примере не уверен что нужен вообще, но по феншую положено

Теперь конфиг isc-dhcp-server (isc-dhcpd-4.2.4 ) на
Linux big-A75F-M2 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux:

$sudo apt-get install vlan-tools isc-dhcp-server
$sudo vconfig add eth0 7
$sudo ifconfig eth0.7 10.90.90.92/8
#Создаем VLAN7 и назначаем адрес 10.90.90.92/8 на котором у нас будет висеть сервер DHCP


local-address 10.90.90.92;

#Теоретически это должно указывать где будет создаваться сокет для прослушки, но практически я понял что эта опция рудимент, я её пробовал изменять и комментировать ни чего не менялось, но как говорят по феншую положено :). Вообще надо сказать что сервер будет «плевать» на все ваши указания и будет автоматом вешаться на интерфейсы IP-которых попадают в подсеть описанную в subnet секции!

if exists agent.circuit-id
{
 log ( info, concat( "Lease for ", binary-to-ascii (10, 8, ".", leased-address),.

 " raw option-82 info is CID: ", binary-to-ascii (10, 8, ".", option agent.circuit-id), " AID: ",

 binary-to-ascii(16, 8, ".", option agent.remote-id)));
}
#Это просто выводит записи в наш лог файл если обнаруживается опция 82

subnet 10.0.0.0 netmask 255.0.0.0 {
    pool {
        range 10.0.0.155;
    }
}
#Задаем подсеть и пул 

Конечно, это только стендовый конфиг, но нам самое главное разобраться с принципом работы. Все же забегая в перед я могу сказать, что у меня работает биллинговая система с option82 и конструкцией dhcp_local_relay(dhcp snooping), а в качестве сервера используется freeradius2 с perl-выборкой IP-адресов из базы postgres. Но это уже выходит за рамки данной статьи.

На машине с сервером запускаем:
$sudo tcpdump -i eth0.7 -e -n -t

И если мы увидели что-то типа:
c0:a0:bb:48:e5:b0 > 00:15:17:db:e3:e0, ethertype IPv4 (0x0800), length 345: 10.90.90.90.68 > 10.90.90.92.67: BOOTP/DHCP, Request from 48:5b:39:43:78:e5, length 303

То есть нет ни каких броадкастов, значит, все идёт хорошо и настало время запускать наш DHCP-сервер.
В первый раз я рекомендую его запустить просто набрав в строке:
$sudo dhcpd

Тогда вы сразу увидите все ошибки, если они есть, и обязательно должна быть запись вида:
Listening on LPF/eth0.7/00:15:17:db:e3:e0/10.0.0.0/8
Sending on LPF/eth0.7/00:15:17:db:e3:e0/10.0.0.0/8

На всякий случай можно проверить спустя несколько секунд:
$pgrep dhcpd

Должен вернуть UID процесса, если ни чего не выведет, проверяйте конфигурацию.

Для чего нужна такая проверка? Я помню случаи, когда сервер стартовал, висел в памяти несколько секунд и вылетал. А я тщетно пытался получить получить IP-адрес.

Если все прошло удачно, в логах мы обнаружим что-то типа:
Dec 2 20:36:17 big-A75F-M2 dhcpd: DHCPREQUEST for 10.0.0.155 from 48:5b:39:43:78:e5 (big-1001PX) via 10.90.90.90

Dec 2 20:36:17 big-A75F-M2 dhcpd: DHCPACK on 10.0.0.155 to 48:5b:39:43:78:e5 (big-1001PX) via 10.90.90.90

Dec 2 20:38:06 big-A75F-M2 dhcpd: Lease for 10.0.0.155 raw option-82 info is CID: 0.4.0.10.0.3 AID: 0.6.c0.a0.bb.48.e5.b0


Теперь одна очень важная вещь, про неё нигде не написано, но я дошёл до неё экспериментальным путём. IP-адрес свитча должен находиться в той же подсети, что и адреса, выдаваемые абонентам. Ни при каких других комбинациях мне не удалось заставить работать связку Dlink DES-3200 (Boot PROM Version: Build 4.00.002 Firmware Version: Build 4.04.004 Hardware Version: C1) и isc-dhcp-server 4.2.4.

И еще не большой бонус, как не погибнуть от броадкастов. Конфиг для Dlink DES-3200 С1:

config safeguard_engine state enable
config safeguard_engine utilization rising 90 falling 30 state enable
#Это защита от перегрузки процессора
config traffic control 1-8 broadcast enable multicast enable unicast disable action drop threshol
d 64 countdown 5 time_interval 5
#Это спасет от множественных броадкастов, генерируемых клиентами
enable loopdetect
config loopdetect ports 1-8 state enable
config loopdetect recover_timer 1200 interval 10 mode port-based
#А это спасёт от петель если уж они образовались


Это статья не клон и не попытка переписать чужие статьи своими словами. Ниже список похожих публикаций и отличия от них. В своей статье я делал акцент на использование данной конструкции как метод авторизации, а не попытку вынести DHCP-сервер за пределы сети.

xgu.ru/wiki/%D0%9E%D0%BF%D1%86%D0%B8%D1%8F_82_DHCP — здесь присутствует ошибка, я потратил много времени, чтобы ее отыскать. Выше я писал о ней (ip-адрес свитча должен находиться в той же подсети, что и адреса, выдаваемые абонентам. Ни при каких других комбинациях мне не удалось заставить работать связку Dlink DES-3200 (Boot PROM Version: Build 4.00.002 Firmware Version: Build 4.04.004 Hardware Version: C1) и isc-dhcp-server 4.2.4.);
habrahabr.ru/post/143846 — здесь dhcp вынесен за пределы сети;
www.dlink.ru/ru/faq/62/228.html — здесь также dhcp вынесен за пределы сети.

+13
38.1k 117
Comments 49
Top of the day