Jump to content

Recommended Posts

Posted

Использую FreeRADIUS как DHCP сервер.

Хочу выдать клиенту статические маршруты через опцию 249

Пробовал по разному, но результат отрицательный:

 

Sending DHCP-Ack of id 592183de from 172.16.3.1:67 to 172.16.28.1:67
       DHCP-Opcode = Server-Message
       DHCP-Hardware-Type = Ethernet
       DHCP-Hardware-Address-Length = 6
       DHCP-Hop-Count = 0
       DHCP-Transaction-Id = 1495368670
       DHCP-Number-of-Seconds = 0
       DHCP-Flags = 0
       DHCP-Client-IP-Address = 0.0.0.0
       DHCP-Your-IP-Address = 192.168.28.161
       DHCP-Server-IP-Address = 192.168.3.1
       DHCP-Gateway-IP-Address = 172.16.28.1
       DHCP-Client-Hardware-Address = 00:01:a3:12:e2:94
       DHCP-Server-Host-Name = ""
       DHCP-Boot-Filename = ""
       DHCP-Router-Address = 192.168.28.1
       DHCP-Subnet-Mask = 255.255.255.0
       DHCP-Domain-Name-Server = 192.168.3.1
       DHCP-Domain-Name-Server = 192.168.3.3
       DHCP-NTP-Servers = 192.43.244.18
       DHCP-Vendor = 0x61726b617465
       DHCP-IP-Address-Lease-Time = 40
       DHCP-DHCP-Server-Identifier = 192.168.3.1
       DHCP-SMTP-Server-Address = 81.91.189.7
       DHCP-WWW-Server-Address = 192.168.3.5
       DHCP-MS-Static-Routes = "0x10c0a8c0a80607"
Finished request 1.

Опция отлично отправляется, но клиент расценивает этот пакет как невалидный и не принимает. Клиент сейчас в лице Windows 2003 Server.

В случае, если опция пустая - клиент принимает пакет.

 

В dictionary.dhcp указал её так:

ATTRIBUTE	DHCP-MS-Static-Routes			249	string

 

Пробовал по разному называть опцию, и DHCP-MS-Classless-Static-Route и MS-Classless-Static-Route, и MS-Static-Route - результат одинаковый.

 

Поиск в гугле дал странный результат - все по разному называют опцию.

 

Как именно должна называться эта опция, чтобы клиент в лице винды её нормально воспринимал? Или может быть я с типом опции намудрил?

Posted

Как внутреннее название опции отражается в DHCP пакете? Правильно, никак.

Ценной информацией было бы, если бы вы показали дамп пакета.

К слову, есть еще же опции 33 и 121.

Posted

10c0a8c0a80607

 

10 = 16

c0a8 = 192.168

c0a80607 = 192.168.6.7

Тут вроде всё правильно.

 

192.168.28.161/255.255.255.0

Скорее всего дропает потому что шлюз не попадает в подсеть клиента.

 

И "DHCP-Vendor = 0x61726b617465" - не хочу расшифровывать, там MSFT5.0 должно быть или вообще его не отдавать, оно вроде только для запросов серверу.

"DHCP-Gateway-IP-Address = 172.16.28.1" - хрень какая то, клиент такое точно не запрашивал %)

также как и ещё куча опций которыми вы в него кидаетесь.

 

 

# http://cpansearch.perl.org/src/SARENNER/Net-IPAddress-1.10/IPAddress.pm
#sub parseIPtoNumber { 
#return(unpack("N", pack("C4", split(/\./, $_[0])))); # C4 = CCCC
#}


# mask to bits
# http://milanweb.net/uni/old/scripting.html
sub subnetBits {
my $m = unpack("N", pack("C4", split(/\./, $_[0]))); # parseIPtoNumber

my $v = pack("L", $m);
my $bcnt = 0;
foreach (0..31) {
	if (vec($v, $_,1) == 1) {
		$bcnt++;
	}
}
return($bcnt);
}


# (121) Classless-Static-Route / (249) MSFT - Classless route
# by Rozhuk Ivan 2011
# RFC 3442
# based on:
# http://www.linuxconfig.net/index.php/linux-manual/network/203-transfer-of-static-routes-to-dhcp.html
# http://www.linux.by/wiki/index.php/FAQ_DHCP_routes
# Syntax: mk_classless_routes_bin_mask($net, $mask, $gw)
# example: mk_classless_routes_bin_mask('192.168.1.0', '255.255.255.0', '192.168.0.254')
sub mk_classless_routes_bin_mask {
#my $net = $_[0];
#my $mask = $_[1];
#my $gw = $_[2];

return(mk_classless_routes_bin_prefixlen($_[0], subnetBits($_[1]), $_[2]));
}

