dhcp option82 + freeradius + ipoe

Технические вопросы по UTM 5.0
wingman
Сообщения: 136
Зарегистрирован: Чт дек 07, 2006 15:36
Контактная информация:

dhcp option82 + freeradius + ipoe

Сообщение wingman »

Предыстория: достаточно долго метался в поисках способа удобного запуска на сети dhcp+option 82.
Потому как ISC-DHCP - это:
- километровые неудобочитаемые конфиги;
- постоянные передергивания при изменениях;
- НЕ-риалтайм управление DHCP-сервером;
- невозможность быстрой смены компа на порту, т.к. запомненная лиза не даст выдать IP заново другому маку
- Сложность с выдачей нескольких IP на порт.
- Ооочень большие сложности, если вдруг придёт в голову раздавать динамические внешники. Привязка ипа к аккаунту в билинг - только хз какими костылями.

Вместе с тем, кроме ISC-DHCP вроде как промышленно-стандартных dhcp-серверов и нету.


Но порыскав по этому форуму, я наткнулся на несколько постов ув. Magnum72 в духе "юзайте freeradius as dhcp, и всё будет" =) После нескольких дней, долгого ковыряния радиуса и одного багрепорта ;)) для себя в голове минимально-необходимое уложил:

- freeradius работает как DHCP с поддержкой Option82. И даже при некоторой удаче крутится и не падает.
- Реализован в freeradius практически только голый сетевой API. Содержимым пакетов, что когда и куда управлять - писать нужно самому. С одной стороны, оно и к лучшему.
- Реализовывается нужный функционал любым rlm_*, где есть хук post_auth(). Для себя я выбрал rlm_perl ;) С одной стороны, работать, конечно, будет помедленнее, чем бинарный сяшный dhcpd. С другой стороны, никто не мешает поднять хоть штук пять dhcp-серверов. И либо для разных сегментов в свитчах в разном порядке релеи прописывать, либо ещё как балансировать. Зато удобство и скорость разработки в разы возрастают. Ну и устаканив всё в перле, можно и свой rlm-модуль на сях написать.


Вывод - надо пробовать поднять всё на фрирадиусе ;)
Нужно как-то сформулировать для себя логику работы работы DHCP, и вот собсно в этом-то и проблема. С одной стороны ничего особо сложного, с другой - камней подводных может быть много.


Необходимые факторы работы DHCP вижу следующие:
1. Возможность выдачи нескольких IP на порт (читай на аккаунт).
2. Возможность дополнительной привязки к маку (Вдруг где-то в старом сегменте таки-останется тупой свитч)
3. Не должно быть проблем с моментальным перетыкиванием устройств на порту. Переткнул -- заработать должно сразу.
4. Должны выдаваться статические маршруты, поскольку гонять инет будем через PC, а локалку через железки.
5. В заблокированном состоянии в наших планах на порту прописывать другой влан. В этом влане выдавать всем IP из некого IP-пула "blocked" и заворачивать http-трафик на страничку "дай денег" ;))
6. Во-первых, во избежание путаницы, которая может возникнуть если монтажник перепутал порты на свитче, или сдох свитч и заменили на новый.
Во-вторых, чтобы не нужно было прописывать порт юзера заранее, до физического подключения.
а. Сделать отнельный влан "неактивированные", в котором заворачивать хттп на страничку "введите логин и пароль".
б. При вводе -- скрипт должен оббежать свитчи по указаному в билинге для юзера адресу и найти его мак.
в. Найдя мак на абонентском (1-24) порту, включить на нём untagged рабочий влан
г1. Найти в билинге привязки данного логина. Если есть - удалить.
г2. Привязать данный логин к найденному скриптом порту.
Х. Вся информация (свитч+порт+возможный мак) должна браться из базы на лету и не кешироваться, чтобы при блокировке юзера, например, не нужно было передёргивать конфиг.




Алгоритм дхцп представляю как-то так:

Код: Выделить всё

