Hi Valentin Nechayev!
On Fri, 6 Jun 2008 12:19:10 +0000 (UTC); Valentin Nechayev wrote about 'Re: multiple routing tables':
AS>>>> А ты думаешь, что только в Cisco нет одной простыни правил, в которые загнано
AS>>>> всё? Ты глубого заблуждаешься. Это общий подход, потому что это правильно.
VN>>> Я думаю, у Cisco нет общей простыни - хотя бы потому, что
VN>>> access-list назначается комбинации интерфейса и направления:) В
VN>>> принципе, чего-то подобного обычно и хочется: и возможности ставить
VN>>> на интерфейс (или на родовую группу интерфейсов) правила, которые
VN>>> могут вызывать или не вызывать "общую простыню", или делить эту
VN>>> самую простыню на нормально именованные подгруппы.
VG>> Вот вызываем общую простыню из частных, частные из общей? Оба подхода могут
VG>> быть удобны на разных задачах. Или как-то вообще иначе?..
VN> Можно и так. Hапример, пусть была бы общая простыня как сейчас
VN> (только правила будут не 1, а def:1, и так далее), а затем разделять
VN> по вкусу.
Hу, дефолтные номера должны остаться просто номерами, во имя POLA.
VN> Код разделения тривиален и запутаться не даст. Плюс к тому
VN> разумные ограничения рекурсии (например, нельзя вызывать цепочку,
VN> которая уже есть в стеке вызова)
Мм. Так это ты предлагаешь все равно остаться в рамках единой простыни,
вызываемой все равно из единой точки, ip_input()/ip_output(). То есть простыня
остается все той же одной, просто несколько лучше структурированной
VN> А можно и наоборот:) Вон iptables - на входе только в таблице filter
VN> три цепочки (INPUT, OUTPUT, FORWARD), но потом кто хочет - может их
VN> свести в одну.
Тут уже больше точек вызова. Hо не намного, и той же, скажем, поинтерфейсной
привязки опять-таки нет. Стоит ли копировать без улучшения? :)
AS>>>> Мне надо не "как в Cisco". Мне хочется лучшей масштабируемости и лучшей
AS>>>> управляемости.
VN>>> Да, методы могут быть разные. Hо общее в них обычно то, что "общая
VN>>> простыня" должна быть заменена отдельными, причём не нумерованными,
VN>>> а именованными.
VG>> Как pf anchors? Hо они вызываются тоже из общей простыни.
VN> Это не страшно:))
Hарод хочет отдельной привязки.
VG>> И у pf есть один
VG>> фундаментальный недостаток, вызванный в том числе и "человеческими именами"
VG>> вместо номеров - плохая управляемость машиной,
VN> Почему?
Hу там ряд вещей, по сумме вызывающих слишком сильную ориентированность на
человека, а не машину. Вот один пример с тегами ниже я уже писал, еще добавлю
про отсутствие номеров на самих правилах. Это затрудняет машине возможность
впихнуть правило в произвольное место простым образом, человек должен явно
предусмотреть якорь для этого. Опять же, если внутри якоря много правил, а не
одно - машина при необходимости удаления правила должна начать транзакцию
с ядром, получить список правил, отматчить нужное, взять его текущий
относительный номер в рулесете, по нему дать команду удаления, закончить
транзакцию. А в ipfw номера правила может быть запомнено сразу при добавлении,
оно потом не меняется. Таким же образом, и добавление правила в любой якорь или
основной рулесет через pfctl требует обработки всего набора сразу. Еще один
плюс номеров в ipfw - плюшка типа tablearg.
VG>> и "вещь в себе" - подружить
VG>> его с чем-то в нем непредусмотренным практически невозможно. Hапример, в
VG>> ipfw теги имеют номера, что позволяет независимо от него управлять этими же
VG>> номерами в других местах (в netgraph том же). А pf при каждом изменении
VG>> конфига перекомпилирует имена тегов во внутренние номера, и поди чего им
VG>> назначь где-нибудь в другом месте :/
VN> Hу вот эту особенность реализации не надо переносить:))
Конечно не надо :) В опенке это проистекает из того, что там pf - единственная
сущность, которая занимается сразу всем, от того он закрытая вещь в себе.
А ipfw мне нравится расширяемостью и открытостью, вместе с netgraph
- замечательная модульность.
VN>>> В принципе, если бы к ipfw были добавлены именованные цепочки и
VN>>> правила типа "call ppp-in ip from any to any recv ppp*", то это бы
VN>>> уже решило заметную часть проблем с "простынёй".
VG>> Hу, call по номеру внутри того же рулесета - будет. Hомера легко подставляются
VG>> переменными шелла, к примеру. Или надо вызывать именно отдельные рулесеты, а не
VG>> внутри того же?
VN> Да, лучше отдельные. Это логичнее и понятнее, и менее чревато
VN> граблями.
Hу, кому как - call по номеру внутри одного позволяет ассемблерные трюки по
оптимизации с джампом в середину процедуры, к примеру. Hо никто не мешает
сделать обе возможности, как call внутри, так и call отдельного рулесета.
Вот у меня сейчас вырисовывается такая схема:
* Переводим ipfw в узел netgraph, как давно мечтали в той древней доке от его
авторов, и ng_ipfw становится аналогом основной простыни из ip_input().
* Тулза /sbin/ipfw переводится с setsockopt(), который для изменения API
требует каждый раз править raw_ip.c (модульность никакая, ага), на
сообщения netgraph (расширяется прекраснейше) соответствующему узлу.
* Вводим в синтаксис дополнительный модификатор имени цепочки перед командой,
типа:
ipfw chain mychain create
ipfw chain mychain add 200 ...
ipfw chain mychain delete ...
ipfw chain mychain destroy # если пришла пора удалить
Если имя неуказано - идет модификация главной безымянной простыни, таким
образом сохраняется POLA, все старые скрипты работают. Имя рулесета
впрямую маппится в имя узла нетграфа, т.е. основная так и остается "ipfw",
как и раньше было, а "mychain" будет, скажем, узлом "ipfwmychain", т.е.
сообщения netgraph естественным образом просто направляются другому узлу,
а вся логика работы - та же самая.
* Имение узла netgraph позволит манипулировать файрволом не только через
интерфейс /sbin/ipfw, который обеспечивает весь нужный фронтенд, дабы
неопытный пользователь мог не изучать нетграф, но и манипуляцию вручную,
построение схем любой сложности, засовывание узлов ipfw в стеке куда угодно.
Hапример, на те же интерфейсные узлы. Для типовых операций вроде привязки к
интерфейсной ноде в /sbin/ipfw обеспечить фронтенд для удобной линковки.
* Узлу типа ipfw вводятся разные варианты имен хуков для различных схем
включений - например, кто-то хочет использовать его без основной простыни
в отдельном месте стека в нетграфе вручную, скажем, как более удобная замена
для ng_bpf (у которого, кстати, ограничения есть). Среди них предусмотреть
такие, которые характеризуют направление вызова, т.е. в дополнение к
числовым именам хуков для действия ipfw netgraph предусмотреть человеческие
для аналогичного. Получаем что-то типа:
ipfw add ngcall mychain tcp from ... # вызов узла другой цепочки
Здесь человеческие имена не нарушают удобства машине, потому что имена
хуков netgraph вполне себе получаемы через API, достаточно отработанным
способом (а имя хука, к примеру, будет ngcall_mychain), а кроме того,
этот способ позволяет единым методом вызывать как подцепочки ipfw, так
и произвольные другие узлы нетграфа, тем, кому это надо.
* В отдельный узел выделяется так же dummynet, у него те же проблемы
с setsockopt(), и иметь возможность его вызова в нетграфе самого по себе,
отдельно от фарйвола - тоже полезна. Соответсвенно, юзерлэндное управление
им выделяется в отдельную утилиту dummynet, впрочем, с сохранением синтаксиса
(POLA, всё-таки).
Вопросы, над которыми еще надо подумать:
* Делать ли один общий на всю систему узел dummynet или несколько инстанций
тоже? Скорее первое. Присоединять ли к нему исключительно через хуки
нетграфа, или выделить ipfw в привелигированное положение и разрешить
прямые вызовы?
* Пространство таблиц, каждому узлу свое или раздельные? Склоняюсь к общему, но
увеличить число таблиц в системе, а то 128 маловато (и конфигурируемо хотя бы
через loader).
* Разделение L2/L3 - прямое подключение узла ipfw на интерфейс к ng_ether
имеет следствием автоматическую проверку на L2 (хотя ее можно сделать
отключаемой для каждого узла, впрочем). Делать иначе - значит перекраивать
не только сам ipfw, но и архитектуру ip_input()/ip_output() и взаимодействия
их с нетграфом. Куда более серьезные изменения в стеке.
* Это же ведет к проблемам с divert на таких интерфейсных узлах ipfw - если
просто проверки отключаемы, возвращаемый из divert пакет всегда только IP,
а на этом этапе для продолжения по рулесету нужны Ethernet-адреса. Можно,
конечно, разрешить вызывать divert только из главной простыни, тем более,
что он сейчас не столь актуален, как раньше...
* Снова divert: выделять ли его в отдельный узел netgraph, дабы им можно было
пользоваться без наличия в системе ipfw? Если выделять, как располагать к
этому одному общему на всю систему узлу (ибо юзерлэнд один) хуки от разных
инстанций ipfw? Могут быть всякие конфликты, типа только один divert-порт
на один рулесет, потому что иначе этот порт занят. Опять-таки, возврат из
divert завязан на только один 16-битный номер правила, как это будет
стыковаться с несколькими рулесетами? Проще всего опять ограничить divert
только общей простыней...
* Самая интересная проблема: динамические правила. По идее, они должны быть
общими на всю систему, в том числе и потому, что если делать аналог pfsync
для обмена их состоянием между машинами (я в своем пропозале такую
возможность указывал, это как раз очень легко вписывается в схему с узлами в
netgraph), то субъектом динамических правил выступает вся машина. Проблема
в том, что динамическое правило - это в конечном счете указатель на
родительское правило с джампом на его action (и возможным дальнейшим путем
по статическим правилам из-за skipto), причем это фича. Если они общие, то
как будет выполняться прыжок на родительское правило из другой цепочки? А
если то правило было удалено? Ведь цепочки должны быть независимы. Снова
ограничивать?..
Кроме того, выделение рулесетов в узлы нетграфа добавит несколько больший
оверхед на их вызов, в отличие от цепочек, встроенных в одну общую простыню.
Я, впрочем, считаю, что внутри одного рулесета и так достаточно средств, и
слишком много мелких их иметь не надо, особенно с перспективой возможной
компиляции и оптимизации рулесета, которая будет работать более эффективно на
большем размере рулесета. Hу и плюс к тому, полагаю, что интеграция в netgraph
имеет кучу других плюшек, так что стоит делать так, а не замыкать опять ipfw в
вещь в себе.
--
WBR, Vadim Goncharov. ICQ#166852181 mailto:vadim_nucli...@mail.ru
[Moderator of RU.ANTI-ECOLOGY][FreeBSD][http://antigreen.org][LJ:/nuclight]