# Syntax: mk_classless_routes_bin_prefixlen($net, $prefixlen, $gw)
# example: mk_classless_routes_bin_prefixlen('192.168.1.0', 24, '192.168.0.254')
sub mk_classless_routes_bin_prefixlen {
#my $net = $_[0];
#my $prefixlen = $_[1];
#my $gw = $_[2];
my $str;

$str = pack('C', $_[1]);

if ($_[1] > 0) {
	my ($s1, $s2, $s3, $s4) = split(/\./, $_[0]);
	$str .= pack('C', $s1);
	$str .= pack('C', $s2) if ($_[1] > 8);
	$str .= pack('C', $s3) if ($_[1] > 16);
	$str .= pack('C', $s4) if ($_[1] > 24);
}

$str .= pack('CCCC', split(/\./, $_[2]));

return($str);
}

Это в бинарку пакует, если вам в хэкс то CCCC по тексту в pack нужно заменить на что то :)

 

Поиском по форуму можете найти пости Wingman с немного другой реализацией.

 

Если хотите отдавать маршрутизацию - смотрите что спрашивает клиент, если запрашивает 121 опцию - то отдавайте всё в ней, только если её нет и есть 249 то в неё это же самое пихайте.

249 - это микрософт зачем то придумал на заре ХР, толи 121 тогда не было в РФК толи выпендрится хотели, но содержимое/формат у них один. Разница в том, что опции 224-254 это вендор специфик, и если по грамотному то в 249 маршруты отдавать нужно только если вендор MSFT, а армия мыльниц может идти лесом.

И семёрка/2к8 запрашивают теперь 121 и 249.

Posted

Вроде разобрался:

Возвращаю значение теперь вот так:

$RAD_REPLY{'DHCP-MS-Static-Routes'} = mk_classless_routes_bin_prefixlen('192.168.6.0', 24, '192.168.28.2');

По функции, указанной вами выше.

 

Однако это начало работать только тогда, когда в dictionary.dhcp указал её так:

ATTRIBUTE	DHCP-MS-Static-Routes			249	octets

Т.е. аналогично 121 опции.

 

DHCP-Gateway-IP-Address - это фрирадиус зачем-то указывает IP адрес DHCP-Relay в пакете, как отключить эту опцию - не нашёл.

  • 1 month later...
Posted

Что именно вы хотите узнать?

 

 

 

 

записываем первый бат результата: длинна префикса в битах

 

$str = pack('C', $_[1]);

 

 

Если длинна префикса больше нуля то записываем байты из IP адреса сети, содержащие значащие биты

if ($_[1] > 0) {

 

разбиваем IP адрес сети на части, чтобы позже сконвертировать строковое представление в число

my ($s1, $s2, $s3, $s4) = split(/\./, $_[0]);

 

Первый байт всегда записываем, ибо мы тут потому что как минимум 1 значащий бит есть

$str .= pack('C', $s1);

 

Если значащих байт в IP адресе сети больше 1 байта (8 бит) то записываем второй байт... и аналогично до 4байта

$str .= pack('C', $s2) if ($_[1] > 8);

$str .= pack('C', $s3) if ($_[1] > 16);

$str .= pack('C', $s4) if ($_[1] > 24);

}

 

 

разбиваем IP адрес шлюза на байты, и тут же конвертируем их в число и записываем

$str .= pack('CCCC', split(/\./, $_[2]));

 

 

 

 

Тут везде подразумевается что изначально оно строка "127" - три байта, а после конвертирования оно 127 - число, 1 байт

 

 

 

  • 1 month later...
Posted (edited)

Перевел один из сегментов на DHCP на основе FreeRADIUS. Уже месяц у меня работает, старался реализовать полностью следуя RFC. Самое сложное было с динамикой. Даже удивительно что не падает и не тормозит :)

 

Кстати тут писали, что бывает и клиенты и сервера забивают на список запрошенных параметров и сервера отвечают как хотят, а клиенты это кушают. У меня клиенты физики, ОС разные, но пока такой проблемы я не увидел.

 

Еще по RFC в classless так же должен входить и дефолт! Столкнулся с этим на OpenSUSE 11.x. Виндам всем пофигу.

Edited by SokolovS
Posted

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

Join the conversation

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

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...
На сайте используются файлы cookie и сервисы аналитики для корректной работы форума и улучшения качества обслуживания. Продолжая использовать сайт, вы соглашаетесь с использованием файлов cookie и с Политикой конфиденциальности.