Приходит DHCP-Discover/Request
	Смотрим, есть ли в нём информация Option82.
		Если option82_info {
			Если влан "заблокированные", выдаём IP-адрес из серого спецпула. Пишем в лизы.
			Если влан "неактивированные", выдаём из другого серого спецпула. Пишем в лизы.
			Иначе {
				выбрать ip, где port=X AND switch=Y AND (mac='x-x-x-x-x-x' OR mac='');
				Если rows > 1 {
					// Если возможных ипов на свитче более одного
					выбрать ip из lease_table где port=y and switch=z and last_leased_time > (now_time - $lease_time + 5)
					Если есть лизы {

						Возможно, юзер включил 2 компа параллельно. Смотрим лизы.
						Если текущая лиза с таким же маком, как в запросе - возможно, просто ребут компа. Выдаём тот же ип.
						Если текущая лиза с другим маком И лиза только одна - выдаём второй возможный ип.
						Если активных лиз (с неистеченным lease_time) столько же, сколько возможных ипов для порта и такого
							мака, как пришел в запросе - в них нет, затираем лизу с временем обновления старше остальных и
							выдаём ип из неё по новой.

						Обновляем last_leased_time в лизе.
					} // if leases exists

				} // if rows>1

				Если возможный ип на порту только один { в любом случае, независимо от прошлых лиз выдаём один и тот же ип. }

			} // if !blocked && !unact
		} // if op82
		else {
			// Если запрос пришел без option82 инфы. По идее, это случается только когда IP уже получен, и требуется обновление
			// лизы. Ну или `ipconfig /renew`, например. Тогда комп обращается к dhcp по уникасту, и relay-инфо в пакет не вставляется.
			а. Из пришедшего пакета известен IP + MAC
			б. Выбрать из lease_table ГДЕ ip=$ip AND mac=$mac
			в. Если есть - отдаём ту же самую инфу и обновляем лизу
			г. Если нет -- шлём DHCPNAK ( [b]?[/b] ХЗ, в каких случаях может такое случиться кроме глюка клиента? По идее не должно )

		} // if !op82


DHCP-Release -> затираем лизу

DHCP->Inform -> Что с ними делать, зачем они могут понадобиться? 
DHCP-Остальное -> Игнорим?
Из этого пока у меня есть freeradius, перенаправляющий DHCP на rlm_perl, в котором есть привязка в коде одного ip для одного порта =)


Ещё остаётся вопрос: как разруливать пулы? Попробовать прикрутить sql_ippool (никогда не юзал, не знаю, как работает), или своими силами так же, как лизы? типа select ... from pool where last_leased_time < (time-$lease_time+10) ? Тогда нужно таблицу со всеми возможными ипами держать, некрасиво ;)


Собственно, у самого голова уже кругом и глаз замылен, хочу попросить у общественности посмотреть на возможные недостатки данной схемы и поискать подводные камни, которые мне в голову пока не пришли.
Кто заинтересован в развитии чего-то такого - буду рад любой помощи, Кто уже внедрил что-то по теме сабжа у себя - буду рад саветам и направлениям в нужное русло ;)

Самому мне по условиям задачи нужно или поднять, оттестить и внедрить у себя option82 + IPoE в течение пары месяцев, или забыть надолго. Буду стараться внедрить ;)

Аватара пользователя
TiRider
Сообщения: 568
Зарегистрирован: Сб июн 07, 2008 12:43

Сообщение TiRider »

Тоже подумываю о таком проекте.. Буду следить как у тебя продвигается. отписывайся, делись информацией ;) и я как займусь тоже буду калякать сюда... ;)

wingman
Сообщения: 136
Зарегистрирован: Чт дек 07, 2006 15:36
Контактная информация:

Сообщение wingman »

TiRider писал(а):Тоже подумываю о таком проекте.. Буду следить как у тебя продвигается. отписывайся, делись информацией ;) и я как займусь тоже буду калякать сюда... ;)
Да собсно черновой вариант уже есть ;) Надо допиливать, дописать руками работу с pool'ами, искать баги и тестить...

Аватара пользователя
TiRider
Сообщения: 568
Зарегистрирован: Сб июн 07, 2008 12:43

Сообщение TiRider »

Отписывайся если есть затыки. Бум думать :wink:

wingman
Сообщения: 136
Зарегистрирован: Чт дек 07, 2006 15:36
Контактная информация:

Сообщение wingman »

TiRider писал(а):Отписывайся если есть затыки. Бум думать :wink:
Сейчас основной затык -- стОит ли пытаться убрать rlm_perl и попробовать сделать на unlang. По идее должно быть постабильнее и немного побыстрее, но блин геморрно, и хз реализуемо ли вообще =)

wingman
Сообщения: 136
Зарегистрирован: Чт дек 07, 2006 15:36
Контактная информация:

Сообщение wingman »

TiRider писал(а):Отписывайся если есть затыки. Бум думать :wink:
Было бы неплохо, если бы кто-нибуть посмотрел:
http://ip-home.net/_wingmans/dhcp.pl.txt

и поискал возможные косяки и недостатки в логике
Ну и потестил бы ;)

Arti
Сообщения: 266
Зарегистрирован: Пн окт 01, 2007 02:44

Сообщение Arti »

Энергично Вы взялись :).

Я вот тока не понял как свич, правильней сказать релей идентифицируется.

Здесь я так понимаю вытаскивается влан и порт:

Код: Выделить всё

		# Parse Circuit-ID&#58;
		my @carr = split //, $CIRCUIT;
		$switch = $RAD_REQUEST&#123;'DHCP-Gateway-IP-Address'&#125;;
		my $hex = $carr&#91;6&#93;.$carr&#91;7&#93;.$carr&#91;8&#93;.$carr&#91;9&#93;;
		$vlan = hex&#40;$hex&#41;;
		$hex = $carr&#91;10&#93;.$carr&#91;11&#93;.$carr&#91;12&#93;.$carr&#91;13&#93;;
		$port = hex&#40;$hex&#41;;

да и в sql-запросе после "Find possible ips for this port in database" я других идентификаторов не вижу.


Кстати говоря... не так давно нашёл у себя смешной баг. Суть которого в том, что свич релеет DHCP запрос, но "оригинальный" пакет с запросом при этом благополучно предаётся дальше.

У Вас я смотрю тоже есть "защита от дурака":

Код: Выделить всё

		# Do nothing if port is magistral, i.e. 25.26.27.28
		if&#40;$port == 25 || $port == 26 || $port == 27 || $port == 28&#41;
		&#123;
я правда у себя решил этот вопрос более тупо:

Код: Выделить всё

create access_profile ip udp src_port_mask 0xFFFF dst_port_mask 0xFFFF source_ip_mask 0.0.0.0 destination_ip_mask 255.255.255.255 profile_id 1
config access_profile profile_id 1 add access_id 1 ip udp src_port 68 dst_port 67 source_ip 0.0.0.0 destination_ip 255.255.255.255 port 49-50 deny
здесь подразумевается des-3550 и что 49 порт - даунлинк, ну и соотвественно на агрегации тоже самое, только на все порты.

wingman
Сообщения: 136
Зарегистрирован: Чт дек 07, 2006 15:36
Контактная информация:

Сообщение wingman »

>> Энергично Вы взялись :).
Можно на "ты" ;))
Я же говорю, время поджимает - а запустить-таки хочется


>> Я вот тока не понял как свич, правильней сказать релей идентифицируется.

Код: Выделить всё

$switch = $RAD_REQUEST&#123;'DHCP-Gateway-IP-Address'&#125;;

>> да и в sql-запросе после "Find possible ips for this port in database" я других идентификаторов не вижу.

Код: Выделить всё

... AND &#40;user_additional_params.paramid=7 AND user_additional_params.value='$switch&#58;$port'&#41; ...
Я у себя пока решил сделать доп.параметр в билинге, и писать туда в формате ип_свитча:порт, типа "1.2.3.4:22"


>> Кстати говоря... не так давно нашёл у себя смешной баг. Суть которого в том, что свич релеет DHCP запрос, но "оригинальный"
>> пакет с запросом при этом благополучно предаётся дальше.
У нас dhcp пока не запущено, поэтому пока тестирую чисто на себе ;(
Если у вас уже крутится - подскажи пару моментов:
- как option82 работает, если в несколько свитчей в цепочке?
Я имею в виду -- если, например, включить режим dhcp_relay option82 "replace", то в цепочке работать не будет - все запросы от нижестоящих свитчей будут похерены, т.к. только на юзерские порты релей включить нельзя.
А если "keep" - то теоретически это уязвимость, т.к. юзер может сформировать левый пакет, послав option82-аттрибуты соседнего порта на свитче, и свитч с полиси 'keep' этот пакет не тронет (т.к. op82 уже есть)

- Сколько в среднем запросов/сек на dhcp приходит и на какое число юзеров?

- Как ведут себя релеи при петле в сегменте? Не получится ли ддоса dhcp-сервера? =)


>> здесь подразумевается des-3550 и что 49 порт - даунлинк
По-моему, некузяво ;) Таким макаром не получится иметь типовой конфиг, т.к. нужно всегда перед заливкой конфига разбираться какой порт ап-, какой даунлинк

mikkey finn
Сообщения: 1612
Зарегистрирован: Пт ноя 10, 2006 15:23

Сообщение mikkey finn »

у длинка можно посмотреть на dhcp_local_relay - эта фича позволяет включить релей только на нужных портах/влане.
Ну и при цепочке все релеится замечательно.
Я для себя посегментно привожу к раздаче адресов по opt82. Конфиг генерю раз в 5 минут.
Для удобства сделал sql view, в котором собираю локальный адрес клиента, мак, свич, порт, uid. Из этого view делаю classes/pools в конфиге.
Сейчас держу два сервера - один чисто opt82, второй раздает по mac-адресам. Время аренды 10 минут, инет по pptp.
Для opt82 и ACL, вырубающих должников, завел два параметра - адрес коммутатора и порт. Плодить много записей в табличке фаерволов биллинга не охота. Да и для инвентаризации не помогает. Биллинг не умеет распределять порты на лету, как адреса из подсетей.
Да, стоят 3028/R2.50 везде. 48 портов в ящик не влазят, а ящик поглубже ставить проблематично.

