Nov. 13th, 2007

nuclight: (Default)
Есть у нас в сети общаги уже долгое время две подсети, с серыми и белыми адресами, при этом бегают по одной физике. Не очень кошерная конфигурация, конечно, ну да так вышло по историческим причинам (тяжелое детство, деревянные игрушки бедные студенты, провайдер-жмот). Суть в том, что хостам желательно бы видеть друг друга напрямую, а не нагружать роутер, который раздает им Интернет, так как у него те же 100 Мбит на вход, если роутить подсети, будут жаловаться, что скорость низкая. Значит, каждому юзеру надо прописать себе постоянный статический маршрут на другую подсеть, тогда будет ходить как положено, напрямую, в обход роутера.

И тут вступает в дело человеческий фактор. Как заставить их прописать? Они ж бестолковые. Желательно бы автоматизировать. Но тут напарываемся на свойства винды. ICMP-редиректы она не принимает (от роутера, который знает, что физическая-то подсеть та же), указание маршрута на интерфейс без указания шлюза (который должен быть адресом этой же машины) она не понимает... Маздай, одним словом. В DHCP есть опция статических маршрутов, но они в ней считаются поклассово - это тогда, как более 10 лет используется CIDR, то есть для нынешних условий неприменимо.

После поисков обнаружилась такая замечательная штука, как RFC 3442, описывающий DHCP-опцию раздачи classless-маршрутов, как раз то, что нужно, даже случай другой подсети на той же физике предусмотрен. Но - его не поддерживает не то что винда, а и другие DHCP-клиенты не всех версий... В результате на сайте сети была просто вывешена динамически генерируемая инструкция, выполнить строчку вида route -p add 172.18.46.0 mask 255.255.255.0 82.117.64.2, где адресом шлюза является адрес самой машины. Инструкцию выполняли, но, конечно, не все и не всегда. Например, забывали выполнить после переустановки винды. Или просто "ниасиливали". Нагрузка на роутер от непрописавших возросла, и на нем это дело было прикрыто файрволом, в надежде, что когда перестанет работать, таки соизволят наконец прочитать инструкцию (в которой увеличилось количество выделений большими буквами и жирным шрифтом). Но толку...

Затем, после дальнейших поисков, было обнаружено, что виндовый DHCP-клиент, начиная с XP, поддерживает приватную опцию за нумером 249, отвечающую ровно за это же и имеющую абсолютно тот же формат, что и опция с кодом 121 из RFC 3442 (зачем они сменили номер, непонятно). Ну, с тем лишь отличием, что RFC предписывает игнорировать опцию routers и указывать маршрут по умолчанию внутри этой нововведенной опции, а опция от MS задает дополнительные к routers маршруты. Итак, Гугль в конце концов подсказал страничку http://scott.yang.id.au/2003/04/getting-stuck-with-dhcpd/ с вот таким примером для конфига DHCP (в котором эта опция тоже не поддерживается, но можно описывать их свои любые, какие хочется):
# MS routes: adds extras to supplement routers option
option ms-classless-static-routes code 249 = array of integer 8;
# RFC3442 routes: overrides routers option
option rfc3442-classless-static-routes code 121 = array of integer 8;
option routers 172.22.0.1;
option ms-classless-static-routes 24, 172, 22, 99, 172, 22, 0, 1 ;
option rfc3442-classless-static-routes 24, 172, 22, 99, 172, 22, 0, 1, 0, 172, 22, 0, 1 ;


Всё бы нормально, но это маршрут, указывающий на сеть, находящуюся за настоящим маршрутизатором. Популярный случай, но у нас несколько другая ситуация, сеть-то должна быть доступна напрямую. RFC 3442 в этом случае говорит, что надо указать в качестве адреса шлюза 0.0.0.0, и клиент должен понять, что это маршрут на интерфейс. Пробуем указать option ms-classless-static-routes 24, 172, 18, 46, 0, 0, 0, 0; ...и наблюдаем, как винда радостно кладет на это большой и толстый болт. Ага, думаем мы, не лыком шиты, чай, винда тупая, просто применяет сеть, маску и шлюз как в команде route. То есть, если указать адрес шлюза, должно подействовать. Пробуем option ms-classless-static-routes 24, 172, 18, 46, 82, 117, 46, 2; - ага, сожрала!

