NAT и IP-фильтрация источника в PF, используя OpenBSD> = 4.7

Я просто прочитал книгу о PF (The Book Of PF, No Starch), но на него не ответил один вопрос.

Если у меня есть шлюзовая машина, использующая два интерфейса: $ int_if и $ ext_if, а я NAT – пакеты, идущие от $ int_if: net (который, скажем, 10.0.0.0/24) до $ ext_if, используя match , когда получает NAT применяется? До или после правил фильтрации?

Пример:

 match out on $ext_if from 10.0.0.0/24 nat-to ($ext_if) pass out on $ext_if from 10.0.0.0/24 block drop out on $ext_if from 10.0.0.23 

Это работает? Или получает исходный IP-адрес пакета, идущего от 10.0.0.23 NATed к адресу $ ext_if, перед проверкой, прошел ли он от 10.0.0.23?

Эта диаграмма не помогает ответить на этот вопрос, я думаю, но это все же интересно: [ http://www.benzedrine.cx/pf_flow.png ]

Если вы читаете FAQ PF NAT [ http://www.openbsd.org/faq/pf/nat.html ], особенно раздел «Настройка NAT», вы столкнетесь с этими предложениями:

Когда пакет выбирается правилом сопоставления, параметры (например, nat-to) в этом правиле запоминаются и применяются к пакету, когда достигается правило пропуска, соответствующее пакету. Это позволяет обрабатывать целый класс пакетов одним правилом сопоставления, а затем принимать конкретные решения о том, разрешать ли трафик с помощью правил блокировки и пропуска.

Я думаю, это звучит так, как будто это не так, как я заявил в предыдущем параграфе, поэтому исходный IP-адрес «запоминается» до тех пор, пока не будет принято решение о действии, которое необходимо выполнить с пакетом. Если решение принято, применяется NAT.

Как вы думаете?

PS: Это довольно теоретический вопрос. Если вы немного прагматичны, вы сделаете это так:

 match out on $ext_if from 10.0.0.0/24 nat-to ($ext_if) block drop from 10.0.0.23 # or, explicitly, # block drop in on $int_if from 10.0.0.23 

Таким образом, правило block уже применяется, когда пакет входит в $ int_if.

EDIT: Еще одна возможность, конечно, решить перед NAT:

 pass from 10.0.0.0/24 block drop from 10.0.0.23 match out on $ext_if from 10.0.0.0/24 nat-to ($ext_if) 

Если пакет из .23 прибывает, он сначала соответствует первому правилу, затем соответствует второму правилу и третьему правилу. Но поскольку вторым правилом является последнее решение о передаче / блокировании, пакет блокируется. Правильно?

Да, это довольно теоретический вопрос, что вы задавали, но очень интересный вопрос.

Правило соответствия будет применяться, когда оно действует в последнем правиле сопоставления. правила соответствия «липкие», как вы упомянули. Основная цель их состоит в том, чтобы иметь возможность устанавливать такие вещи, как правило NAT один раз, и не нужно ставить nat-to в конце набора правил, которые вы имеете о исходящем трафике.

В вашем примере пакет будет удален. Я должен посмотреть на код или попросить Хеннинга Брауэра быть уверенным, что они полностью пропускают проверку NAT в случае сбрасывания, но он не получит NATted.

Я думаю, что ваше правило охвачено Книгой PF (получило 2-е издание?), Но я не думаю, что они явно об этом говорят с правилом совпадения.

Исправьте меня, если я ошибаюсь, вы хотите передать все исходящие пакеты из 10.0.0.0/24, но вы хотите заблокировать 10.0.0.23? Если это так, измените правило:

 match out on $ext_if from 10.0.0.0/24 nat-to ($ext_if) block drop out quick on $ext_if from 10.0.0.23 pass out on $ext_if from 10.0.0.0/24 

Просто используйте quick чтобы предотвратить продолжение фильтрации брандмауэром (аналогично break на некоторых языках программирования).

http://www.openbsd.org/faq/pf/filter.html#quick

Быстрое ключевое слово

Как указано выше, каждый пакет оценивается с помощью набора правил фильтрации сверху вниз. По умолчанию пакет помечен для прохода, который может быть изменен любым правилом и может быть изменен взад и вперед несколько раз до окончания правил фильтра. Последнее правило соответствия «выигрывает». Существует исключение: Быстрая опция в правиле фильтрации приводит к отмене любой последующей обработки правила и вызывает указанное действие. Давайте рассмотрим пару примеров:

Неправильно:

 block in on fxp0 proto tcp to port ssh pass in all 

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

Лучше:

 block in quick on fxp0 proto tcp to port ssh pass in all 

Эти правила оцениваются несколько иначе. Если строка блока согласована, из-за быстрой опции пакет будет заблокирован, а остальная часть набора правил будет проигнорирована.