Arti
Сообщения: 266
Зарегистрирован: Пн окт 01, 2007 02:44

Сообщение Arti »

wingman писал(а): Я у себя пока решил сделать доп.параметр в билинге, и писать туда в формате ип_свитча:порт, типа "1.2.3.4:22"
>> здесь подразумевается des-3550 и что 49 порт - даунлинк
По-моему, некузяво ;) Таким макаром не получится иметь типовой конфиг
У меня всегда аплиньк комбо два. Ничего в этом такого нет. В сети зоопарк 3526/3550 3528/3552. Конфиги типовые на влан и свич.


У меня есть цепочки из свичей правда не длинные - не более 3 штук. После релея пакет летит юникастом и релей агент не должен его трогать.

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

Запросов после того как пофиксил баг с "массовым релем" совсем немного точно не измерял - смотрю по top'у и потерянным udp - если статистика устраивает - то я и ничего не трогаю :)

Arti
Сообщения: 266
Зарегистрирован: Пн окт 01, 2007 02:44

Сообщение Arti »

mikkey finn писал(а):у длинка можно посмотреть на dhcp_local_relay -
Эта... я все ленюсь проверить: он оригинальный клиентский DHCP-запрос форвардит дальше?
Последний раз редактировалось Arti Ср июн 02, 2010 20:05, всего редактировалось 1 раз.

mikkey finn
Сообщения: 1612
Зарегистрирован: Пт ноя 10, 2006 15:23

Сообщение mikkey finn »

а вот этого не скажу, не проверял.

mikkey finn
Сообщения: 1612
Зарегистрирован: Пт ноя 10, 2006 15:23

Сообщение mikkey finn »

Arti писал(а):
wingman писал(а): Я у себя пока решил сделать доп.параметр в билинге, и писать туда в формате ип_свитча:порт, типа "1.2.3.4:22"
>> здесь подразумевается des-3550 и что 49 порт - даунлинк
По-моему, некузяво ;) Таким макаром не получится иметь типовой конфиг
У меня всегда аплиньк комбо два. Ничего в этом такого нет. В сети зоопарк 3526/3550 3528/3552. Конфиги типовые на влан и свич.


У меня есть цепочки из свичей правда не длинные - не более 3 штук. После релея пакет летит юникастом и релей агент не должен его трогать.

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

Запросов после того как пофиксил баг с "массовым релем" совсем немного точно не измерял - смотрю по top'у и потерянным udp - если статистика устраивает - то я и ничего не трогаю :)
И клиенты на свиче получают адрес из пула, первый свободный? каждый раз может быть новый адрес из пула? Эт не очень. У нас любят искать во внутрисети децкую порнуху, соотв задают вопросы "а кто у вас сидит с таким-то адресом?" Если адрес из пула - отвечать устанешь, имхо.

wingman
Сообщения: 136
Зарегистрирован: Чт дек 07, 2006 15:36
Контактная информация:

Сообщение wingman »

Arti писал(а):
mikkey finn писал(а):у длинка можно посмотреть на dhcp_local_relay -
Эта... я все ленюсь проверить: он оригинальный клиентский DHCP-запрос форвардит дальше?
http://forum.dlink.ru/viewtopic.php?t=6 ... Y&start=30
Функция DHCP Local Relay представляет собой Option 82 Insertion когда поля Option 82 добавляются в каждый Broadcast DHCP пакет от клиента без Relay в оригинальном VLAN-е. При использовании DHCP Relay на этой серии глобальное включение этой функции позволяет блокировать DHCP Broadcast пакеты в клиентских VLAN-ах, что как раз позволяет правильно использовать функцию в топологии цепочка или кольцо.
Вот как-то так. Т.е. как раз relay - оставляет оригинальный запрос, а local_relay блочит.
Но вот (сходу не найду) читал, как мне кажется, на форуме длинка, что есть в ней какие-то проблемы

Arti
Сообщения: 266
Зарегистрирован: Пн окт 01, 2007 02:44

Сообщение Arti »

лень все от неё...

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

Поводу ссылки на длинк - все надо проверять самому :) особенно когда дело касается dlink. Качество софта у них весьма посредственное - вон все основые баги в 3526/52 пофиксили примерно за год до её снятия с производства, да и то... в 5-той есть баг с igmp, 6-тую досих пор в паблик не выкладывают (там это баг должен быть пофиксен), а сами свичи уже давно не выпускают :).

Закрыто