Здесь самое время почесать репу - это, значит, придется для каждого клиента в dhcpd.conf описывать индивидуальную натсройку?! Ладно здесь, когда адреса описаны статически (привязка к MAC-адресу), потеряется только изящность указания адреса в единой точке (DNS) и избыточность конфига - а если у кого-то адреса раздаются динамически, что тогда?..

После загрузочной кружки чая с шоколадом в голову приходит мысль перечитать dhcp-eval(5). Вдумчивое укуривание им и dhcp-options(5) рожает идею генерировать эту опцию для каждого клиента на ходу из его адреса. Немного правки, и возникает конструкция:

option ms-classless-static-routes = concat (24, 82, 117, 64, leased-address);

На что нас посылает нахуй уже dhcpd. С невнятной синтаксической ошибкой 117 exceeds max (255) for precision. Рытье в исходниках и манах приводит к озарению: я дебил у dhcpd разная трактовка numeric-expressions и data-expressions. То бишь, надо преобразовать форматы его встроенными функциями. И в конечном счете получаем несколько громоздкую, но работающую конструкцию:
...
# Define option codes and types for later use in subnet declarations
option ms-classless-static-routes code 249 = array of integer 8;
option rfc3442-classless-static-routes code 121 = array of integer 8;
# Classless routing:
# RFC3442 provides way to store classless routes in option 121 with
# format of 1 byte masklen, 0 to 4 bytes of destination network (rounding
# up mask bits to next byte), and 4 bytes of router address, e.g.
# 128.93.40.0/17 -> 1.2.3.4 will be bytes 17 128 93 40 1 2 3 4;
# then any number of routes in the same format. MS routes (XP+)
# are using the same format, but option code 249. Also, RFC3442
# routes require including default route (masklen 0 then IP of router)
# which overrides routers option, and MS routes don't need to
# include default route, they still use routers option.
# When destination net is directly attached to client's interface,
# as in our case below, RFC3442 requires using gate IP 0.0.0.0,
# but Windows client do not understand it, they want their own IP as
# gate IP, so we must generate this option for them from "leased-address". 

shared-network AVTF.NET {

subnet 172.18.46.0 netmask 255.255.255.0 {
        option routers 172.18.46.1;
        option broadcast-address 172.18.46.255;
        option domain-name-servers 172.18.46.1;

        option ms-classless-static-routes = concat(encode-int(24,  8),
                                                   encode-int(82,  8),
                                                   encode-int(117, 8),
                                                   encode-int(64,  8),
                                                   leased-address);
        option rfc3442-classless-static-routes 24, 82, 117, 64, 0, 0, 0, 0,
                                                0, 172, 18, 46, 1;

и т.д.


Жаль, это не работает для Windows 2000 (да и в Висте, судя по ссылкам во время поиска в гугле, в этом что-то поломали), но для большинства XPёвых машин в сети теперь будет всё нормально :)

UPDATE: Сообщили, что за прошедшие сутки с момента включения этих опций наблюдались проблемы у некоторых юзеров - Виста не может получить адрес. В инете нашлось по теме http://users.livejournal.com/_pacak_/48017.html и http://support.microsoft.com/default.aspx/kb/928233. Блядский Мелкософт. Поймаю живую Висту, поэкспериментирую, а пока что отключил опцию (странно, оно же раньше получало, в статье-то речь про другое)...

UPD2: Была найдена также ссылка http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=1383260&SiteID=17 и вышедший с тех пор хотфикс http://support.microsoft.com/kb/933340/ (должен был войти в Vista SP1). По ссылке сообщается, что Виста понимает как опцию 249, так и опцию 121 (по стандарту), но не будет принимать дублирующиеся маршруты - а в моем конфиге в обеих опциях маршруты как раз дублировались. Однако, экспериментов с этим все равно не проводил (и человеку по ссылке тоже не помогло, впрочем, у него это было до хотфикса).

February 2017

S M T W T F S
   1 234
567891011
12131415161718
19202122232425
262728    

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 10th, 2025 12:06 am
Powered by Dreamwidth Studios