Перевод дерева в формат правил iptables

Допустим, есть вершина N, и это не лист. Тогда одно из правил N является активным. Из-за того, что правила в вершине описывают состояние соединений именно в этой вершине, получить ЭВ, используемое для деления узла N можно так:

1. Найти, какое из правил активно в N;

2. Выписать значение этого правила для левого потомка N.

Условно обозначим данную операцию PrintSeparation(N). На втором шаге можно было бы использовать и правого потомка, это вопрос соглашения. В генераторе всегда используется левый. Хотя iptables не поддерживает древовидные структуры, есть возможность создавать пользовательские цепочки правил, с помощью чего деревья можно моделировать. Делается это следующим образом (на примере все того же узла N):

1. создается новая цепочка с уникальным именем C(N);

2. создается правило вида «если PrintSeparation(N), то перейти в цепочку C(N)».

Все соединения левого потомка N перейдут в цепочку C(N), а соединения правого потомка останутся в текущей цепочке — что и описывает деление вершины. Имя цепочки строится по шаблону «chain» + порядковый номер.

Все дерево переводится в набор команд iptables обходом в глубину. Выше разобрано, как реализуется перевод обычных вершин (не листьев). В листьях происходит иной процесс. Напомним, что все правила листа помечены как активные. Печатаются именно эти правила, а не правила потомков (т.к. потомков нет). Также производится проверка на избыточность правил. Согласно требованиям к системе, должно обеспечиваться как можно меньшее количество сравнений для определения статуса соединения. В не-листьях избыточных сравнений быть не может, а вот в листьях они могут иметь место. Где-то в ветке от корня до листа может сработать некоторое правило R с пороговым значением а. Если ниже по ветке будут работать другие правила, то вполне вероятна ситуация, когда в конечной вершине ветки R(a) будет выписано вторично. Но это совершенно не нужно, потому что пакеты, не удовлетворяющие R(a), отсеяны раньше и в вершину попасть не могут. Для борьбы с подобными ситуациями при распечатке правил листов происходит обратный поиск по ветке от листа до корня, и избыточные правила не печатаются.

Приведем пример реального дерева правил и того, как оно переводится в набор команд iptables. Данные получены при обработке статистики, собранной на одном из сегментов локальной сети НГУ (подробнее см. главу о тестовых испытаниях системы).

Рисунок 1. Пример дерева.

На рисунке 1 изображено начало дерева. Смысл обозначений таков:

J0: порт назначения меньше или равен 80;

J1: получатель находится в любой из местных подсетей (внутренний адрес);

J2: адрес отправителя равен 193.124.208.85.

А вот как выделенная жирным ветка дерева (J0J1J2) была переведена в команды iptables:

 

1: iptables -N chain1

2: iptables -A chain0 -p tcp --dport 1:80 -j chain1

3: iptables -N chain2

4: iptables -A chain1 -m set --set mset0 dst -j chain2

...

X: iptables -A chain1 -p tcp --dport 80 -s 193.124.208.85 -j chain_accept

...

 

Номера строк проставлены вручную для удобства, в настоящих командах их нет. Из фрагмента можно увидеть, во что преобразуются J0, J1 и J2. J0 описано в строке 2, J1 — в строке 4. Как видно, все соединения, удовлетворяющие J1, уходят в цепочку chain2 и там проходят дальнейшее деление. Соединения, не удовлетворяющие J1, остаются в цепочке chain1. В строке X описано J2, а также видно следствие того, что правило портов оказалось активным в листе. Было обнаружено, что все соединения в этом листе имеют порт назначения с номером 80, и этот факт отражен в командах iptables (хотя деления по данному параметру не было). О цепочке chain_accept будет рассказано в главе, посвященной структуре генерируемых правил. Сейчас важно лишь то, что в нее попадают все нормальные пакеты.

Далее мы разберем работу двух имеющихся на данный момент в системе правил, которые покрывают четыре свойства соединения: протокол, порт назначения, адреса отправителя и получателя. Станет понятно, почему в примере выше нигде нет проверок на порт отправителя, что скрывается за наименованием mset0, откуда берется адрес 192.124.208.85, и почему в строке X нет проверки на адрес назначения.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: