Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss
Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

ipfw and keep-state

267 views
Skip to first unread message

Victor Sudakov

unread,
Jul 19, 2007, 3:11:35 AM7/19/07
to
Коллеги,

Есть набор правил:

00050 divert 8668 ip from any to any via rl0
00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
00300 deny log logamount 100 ip from x.x.x.x/27 to any out via rl0
00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
65535 allow ip from any to any

Почему может такое происходить, что при попытке установить tcp сессию с
x.x.x.x на y.y.y.y динамическое правило не создаётся и обратные пакеты
режутся 400-м правилом? Это как-то связано с 50-м правилом: если его
убрать, динамическое правило будет создаваться.

Где я торможу? И что можно проделать, кроме явного разрешения обратного
трафика с y.y.y.y ?

--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

Kirill Nuzhdin

unread,
Jul 19, 2007, 3:36:24 AM7/19/07
to
Victor Sudakov wrote:
> Коллеги,
>
> Есть набор правил:
>
> 00050 divert 8668 ip from any to any via rl0
> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
> 00300 deny log logamount 100 ip from x.x.x.x/27 to any out via rl0
> 00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
> 65535 allow ip from any to any
>
> Почему может такое происходить, что при попытке установить tcp сессию с
> x.x.x.x на y.y.y.y динамическое правило не создаётся и обратные пакеты
> режутся 400-м правилом? Это как-то связано с 50-м правилом: если его
> убрать, динамическое правило будет создаваться.
>
> Где я торможу? И что можно проделать, кроме явного разрешения обратного
> трафика с y.y.y.y ?

а что нат с этими пакетами делает? (x.x.x.x->y.y.y.y)

--
Best regards,
Kirill Nuzhdin

Vadim Guchenko

unread,
Jul 19, 2007, 3:41:58 AM7/19/07
to

VS> 00050 divert 8668 ip from any to any via rl0
VS> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
VS> 00300 deny log logamount 100 ip from x.x.x.x/27 to any out via rl0
VS> 00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
VS> 65535 allow ip from any to any

А где check-state?

VS> И что можно проделать, кроме явного разрешения обратного
VS> трафика с y.y.y.y ?

Обратный TCP трафик эффективнее разрешить правилом allow tcp from any to any
established. Динамические правила лучше создавать только для исходящих UDP.
Если сервер с натом является шлюзом для локалки в инет, то смысла для
натовых пакетов создавать динамические правила нет вообще. Сеть за натом
(если там серые адреса) и так защищена. Чтобы правила файрвола стали
простыми и понятными, есть смысл явно разделить обработку входящего и
исходящего трафика. В этом случае на нат будет не один, а два диверта.

--
Best regards, Vadim.

Kirill Nuzhdin

unread,
Jul 19, 2007, 3:48:36 AM7/19/07
to
Vadim Guchenko wrote:
>
> VS> 00050 divert 8668 ip from any to any via rl0
> VS> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
> VS> 00300 deny log logamount 100 ip from x.x.x.x/27 to any out via rl0
> VS> 00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
> VS> 65535 allow ip from any to any
>
> А где check-state?

там же где и первый keep-state

Victor Sudakov

unread,
Jul 19, 2007, 4:40:38 AM7/19/07
to

natd настроен транслировать любые RFC1918 адреса в некий публичный
адрес (не в y.y.y.y).

Victor Sudakov

unread,
Jul 19, 2007, 4:48:41 AM7/19/07
to
Vadim Guchenko wrote:

> VS> 00050 divert 8668 ip from any to any via rl0
> VS> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
> VS> 00300 deny log logamount 100 ip from x.x.x.x/27 to any out via rl0
> VS> 00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
> VS> 65535 allow ip from any to any

> А где check-state?

Правило для check-state не обязательно указывать явно. Оно получает тот
же номер, что соответствующее ему keep-state.

Но на самом деле check-state тут совсем не при чём. "ipfw -d list"
показывает, что динамическое правило вообще не создаётся.

> VS> И что можно проделать, кроме явного разрешения обратного
> VS> трафика с y.y.y.y ?

> Обратный TCP трафик эффективнее разрешить правилом allow tcp from any to any
> established. Динамические правила лучше создавать только для исходящих UDP.

Вопрос был не как лучше сделать, а почему не работает данная
конструкция. В ней есть ошибка? Возможно, какой-то неочевидный мне
момент с порядком прохождения пакетов через ipfw?

Насчёт established спорно. Пропускать пакет от кого попало только на
том основании, что на нём есть ACK bit?

Kirill Nuzhdin

unread,
Jul 19, 2007, 5:04:22 AM7/19/07
to

очевидно, что

1. правило 50 (именно нат) модифицирует пакеты вида x.x.x.x->y.y.y.y так, что
они перестают попадать под правило from x.x.x.x/27 to y.y.y.y

2. после модификации пакетов, они таки доходят до некоего адресата, ответы
которого попадают под правило 400 from any to x.x.x.x/27 in via rl0

было бы проще ответить на вопрос, если представлять где адреса хххх уууу, из
какой подсети адрес у rl0, как идет интересующий пакет, пришедший на rl0 пакет,
что из хххх и уууу из рфц1918, а что нет

Vadim Guchenko

unread,
Jul 19, 2007, 5:12:56 AM7/19/07
to

>> VS> 00050 divert 8668 ip from any to any via rl0
>> VS> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
>> VS> 00300 deny log logamount 100 ip from x.x.x.x/27 to any out via
>> rl0
>> VS> 00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
>> VS> 65535 allow ip from any to any

>> А где check-state?
VS> Правило для check-state не обязательно указывать явно. Оно получает
VS> тот же номер, что соответствующее ему keep-state.

Забыл этот момент. Обычно я явно указываю check-state.

VS> Вопрос был не как лучше сделать, а почему не работает данная
VS> конструкция. В ней есть ошибка? Возможно, какой-то неочевидный мне
VS> момент с порядком прохождения пакетов через ipfw?

Вероятно при попытке установить соединение с хостом y.y.y.y нат заменяет в
исходящем пакете src_ip на некий публичный адрес, не входящий в подсеть
x.x.x.x/27, поэтому правило 220 не срабатывает.

VS> Насчёт established спорно. Пропускать пакет от кого попало только на
VS> том основании, что на нём есть ACK bit?

А чем это хуже ситуации с динамическими правилами?

--
Best regards, Vadim.

Alex Mogilnikov

unread,
Jul 19, 2007, 11:19:07 AM7/19/07
to
Привет Victor!

19 Jul 07 11:11, Victor Sudakov писал All:

VS> 00050 divert 8668 ip from any to any via rl0
VS> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state

VS> Почему может такое происходить, что при попытке установить tcp сессию
VS> с x.x.x.x на y.y.y.y динамическое правило не создаётся и обратные
VS> пакеты режутся 400-м правилом? Это как-то связано с 50-м правилом:
VS> если его убрать, динамическое правило будет создаваться.

Потому что порядок операций у тебя несимметричен: в одном направлении
правилом проверяется реальный адрес, а в обратном - транслированный. Или
наоборот, смотря где кто находится. По идее, надо делать два разных
divert-правила для "туда" и для "обратно", чтобы проверка адресов оказалась
между ними.

Всего наилучшего, [Team PCAD 2000]
Алексей М.
... в манах то любой ламмер прочитать сможет (c) Andrew Wingorodov

Vadim Goncharov

unread,
Jul 19, 2007, 11:43:14 AM7/19/07
to
Hi Victor Sudakov!

On Thu, 19 Jul 2007 08:48:41 +0000 (UTC); Victor Sudakov wrote about 'Re: ipfw and keep-state':

>> Обратный TCP трафик эффективнее разрешить правилом allow tcp from any to any
>> established. Динамические правила лучше создавать только для исходящих UDP.

VS> Вопрос был не как лучше сделать, а почему не работает данная
VS> конструкция. В ней есть ошибка? Возможно, какой-то неочевидный мне
VS> момент с порядком прохождения пакетов через ipfw?
VS> Насчёт established спорно. Пропускать пакет от кого попало только на
VS> том основании, что на нём есть ACK bit?

Ну, допустим, что в обычных условиях так теоретически можно нахакерить.
Но за NAT-то с чего? Так что в этом случае вполне можно.

--
WBR, Vadim Goncharov. ICQ#166852181 mailto:vadim_n...@mail.ru
[Moderator of RU.ANTI-ECOLOGY][FreeBSD][http://antigreen.org][LJ:/nuclight]

Vadim Goncharov

unread,
Jul 19, 2007, 11:51:46 AM7/19/07
to
Hi Victor Sudakov!

On Thu, 19 Jul 2007 07:11:35 +0000 (UTC); Victor Sudakov wrote about 'ipfw and keep-state':

VS> Есть набор правил:

VS> 00050 divert 8668 ip from any to any via rl0
VS> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
VS> 00300 deny log logamount 100 ip from x.x.x.x/27 to any out via rl0
VS> 00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
VS> 65535 allow ip from any to any
VS> Почему может такое происходить, что при попытке установить tcp сессию с
VS> x.x.x.x на y.y.y.y динамическое правило не создаётся и обратные пакеты
VS> режутся 400-м правилом? Это как-то связано с 50-м правилом: если его
VS> убрать, динамическое правило будет создаваться.
VS> Где я торможу?

В порядке прохождения пакетов через ipfw. В данном рулесете каждый пакет
"наружу" попадет в divert 4 раза, правило проверки стоит уже после
диверта, на прохождении в out через него пойдет пакет с уже
оттранслированным адресом. Следует разделить диверты на входе и выходе
и соответственно расположить динамические правила.

У меня это делается примерно вот так:
ipfw add divert natd ip from $graynet to any out xmit $extiface recv $intiface
ipfw add divert natd ip from any to $ext_nat_address in recv $extiface

Vadim Goncharov

unread,
Jul 19, 2007, 11:56:47 AM7/19/07
to
Hi Victor Sudakov!

On Thu, 19 Jul 2007 08:48:41 +0000 (UTC); Victor Sudakov wrote about 'Re: ipfw and keep-state':

VS>> 00050 divert 8668 ip from any to any via rl0
VS>> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
VS>> 00300 deny log logamount 100 ip from x.x.x.x/27 to any out via rl0
VS>> 00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
VS>> 65535 allow ip from any to any
>> А где check-state?

VS> Правило для check-state не обязательно указывать явно. Оно получает тот
VS> же номер, что соответствующее ему keep-state.
VS> Но на самом деле check-state тут совсем не при чём. "ipfw -d list"
VS> показывает, что динамическое правило вообще не создаётся.

Хм, только сейчас заметил, что keep-state повешен на всё сразу,
возможно, причина не-создания лежит здесь - точнее, оно создается, но
с дефолтным таймаутом в секунду и успевает исчезнуть раньше, чем
придет ответ / будет просмотрен список правил. Впрочем, я тут могу
ошибаться, сначала в любом случае следует разносить диверты.

Victor Sudakov

unread,
Jul 19, 2007, 10:33:16 PM7/19/07
to
Kirill Nuzhdin wrote:
> >>> Есть набор правил:
> >>>
> >>> 00050 divert 8668 ip from any to any via rl0
> >>> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
> >>> 00300 deny log logamount 100 ip from x.x.x.x/27 to any out via rl0
> >>> 00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
> >>> 65535 allow ip from any to any
> >>>
> >>> Почему может такое происходить, что при попытке установить tcp сессию с
> >>> x.x.x.x на y.y.y.y динамическое правило не создаётся и обратные пакеты
> >>> режутся 400-м правилом? Это как-то связано с 50-м правилом: если его
> >>> убрать, динамическое правило будет создаваться.
> >>>
> >>> Где я торможу? И что можно проделать, кроме явного разрешения обратного
> >>> трафика с y.y.y.y ?

[dd]

> очевидно, что

> 1. правило 50 (именно нат) модифицирует пакеты вида x.x.x.x->y.y.y.y так, что
> они перестают попадать под правило from x.x.x.x/27 to y.y.y.y

Спасибо, так и оказалось.

Victor Sudakov

unread,
Jul 19, 2007, 10:37:17 PM7/19/07
to
Vadim Guchenko wrote:

> >> VS> 00050 divert 8668 ip from any to any via rl0
> >> VS> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
> >> VS> 00300 deny log logamount 100 ip from x.x.x.x/27 to any out via
> >> rl0
> >> VS> 00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
> >> VS> 65535 allow ip from any to any

[dd]

> Вероятно при попытке установить соединение с хостом y.y.y.y нат заменяет в
> исходящем пакете src_ip на некий публичный адрес, не входящий в подсеть
> x.x.x.x/27, поэтому правило 220 не срабатывает.

Так и есть. А как же теперь написать правило с keep-state, чтобы
учесть NAT?

> VS> Насчёт established спорно. Пропускать пакет от кого попало только на
> VS> том основании, что на нём есть ACK bit?

> А чем это хуже ситуации с динамическими правилами?

Теоретически, может случиться ACK flood и firewall не спасет.

Victor Sudakov

unread,
Jul 19, 2007, 10:38:17 PM7/19/07
to
Vadim Goncharov wrote:

> >> Обратный TCP трафик эффективнее разрешить правилом allow tcp from any to any
> >> established. Динамические правила лучше создавать только для исходящих UDP.
> VS> Вопрос был не как лучше сделать, а почему не работает данная
> VS> конструкция. В ней есть ошибка? Возможно, какой-то неочевидный мне
> VS> момент с порядком прохождения пакетов через ipfw?
> VS> Насчёт established спорно. Пропускать пакет от кого попало только на
> VS> том основании, что на нём есть ACK bit?

> Ну, допустим, что в обычных условиях так теоретически можно нахакерить.
> Но за NAT-то с чего? Так что в этом случае вполне можно.

Пожалуй ты прав, NAT сам по себе stateful, особенно с -deny_incoming.

Victor Sudakov

unread,
Jul 19, 2007, 10:51:48 PM7/19/07
to
Vadim Goncharov wrote:

> VS> Есть набор правил:

> VS> 00050 divert 8668 ip from any to any via rl0
> VS> 00220 allow ip from x.x.x.x/27 to y.y.y.y keep-state
> VS> 00300 deny log logamount 100 ip from x.x.x.x/27 to any out via rl0
> VS> 00400 deny log logamount 100 ip from any to x.x.x.x/27 in via rl0
> VS> 65535 allow ip from any to any
> VS> Почему может такое происходить, что при попытке установить tcp сессию с
> VS> x.x.x.x на y.y.y.y динамическое правило не создаётся и обратные пакеты
> VS> режутся 400-м правилом? Это как-то связано с 50-м правилом: если его
> VS> убрать, динамическое правило будет создаваться.
> VS> Где я торможу?

> В порядке прохождения пакетов через ipfw. В данном рулесете каждый пакет
> "наружу" попадет в divert 4 раза,

То так. Однако простейший пример, который я брал из /etc/rc.firewall.

> правило проверки стоит уже после
> диверта, на прохождении в out через него пойдет пакет с уже
> оттранслированным адресом. Следует разделить диверты на входе и выходе
> и соответственно расположить динамические правила.

> У меня это делается примерно вот так:
> ipfw add divert natd ip from $graynet to any out xmit $extiface recv $intiface
> ipfw add divert natd ip from any to $ext_nat_address in recv $extiface

А где должен стоять keep-state относительно этих двух строчек?

Впрочем, keep-state не обязательно, natd сам отсеет ненужный входящий
трафик. Задача в другом - часть пакетов из приватной сети должна уйти
в ipsec, часть пройти через NAT и далее попасть на разрешённый список
хостов в Интернете, а остальной трафик должен быть запрещён.

Andrew Filonov

unread,
Jul 20, 2007, 1:34:09 AM7/20/07
to
>>>>> "VS" == Victor Sudakov writes:

VS> 00050 divert 8668 ip from any to any via rl0 00220 allow ip from
VS> x.x.x.x/27 to y.y.y.y keep-state 00300 deny log logamount 100 ip
VS> from x.x.x.x/27 to any out via rl0 00400 deny log logamount 100
VS> ip from any to x.x.x.x/27 in via rl0 65535 allow ip from any to
VS> any

VS> Где я торможу?
Ну от тебя я такого не ожидал.

divert port
Divert packets that match this rule to the divert(4) socket bound
to port port. _The search terminates_.

VS> И что можно проделать, кроме явного разрешения обратного трафика
VS> с y.y.y.y ?
ничего.

--
Andrew E. Filonov
No one's life, liberty, or property are safe
while the legislature is in session.

Victor Sudakov

unread,
Jul 20, 2007, 1:43:45 AM7/20/07
to
Andrew Filonov wrote:

> VS> 00050 divert 8668 ip from any to any via rl0 00220 allow ip from
> VS> x.x.x.x/27 to y.y.y.y keep-state 00300 deny log logamount 100 ip
> VS> from x.x.x.x/27 to any out via rl0 00400 deny log logamount 100
> VS> ip from any to x.x.x.x/27 in via rl0 65535 allow ip from any to
> VS> any

> VS> Где я торможу?
> Ну от тебя я такого не ожидал.

> divert port
> Divert packets that match this rule to the divert(4) socket bound
> to port port. _The search terminates_.


Ну и что, что terminates?

# Network Address Translation. All packets are passed to natd(8)
# before they encounter your remaining rules. The firewall rules
# will then be run again on each packet after translation by natd
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# starting at the rule number following the divert rule.

Так что проблема была в другом.

Andrew Filonov

unread,
Jul 20, 2007, 2:17:57 AM7/20/07
to
>>>>> "VS" == Victor Sudakov writes:


VS> Ну и что, что terminates?
А то, что дальше - идет совсем другой пакет.

--
Andrew E. Filonov
The mountain gets steeper as you get closer.

Victor Sudakov

unread,
Jul 20, 2007, 3:14:12 AM7/20/07
to
Andrew Filonov wrote:


> VS> Ну и что, что terminates?
> А то, что дальше - идет совсем другой пакет.

Я уже все мозги свернул, пытаясь сделать на ipfw нечто вполне
тривиальное с точки зрения циски. Спасибо, что хоть политики IPSec не
через правила ipfw задаются, а то и они путались бы под ногами (про
плохого танцора можешь не напоминать, сам знаю).

Может лучше ipnat задействовать?

Vadim Goncharov

unread,
Jul 20, 2007, 3:36:26 AM7/20/07
to
Hi Victor Sudakov!

On Fri, 20 Jul 2007 02:38:17 +0000 (UTC); Victor Sudakov wrote about 'Re: ipfw and keep-state':

>>> Обратный TCP трафик эффективнее разрешить правилом allow tcp from any to any
>>> established. Динамические правила лучше создавать только для исходящих UDP.
VS>> Вопрос был не как лучше сделать, а почему не работает данная
VS>> конструкция. В ней есть ошибка? Возможно, какой-то неочевидный мне
VS>> момент с порядком прохождения пакетов через ipfw?
VS>> Насчёт established спорно. Пропускать пакет от кого попало только на
VS>> том основании, что на нём есть ACK bit?
>> Ну, допустим, что в обычных условиях так теоретически можно нахакерить.
>> Но за NAT-то с чего? Так что в этом случае вполне можно.

VS> Пожалуй ты прав, NAT сам по себе stateful, особенно с -deny_incoming.

Я больше имел в виду то, что серые адреса - unrouteable. Левые пакеты на
машины снаружи просто не могут прилететь (разве что из directly-attached
к роутеру сети, но решается включением antispoof или verrevpath в ipfw).

Vadim Goncharov

unread,
Jul 20, 2007, 3:48:00 AM7/20/07
to
Hi Victor Sudakov!

On Fri, 20 Jul 2007 02:51:48 +0000 (UTC); Victor Sudakov wrote about 'Re: ipfw and keep-state':

VS> То так. Однако простейший пример, который я брал из /etc/rc.firewall.

На то он и простейший... /* вообще говоря, в одном направлении не
4 раза, а 2, это я с обратным пакетом посчитал - но с разделенными
дивертами все равно в 2 раза меньше попаданий и соответственно
переключений контекста */

>> правило проверки стоит уже после
>> диверта, на прохождении в out через него пойдет пакет с уже
>> оттранслированным адресом. Следует разделить диверты на входе и выходе
>> и соответственно расположить динамические правила.
>> У меня это делается примерно вот так:
>> ipfw add divert natd ip from $graynet to any out xmit $extiface recv $intiface
>> ipfw add divert natd ip from any to $ext_nat_address in recv $extiface

VS> А где должен стоять keep-state относительно этих двух строчек?
VS> Впрочем, keep-state не обязательно, natd сам отсеет ненужный входящий
VS> трафик. Задача в другом - часть пакетов из приватной сети должна уйти
VS> в ipsec, часть пройти через NAT и далее попасть на разрешённый список
VS> хостов в Интернете, а остальной трафик должен быть запрещён.

Расположение зависит от того, что тебе нужно. Поскольку (отвечая
на другое письмо) ipfw, в отличие от той же циски, низкоуровневой
файрвол, в нем все такие вещи делаются руками. То есть нужно нарисовать
схему прохождения пакетов, вспомнить, как к ним применяются правила (в
т.ч. динамические). В виду той же низкоуровневости задачу можно решать
более чем одним способом, например можно сразу в divert рулить пакеты на
те сети, которые разрешены (остальное запрещено) без keep-state - пускай
состояния обруливает natd.

Alex Bakhtin

unread,
Jul 20, 2007, 4:14:39 AM7/20/07
to
>>>>> "VS" == Victor Sudakov writes:
Привет,

>> Вероятно при попытке установить соединение с хостом y.y.y.y нат заменяет в
>> исходящем пакете src_ip на некий публичный адрес, не входящий в подсеть
>> x.x.x.x/27, поэтому правило 220 не срабатывает.

VS> Так и есть. А как же теперь написать правило с keep-state, чтобы
VS> учесть NAT?

Используй не allow а skipto. Возможно, в сочетании с навешиванием
тега. У меня оно сделано как-то так. Конфиг не полный и до конца не
доработанный (нет времени), но практически все, что мне нужно -
работает. До выхода релиза семерки трогать ничего не буду, скорее всего.

Два аплинка - через ng0 и ng1. Тег навешивается в целях
connection-oriented полиси роутинга. Естественно, one pass выключено.


add 00050 divert 8768 ip from any to any in via ng0
add 00051 divert 8868 ip from any to any in via fxp0
add 00052 divert 8968 ip from any to any in via ng1

add 00100 check-state

add 10001 skipto 50000 tcp from not table(127) to me dst-port 22
setup keep-state
add 10031 skipto 50000 tag 1000 tcp from me to any setup keep-state out via
ng1
add 10032 skipto 50000 tag 2000 tcp from me to any setup keep-state out via
ng0
add 10033 skipto 50000 tcp from me to any setup keep-state


add 50008 skipto 54000 ip from any to any out via ste0
add 50009 skipto 54000 ip from any to any out via ste3
add 50009 skipto 54000 ip from any to any out via fxp1

add 50010 skipto 55000 ip from any to any tagged 1000
add 50011 skipto 55000 ip from table(20) to any
add 50020 skipto 56000 ip from any to any tagged 2000
add 50021 skipto 56000 ip from table(10) to any

add 50100 skipto 51000 ip from any to any out via ng0
add 50110 skipto 52000 ip from any to any out via fxp0
add 50120 skipto 53000 ip from any to any out via ng1

add 50900 allow ip from any to any in via ste0
add 50901 allow ip from any to any in via ste3
add 50901 allow ip from any to any in via fxp1

add 50996 allow ip from any to any in via ng1
add 50997 allow ip from any to any in via ng0
add 50998 allow ip from any to any in via fxp0

add 50999 skipto 65000 ip from any to any

add 51000 divert 8768 ip from any to any out via ng0
add 51001 allow ip from any to any

add 52010 divert 8868 ip from any to any out via fxp0
add 52011 allow ip from any to any

add 53000 divert 8968 ip from any to any out via ng1
add 53021 allow ip from any to any

add 54000 allow ip from any to any

add 55010 allow ip from any to any in via ng1
add 55020 divert 8968 ip from any to any
add 55030 fwd 192.168.2.2 ip from any to any

add 56010 allow ip from any to any in via ng0
add 56020 divert 8768 ip from any to any
add 56030 fwd 192.168.1.1 ip from any to any

add 64999 skipto 65000 ip from any to any

--
Best regards, Alex Bakhtin, CCIE #8439
AMT Group, Cisco Systems Gold Partner, http://www.amt.ru

Valentin Davydov

unread,
Jul 20, 2007, 4:32:43 AM7/20/07
to
> From: Vadim Goncharov <vadimn...@tpu.ru>
> Date: Fri, 20 Jul 2007 07:36:26 +0000 (UTC)

>
> >>> Обратный TCP трафик эффективнее разрешить правилом allow tcp from any to any
> >>> established. Динамические правила лучше создавать только для исходящих UDP.
> VS>> Вопрос был не как лучше сделать, а почему не работает данная
> VS>> конструкция. В ней есть ошибка? Возможно, какой-то неочевидный мне
> VS>> момент с порядком прохождения пакетов через ipfw?
> VS>> Насчёт established спорно. Пропускать пакет от кого попало только на
> VS>> том основании, что на нём есть ACK bit?
> >> Ну, допустим, что в обычных условиях так теоретически можно нахакерить.
> >> Но за NAT-то с чего? Так что в этом случае вполне можно.
> VS> Пожалуй ты прав, NAT сам по себе stateful, особенно с -deny_incoming.
>
>Я больше имел в виду то, что серые адреса - unrouteable. Левые пакеты на
>машины снаружи просто не могут прилететь (разве что из directly-attached
>к роутеру сети, но решается включением antispoof или verrevpath в ipfw).

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

Вал. Дав.

Vadim Guchenko

unread,
Jul 20, 2007, 6:00:51 AM7/20/07
to

>> VS> Насчёт established спорно. Пропускать пакет от кого попало только
>> на том основании, что на нём есть ACK bit?

>> А чем это хуже ситуации с динамическими правилами?
VS> Теоретически, может случиться ACK flood и firewall не спасет.

Попробую рассмотреть все варианты, связанные с TCP.

1. Предположим, некоторый сервер, имеющий реальный адрес, установил
TCP-соединение с удаленным хостом:

local_ip:local_port <-> remote_ip:remote_port

Если никакого файрвола нет, то сервер будет принимать все приходящие
TCP-пакеты. Однако в обработку, в рамках рассматриваемого соединения,
попадут только те пакеты, которые пришли с remote_ip:remote_port на
local_ip:local_port. Остальные пакеты будут отброшены TCP-стеком (либо
обработаны в рамках других активных соединений). После того, как проверка
адресов и портов прошла успешно, анализируются другие поля в TCP-пакете, в
частности sequence number. Если тупо флудить с различных адресов и портов
TCP-пакетами на local_ip:local_port, это ничего не даст, т.к. все пакеты
будут проигнорированы TCP-стеком. Для получения результата флудить нужно
так, чтобы в src_ip был remote_ip, а в src_port - remote_port. Но даже если
и это будет выполнено, встает вопрос об угадывании sequence number, времени
посылки пакета и т.д.

Предположим где-то на шлюзе настроен ipfw с правилом allow tcp from any to
any established. Т.е. он пропускает через себя все TCP-пакеты, кроме
запросов на установку соединения. Ситуация не меняется. Любые TCP-атаки,
включая флуд, будут прозрачно пропущены через ipfw и обработаны
(проигнорированы) TCP-стеком на локальном сервере.

Предположим на шлюзе настроен ipfw, создающий на каждое исходящее
TCP-соединение динамическое правило. Соответственно, ipfw пропустит внутрь
сети только TCP-пакеты вида:

remote_ip:remote_port -> local_ip:local_port

Разница с предыдущими двумя случаями в том, что простой флуд не дойдет до
целевого сервера, а будет отброшен еще на шлюзе с ipfw. Однако
целенаправленная атака, когда подменяются src_ip и src_port, все равно
пройдет через ipfw и дойдет до сервера назначения.

2. Теперь предположим, что сервер, который установил TCP-соединение с
удаленным хостом, имеет серый адрес и находится за натом. Для простоты будем
считать, что нат не меняет номера портов - только ip-адреса:

local_ip:local_port <-> [local_ip <- nat -> public_ip] <->
remote_ip:remote_port

TCP-пакеты в рамках установленного соединения будут приходить снаружи на нат
в виде:

remote_ip:remote_port -> public_ip:local_port

Только у таких входящих пакетов нат будет заменять public_ip на local_ip и
соответветственно только такие пакеты дойдут до нужного сервера внутри сети
в соответствии с роутингом. Все остальные пакеты, у которых хотя бы один из
четырех элементов будет другим, будут проигнорированы натом (возвращены
после диверта неизмененными). В соответствии с роутингом они осядут на
шлюзе, т.е. до целевого сервера не дойдут. Иными словами, обычный флуд будет
отброшен на шлюзе с натом. Целенаправленная же атака с подмененными src_ip и
src_port опять-таки пройдет через нат.

Выводы. Если имеет место спуфинг и кто-то целенаправленно пытается
вклиниться в TCP-соединение, то ни один из способов не поможет - все они
пропустят пакет до сервера назначения. И уже TCP-стек на сервере назначения
будет решать отбрасывать или принимать полученный пакет. Разница во всех
описанных способах только в том, где будет оседать TCP-флуд с разных
адресов - на целевом сервере или на шлюзе. Сам по себе флуд не представляет
угрозы для безопасности, он может лишь забить сетевые каналы и привести к
отказу в обслуживании. Конкретно TCP-флуд, попадающий под правило
established, к отказу в обслуживании приведет вряд ли, т.к. поддельные
TCP-пакеты будут отбрасываться TCP-стеком еще не доходя до приложения. Далее
можно рассуждать так. Если сервер имеет серый адрес, т.е. на шлюзе есть нат,
то никакого файрвола для пакетов, которые обрабатывает нат, не надо вообще.
Все функции по защите выполняет сам нат. Если же сервер имеет реальный
адрес, то видимо он принимает какие-то входящие соединения извне. А это
значит, что как минимум один порт на ipfw шлюза должен быть открыт для этого
сервера. Т.е. через этот порт можно честно флудить пакетами без всяких
заморочек со спуфингом, и эти пакеты дойдут до сервера назначения и даже
будут приняты приложением, т.е. DOS обеспечен. В этом случае делать
keep-state для TCP смысла нет. Все равно от флуда не спасет. Эффективнее
пропустить весь established TCP-трафик. А если машина не принимает никаких
соединений извне, но все же имеет реальный адрес, наверное это как раз тот
случай, когда реальный адрес берут для того, чтобы иметь полноценный выход в
инет, не ограниченный ни натом, ни файрволом. Т.е. преполагается, что такая
машина готова принимать извне любые пакеты, пришедшие на ее адрес. В том
числе флуд. Таким образом, я не вижу преимуществ использования keep-state
для исходящих TCP-пакетов. А вот для исходящих UDP без keep-state уже никак.

Почему allow tcp from any to any established эффективнее чем allow tcp from
any to any keep-state? Потому что keep-state требует памяти для создания
динамических правил. В случае большого трафика - много памяти. Этой памяти
может внезапно не хватить и часть пакетов потеряется. Кроме того, нужно
время для просмотра таблицы динамических правил.

--
Best regards, Vadim.

Vadim Goncharov

unread,
Jul 21, 2007, 8:15:44 AM7/21/07
to
Hi Vadim Guchenko!

On Fri, 20 Jul 2007 10:00:51 +0000 (UTC); Vadim Guchenko wrote about 'ipfw and keep-state':


VS>> Насчёт established спорно. Пропускать пакет от кого попало только
>>> на том основании, что на нём есть ACK bit?
>>> А чем это хуже ситуации с динамическими правилами?
VS>> Теоретически, может случиться ACK flood и firewall не спасет.

VG> Попробую рассмотреть все варианты, связанные с TCP.
[...]
VG> Почему allow tcp from any to any established эффективнее чем allow tcp from
VG> any to any keep-state? Потому что keep-state требует памяти для создания
VG> динамических правил. В случае большого трафика - много памяти. Этой памяти
VG> может внезапно не хватить и часть пакетов потеряется. Кроме того, нужно
VG> время для просмотра таблицы динамических правил.

Это всё варианты DoS-атак, тут все верно. Возможная дырявость
established заключается в другом - если за шлюзом сеть с реальными
адресами и в ней есть инсайдер, он может организовать обход файрвола,
обойдясь без начального пакета с SYN, так что все подпадут под
established. Но для случая с NATом этот вариант опять-таки нереален.

Vadim Goncharov

unread,
Jul 21, 2007, 8:57:52 AM7/21/07
to
Hi Valentin Davydov!

On Fri, 20 Jul 2007 08:32:43 +0000 (UTC); Valentin Davydov wrote about 'Re: ipfw and keep-state':

>>>> Обратный TCP трафик эффективнее разрешить правилом allow tcp from any to any
>>>> established. Динамические правила лучше создавать только для исходящих UDP.
VS>>> Вопрос был не как лучше сделать, а почему не работает данная
VS>>> конструкция. В ней есть ошибка? Возможно, какой-то неочевидный мне
VS>>> момент с порядком прохождения пакетов через ipfw?
VS>>> Насчёт established спорно. Пропускать пакет от кого попало только на
VS>>> том основании, что на нём есть ACK bit?
>>> Ну, допустим, что в обычных условиях так теоретически можно нахакерить.
>>> Но за NAT-то с чего? Так что в этом случае вполне можно.
VS>> Пожалуй ты прав, NAT сам по себе stateful, особенно с -deny_incoming.
>>Я больше имел в виду то, что серые адреса - unrouteable. Левые пакеты на
>>машины снаружи просто не могут прилететь (разве что из directly-attached
>>к роутеру сети, но решается включением antispoof или verrevpath в ipfw).

VD> Попробуй запустить трэйс на серый адрес. У меня с одного из роутеров четыре
VD> живых хопа было видно, каждый следующий дефолт для предыдущего.

Кое-где такое бывает, да.

Victor Sudakov

unread,
Jul 23, 2007, 1:05:40 AM7/23/07
to
Alex Bakhtin wrote:

> >> Вероятно при попытке установить соединение с хостом y.y.y.y нат заменяет в
> >> исходящем пакете src_ip на некий публичный адрес, не входящий в подсеть
> >> x.x.x.x/27, поэтому правило 220 не срабатывает.

> VS> Так и есть. А как же теперь написать правило с keep-state, чтобы
> VS> учесть NAT?

> Используй не allow а skipto. Возможно, в сочетании с навешиванием
> тега. У меня оно сделано как-то так. Конфиг не полный и до конца не
> доработанный (нет времени), но практически все, что мне нужно -
> работает. До выхода релиза семерки трогать ничего не буду, скорее всего.

Посмотрел пример. Очень похоже на Basic двадцатилетней давности :(
Такая же неудобочитаемая мешанина из GOTO, в которой очень легко
запутаться и ошибиться. Это упрёк, конечно, не тебе лично, а
дизайнерам ipfw.

> Два аплинка - через ng0 и ng1. Тег навешивается в целях
> connection-oriented полиси роутинга. Естественно, one pass выключено.

Не совсем понял, при чём тут one pass. Он же на dummynet влияет, а
никаких pipe или queue я в твоём примере не нашёл.

Vadim Goncharov

unread,
Jul 23, 2007, 2:26:49 AM7/23/07
to
Hi Victor Sudakov!

On Mon, 23 Jul 2007 05:05:40 +0000 (UTC); Victor Sudakov wrote about 'Re: ipfw and keep-state':

>>> Вероятно при попытке установить соединение с хостом y.y.y.y нат заменяет в
>>> исходящем пакете src_ip на некий публичный адрес, не входящий в подсеть
>>> x.x.x.x/27, поэтому правило 220 не срабатывает.
VS>> Так и есть. А как же теперь написать правило с keep-state, чтобы
VS>> учесть NAT?
>> Используй не allow а skipto. Возможно, в сочетании с навешиванием
>> тега. У меня оно сделано как-то так. Конфиг не полный и до конца не
>> доработанный (нет времени), но практически все, что мне нужно -
>> работает. До выхода релиза семерки трогать ничего не буду, скорее всего.

VS> Посмотрел пример. Очень похоже на Basic двадцатилетней давности :(
VS> Такая же неудобочитаемая мешанина из GOTO, в которой очень легко
VS> запутаться и ошибиться. Это упрёк, конечно, не тебе лично, а
VS> дизайнерам ipfw.

То, что ipfw низкоуровневой - его плюс (и минус одновременно). Хочешь
простоты - возьми pf, большинство задач он решит красиво и элегантно.

>> Два аплинка - через ng0 и ng1. Тег навешивается в целях
>> connection-oriented полиси роутинга. Естественно, one pass выключено.

VS> Не совсем понял, при чём тут one pass. Он же на dummynet влияет, а
VS> никаких pipe или queue я в твоём примере не нашёл.

Не только, еще и на netgraph/ngtee влияет. Вероятно, был приведен не
весь конфиг либо стоит на всякий случай заранее - "щас допишу".

Vadim Guchenko

unread,
Jul 23, 2007, 4:54:04 AM7/23/07
to

VS> Посмотрел пример. Очень похоже на Basic двадцатилетней давности :(
VS> Такая же неудобочитаемая мешанина из GOTO, в которой очень легко
VS> запутаться и ошибиться. Это упрёк, конечно, не тебе лично, а
VS> дизайнерам ipfw.

Исторически так сложилось, что правила файрвола в rc.firewall написаны в плохом и труднопонимаемом стиле: входящие и исходящие пакеты проходят один и тот же набор правил. Многие используют этот скрипт как образец для написания собственного набора правил и
наступают на одни и те же грабли. Как минимум, с натом. На самом деле ipfw очень удобен, если писать список правил как некую программу - с разбиением на мелкие подпрограммы (блоки) и добавлением комментариев. При этом надо руководствоваться рядом
соглашений:

1. Весь трафик первым делом делится на входящий и исходящий. Каждый вид трафика обрабатывается в отдельном блоке. В качестве еще одного блока можно выделить трафик через интерфейс lo0. Слова in и out после первоначального разделения трафика не
используются.
2. Входящий трафик делится на а) трафик, адресованный данному серверу; б) броадкасты; в) мультикасты; г) трафик, идущий транзитом. Каждый из видов трафика обрабатывается в отдельном блоке. Слово me после разделения трафика не используется.
3. Ветвление на блоки происходит по ip-адресам. Имена интерфейсов используются по возможности как можно реже и только тогда, когда без них не обойтись. В частности, при написании правил антиспуфинга. При использовании имен интерфейсов крайне не
рекомендуется использовать слово via. В зависимости от блока (входящий или исходящий трафик) рекомендуется использовать слова xmit или recv. Это повышает читабельность.
4. Все строки с правилами нумеруются (там где это допустимо). Нумерация строго возрастающая. Рекомендуемый шаг между соседними номерами 100.
5. Блок занимает строго фиксированный диапазон номеров строк ipfw. Номер строки, с которой начинается блок, указывается в комментарии в начале этого блока. Переход на блок происходит только на его начало. Переход в середину блока недопустим.
6. Блок всегда заканчивается строкой allow ip from any to any или deny ip from any to any. Исключение составляет ситуация, когда один блок должен выполняться следом за другим. Даже если блок пустой (например, броадкасты или мультикасты не используются),
все равно лучше поместить в него это единственное правило, чем удалять блок целиком. Возможно в будущем туда что-нибудь допишется.

Пример я как-то уже приводил несколько лет назад. Приведу еще раз для трех разных серверов. Макросы, начинающиеся с %, заменятся на блоки ip-адресов. На всех серверах дефолтное 65535 правило: allow ip from any to any.

Правила на центральном роутере/шлюзе в инет:

###############################################################################
###############################################################################
###############################################################################

#!/bin/sh -e

fwcmd="echo"

# Интерфейсы, подключенные к Интернету
xmit_iface_inet="{ xmit fxp1 or xmit fxp2 }"
recv_iface_inet="{ recv fxp1 or recv fxp2 }"

# Ограничение количества ping-пакетов, уходящих на аплинка
$fwcmd pipe 10 config bw 5Kbit/s

###############################################################################
## Разделение трафика в зависимости от направления (нумерация с 100)
###############################################################################

# Трафик через интерфейс lo0
$fwcmd add 100 allow ip from any to any via lo0

# Исходящий трафик
$fwcmd add 200 skipto 30000 ip from any to any out

###############################################################################
## Входящий трафик (нумерация с 500)
###############################################################################

# Съем трафика для статистики
$fwcmd add 500 divert 18000 ip from any to any $recv_iface_inet

# NAT-трансляция входящих пакетов
$fwcmd add 700 divert 8668 ip from any to %ip.nat $recv_iface_inet

##-----------------------------------------------------------------------------
## Антиспуфинг (нумерация с 1000)
##-----------------------------------------------------------------------------

# Интерфейсы Интернета
$fwcmd add 1000 deny log ip from %global.internal to any $recv_iface_inet

##-----------------------------------------------------------------------------
## Разделение трафика в зависимости от получателя пакета (нумерация с 5000)
##-----------------------------------------------------------------------------

# Трафик, адресованный серверу
$fwcmd add 5000 skipto 10000 ip from any to me

# Броадкасты
$fwcmd add 5100 skipto 20000 ip from any to 255.255.255.255

# Мультикасты
$fwcmd add 5200 skipto 25000 ip from any to 224.0.0.0/4

##-----------------------------------------------------------------------------
## Трафик, идущий транзитом (нумерация с 6000)
##-----------------------------------------------------------------------------

# Запрещаем трафик на закрытые адреса магистрали
$fwcmd add 6000 deny log ip from any to %global.backbone.private

# Разрешаем остальной трафик
$fwcmd add 6300 allow ip from any to any

##-----------------------------------------------------------------------------
## Трафик, адресованный серверу (нумерация с 10000)
##-----------------------------------------------------------------------------

# Разрешаем установленные TCP-соединения
$fwcmd add 10000 allow tcp from any to any established

# Разрешаем фрагменты IP-пакетов
$fwcmd add 10100 allow ip from any to any frag

# Разрешаем пакеты, удовлетворяющие динамическим правилам
$fwcmd add 10200 check-state

# Разрешаем OSPF-пакеты
$fwcmd add 10300 allow ospf from %global.backbone to any

# Разрешаем GRE-пакеты
$fwcmd add 10400 allow gre from any to any

##-----------------------------------------------------------------------------
## Службы сервера (нумерация с 12000)
##-----------------------------------------------------------------------------

# SSH
$fwcmd add 12000 deny tcp from %deny.ssh to %ip.ssh 22
$fwcmd add 12100 allow tcp from %allow.ssh to %ip.ssh 22

# BGP
$fwcmd add 12200 deny tcp from %deny.bgp to %ip.bgp 179
$fwcmd add 12300 allow tcp from %allow.bgp to %ip.bgp 179

# SNMP
$fwcmd add 12400 allow udp from %allow.snmp to %ip.snmp 161,1161

##-----------------------------------------------------------------------------
## Завершающие правила для трафика, адресованного серверу (нумерация с 18000)
##-----------------------------------------------------------------------------

# Разрешаем ICMP-пакеты
$fwcmd add 18000 allow icmp from any to any

# Разрешаем работу traceroute
$fwcmd add 18100 unreach port udp from any to any 33434-33584

# Запрещаем соединения на 113 порт (ident)
$fwcmd add 18200 reset tcp from any to any 113

# Запрещаем соединения на 1080 порт (socks check)
$fwcmd add 18300 reset tcp from any to any 1080

# Запрещаем остальной трафик
$fwcmd add 18400 deny log ip from any to any

##-----------------------------------------------------------------------------
## Броадкасты (нумерация с 20000)
##-----------------------------------------------------------------------------

# Разрешаем SNMP trap'ы от ИБП
$fwcmd add 20000 allow udp from %global.backbone to any 162

# Разрешаем NTP-пакеты
$fwcmd add 20100 allow udp from %global.backbone to %global.backbone.broadcast 123

# Запрещаем остальной трафик
$fwcmd add 20200 deny log ip from any to any

##-----------------------------------------------------------------------------
## Мультикасты (нумерация с 25000)
##-----------------------------------------------------------------------------

# Разрешаем OSPF-пакеты
$fwcmd add 25000 allow ospf from %global.backbone to 224.0.0.0/24{5,6}

# Разрешаем общие IGMP и DVMRP-пакеты
$fwcmd add 25100 allow igmp from %global.backbone to 224.0.0.0/24{1,2,4}
$fwcmd add 25200 allow igmp from %ip.link.iskranet-gw to 224.0.0.0/24{1,2}

# Разрешаем трафик TVoIP
$fwcmd add 25300 allow ip from %ip.ext.tvoip to 224.2.153.173

# Запрещаем остальной трафик
$fwcmd add 25400 deny log ip from any to any

###############################################################################
## Исходящий трафик (нумерация с 30000)
###############################################################################

# Запрещаем отправку пакетов, предназначенных для внутрисетевых адресов,
# на шлюз по умолчанию
$fwcmd add 30000 deny ip from any to %global.internal $xmit_iface_inet

# Запрещаем отправку в Интернет пакетов Netbios
$fwcmd add 30100 deny tcp from any to any 135,139,445 $xmit_iface_inet

# Запрещаем отправку пакетов в Интернет для клиентов, которые отключены
# от Интернета
$fwcmd add 30200 skipto 30350 ip from %allow.internet to any $xmit_iface_inet
$fwcmd add 30300 deny ip from any to any $xmit_iface_inet

# Шейпинг ping-пакетов
$fwcmd add 30350 skipto 30400 icmp from %group.ping-shaping to any icmptypes 8 $xmit_iface_inet
$fwcmd add 30351 pipe 10 icmp from any to any icmptypes 8 $xmit_iface_inet

# Съем трафика для статистики
$fwcmd add 30400 divert 18001 ip from any to any $xmit_iface_inet

# NAT-трансляция исходящих пакетов
$fwcmd add 30800 divert 8668 ip from 192.168.0.0/16 to any $xmit_iface_inet
#$fwcmd add 30900 allow ip from %ip.nat to any $xmit_iface_inet

# Направляем пакеты в нужные интерфейсы аплинков в зависимости от их src-адреса
$fwcmd add 31000 fwd %ip.link.krastelecom-gw ip from %ip.link.krastelecom to any $xmit_iface_inet
$fwcmd add 31100 fwd %ip.link.iskranet-gw ip from %ip.link.iskranet to any $xmit_iface_inet

# Динамическое правило для доступа с данного сервера к внешним службам по UDP
$fwcmd add 31200 allow udp from me to any keep-state

##-----------------------------------------------------------------------------
## Аккаунтинг трафика (нумерация с 40000)
##-----------------------------------------------------------------------------

# Трафик Интернета
$fwcmd add 40000 skipto 40200 ip from %global.internal to %group.accounting
$fwcmd add 40100 divert 17000 ip from any to %group.accounting

###############################################################################
###############################################################################
###############################################################################


Правила на сервере доступа:

###############################################################################
###############################################################################
###############################################################################

#!/bin/sh -e

fwcmd="echo"

# Интерфейс, подключенный к клиентскому сегменту
iface_clients=fxp0

# Интерфейсы VPN
iface_vpns=ng*

###############################################################################
## Разделение трафика в зависимости от направления (нумерация с 100)
###############################################################################

# Трафик через интерфейс lo0
$fwcmd add 100 allow ip from any to any via lo0

# Исходящий трафик
$fwcmd add 200 skipto 30000 ip from any to any out

###############################################################################
## Входящий трафик (нумерация с 500)
###############################################################################

# Открываем доступ к DHCP-серверу с незарегистрированных адресов, запрещаем
# с них любой другой трафик
$fwcmd add 500 allow udp from %clients.unreg to %srv.dhcp 67
$fwcmd add 600 allow udp from %clients.unreg to 255.255.255.255 67
$fwcmd add 700 deny ip from %clients.unreg to any

##-----------------------------------------------------------------------------
## Антиспуфинг (нумерация с 1000)
##-----------------------------------------------------------------------------

# Интерфейс клиентов
$fwcmd add 1000 skipto 5000 ip from 0.0.0.0 to any recv $iface_clients
$fwcmd add 1100 skipto 5000 ip from %clients to any recv $iface_clients
$fwcmd add 1200 deny log ip from any to any recv $iface_clients

# Интерфейсы VPN
$fwcmd add 1300 skipto 5000 ip from %clients to any recv $iface_vpns
$fwcmd add 1400 skipto 5000 ip from any to any verrevpath recv $iface_vpns
$fwcmd add 1500 deny log ip from any to any recv $iface_vpns

##-----------------------------------------------------------------------------
## Разделение трафика в зависимости от получателя пакета (нумерация с 5000)
##-----------------------------------------------------------------------------

# Трафик, адресованный серверу
$fwcmd add 5000 skipto 10000 ip from any to me

# Броадкасты
$fwcmd add 5100 skipto 20000 ip from any to 255.255.255.255
$fwcmd add 5200 skipto 20000 ip from any to %global.backbone.broadcast
$fwcmd add 5300 skipto 20000 ip from any to %clients.broadcast

# Мультикасты
$fwcmd add 5400 skipto 25000 ip from any to 224.0.0.0/4

##-----------------------------------------------------------------------------
## Трафик, идущий транзитом (нумерация с 6000)
##-----------------------------------------------------------------------------

# Запрещаем трафик на закрытые адреса магистрали
$fwcmd add 6000 deny log ip from any to %global.backbone.private

# Разрешаем любой трафик, идущий c VPN-адресов клиентов, которым открыт доступ
# к услугам сети, и обратно
$fwcmd add 6100 allow ip from %access.allow to any
$fwcmd add 6200 allow ip from any to %access.allow

# Разрешаем трафик, идущий от клиентов на DNS-резолвер и обратно
$fwcmd add 6300 allow ip from any to %global.srv.resolver
$fwcmd add 6400 allow ip from %global.srv.resolver to any

# Разрешаем трафик, идущий от клиентов на веб-сервер сети и обратно
$fwcmd add 6500 allow ip from any to %global.srv.http
$fwcmd add 6600 allow ip from %global.srv.http to any

# Разрешаем эхо-запросы, идущие на локальные адреса клиентов, и эхо-ответы
# c этих адресов
$fwcmd add 6700 allow icmp from any to %clients icmptypes 8
$fwcmd add 6800 allow icmp from %clients to any icmptypes 0

# Запрещаем остальной трафик
$fwcmd add 6900 deny log ip from any to any

##-----------------------------------------------------------------------------
## Трафик, адресованный серверу (нумерация с 10000)
##-----------------------------------------------------------------------------

# Разрешаем установленные TCP-соединения
$fwcmd add 10000 allow tcp from any to any established

# Разрешаем фрагменты IP-пакетов
$fwcmd add 10100 allow ip from any to any frag

# Разрешаем пакеты, удовлетворяющие динамическим правилам
$fwcmd add 10200 check-state

# Разрешаем OSPF-пакеты
$fwcmd add 10300 allow ospf from %global.backbone to any

# Разрешаем GRE-пакеты
$fwcmd add 10400 allow gre from any to any

##-----------------------------------------------------------------------------
## Службы сервера (нумерация с 12000)
##-----------------------------------------------------------------------------

# SSH
$fwcmd add 12000 allow tcp from %srv.ssh.allow to %srv.ssh 22

# DHCP
$fwcmd add 12100 allow udp from %srv.dhcp.allow to %srv.dhcp 67

# PPTP
$fwcmd add 12200 allow tcp from %srv.pptp.allow to %srv.pptp 1723

# SNMP
$fwcmd add 12300 allow udp from %srv.snmp.allow to %srv.snmp 161,1161

##-----------------------------------------------------------------------------
## Завершающие правила для трафика, адресованного серверу (нумерация с 18000)
##-----------------------------------------------------------------------------

# Разрешаем ICMP-пакеты
$fwcmd add 18000 allow icmp from any to any

# Разрешаем работу traceroute
$fwcmd add 18100 unreach port udp from any to any 33434-33584

# Запрещаем соединения на 80 порт (samba)
$fwcmd add 18200 reset tcp from any to any 80

# Запрещаем соединения на 113 порт (ident)
$fwcmd add 18300 reset tcp from any to any 113

# Запрещаем соединения на 1080 порт (socks check)
$fwcmd add 18400 reset tcp from any to any 1080

# Запрещаем остальной трафик
$fwcmd add 18500 deny log ip from any to any

##-----------------------------------------------------------------------------
## Броадкасты (нумерация с 20000)
##-----------------------------------------------------------------------------

# Разрешаем SNMP trap'ы от ИБП
$fwcmd add 20000 allow udp from %global.backbone to any 162

# Разрешаем NTP-пакеты
$fwcmd add 20100 allow udp from %global.backbone to %global.backbone.broadcast 123

# Разрешаем поиск DHCP-сервера
$fwcmd add 20200 allow udp from %srv.dhcp.allow to any 67

# Запрещаем остальной трафик
$fwcmd add 20300 deny log ip from any to any

##-----------------------------------------------------------------------------
## Мультикасты (нумерация с 25000)
##-----------------------------------------------------------------------------

# Разрешаем OSPF-пакеты
$fwcmd add 25000 allow ospf from %global.backbone to 224.0.0.0/24{5,6}

# Разрешаем общие IGMP и DVMRP-пакеты
$fwcmd add 25100 allow igmp from %global.backbone to 224.0.0.0/24{1,2,4}
$fwcmd add 25200 allow igmp from %clients to 224.0.0.0/24{1,2}

# Разрешаем подписку на группы TVoIP
$fwcmd add 25300 allow igmp from %clients to %global.srv.tvoip.groups

# Разрешаем трафик TVoIP
$fwcmd add 25400 allow ip from %global.srv.tvoip to %global.srv.tvoip.groups

# Запрещаем остальной трафик
$fwcmd add 25500 deny log ip from any to any

###############################################################################
## Исходящий трафик (нумерация с 30000)
###############################################################################

# Динамическое правило для доступа с данного сервера к внешним службам по UDP
$fwcmd add 30000 allow udp from me to any keep-state

###############################################################################
###############################################################################
###############################################################################


Правила на сервере служб:

###############################################################################
###############################################################################
###############################################################################

#!/bin/sh -e

fwcmd="echo"

###############################################################################
## Разделение трафика в зависимости от направления (нумерация с 100)
###############################################################################

# Трафик через интерфейс lo0
$fwcmd add 100 allow ip from any to any via lo0

# Исходящий трафик
$fwcmd add 200 skipto 30000 ip from any to any out

###############################################################################
## Входящий трафик (нумерация с 1000)
###############################################################################

##-----------------------------------------------------------------------------
## Разделение трафика в зависимости от получателя пакета (нумерация с 5000)
##-----------------------------------------------------------------------------

# Трафик, адресованный серверу
$fwcmd add 5000 skipto 10000 ip from any to me

# Броадкасты
$fwcmd add 5100 skipto 20000 ip from any to 255.255.255.255
$fwcmd add 5150 skipto 20000 ip from any to %group.backbone_broadcast

# Мультикасты
$fwcmd add 5200 skipto 25000 ip from any to 224.0.0.0/4

##-----------------------------------------------------------------------------
## Трафик, идущий транзитом (нумерация с 6000)
##-----------------------------------------------------------------------------

# Запрещаем весь трафик
$fwcmd add 6000 deny log ip from any to any

##-----------------------------------------------------------------------------
## Трафик, адресованный серверу (нумерация с 10000)
##-----------------------------------------------------------------------------

# Преобразовываем запросы к DNS-резолверу
$fwcmd add 10000 divert 8669 ip from %allow.resolver_internet to %ip.resolver

# Разрешаем установленные TCP-соединения
$fwcmd add 10100 allow tcp from any to any established

# Разрешаем фрагменты IP-пакетов
$fwcmd add 10200 allow ip from any to any frag

# Разрешаем пакеты, удовлетворяющие динамическим правилам
$fwcmd add 10300 check-state

# Разрешаем OSPF-пакеты
$fwcmd add 10400 allow ospf from %group.backbone to any

##-----------------------------------------------------------------------------
## Службы сервера (нумерация с 12000)
##-----------------------------------------------------------------------------

# SSH
$fwcmd add 12000 deny tcp from %deny.ssh to %ip.ssh 22
$fwcmd add 12100 allow tcp from %allow.ssh to %ip.ssh 22

# DNS-резолвер
$fwcmd add 12200 deny { tcp or udp } from %deny.resolver to %ip.resolver 53
$fwcmd add 12300 allow { tcp or udp } from %allow.resolver to %ip.resolver 53

# DNS-сервер
$fwcmd add 12400 deny { tcp or udp } from %deny.dns to %ip.dns 53
$fwcmd add 12500 allow { tcp or udp } from %allow.dns to %ip.dns 53

# DNS-кэш
$fwcmd add 12600 deny { tcp or udp } from %deny.dnscache to %ip.dnscache 53
$fwcmd add 12700 allow { tcp or udp } from %allow.dnscache to %ip.dnscache 53

# NTP-сервер
$fwcmd add 12800 deny udp from %deny.ntp to %ip.ntp 123
$fwcmd add 12900 allow udp from %allow.ntp to %ip.ntp 123

# IRC
$fwcmd add 13000 deny tcp from %deny.irc to %ip.irc 6667-6669
$fwcmd add 13100 allow tcp from %allow.irc to %ip.irc 6667-6669
$fwcmd add 13200 deny icmp from any to %ip.irc icmptypes 8

# HTTP
$fwcmd add 13700 deny tcp from %deny.http to %ip.http 80,443
$fwcmd add 13800 allow tcp from %allow.http to %ip.http 80,443

# SMTP
$fwcmd add 13900 deny tcp from %deny.smtp to %ip.smtp 25
$fwcmd add 14000 allow tcp from %allow.smtp to %ip.smtp 25
$fwcmd add 14100 deny tcp from %group.internal to %ip.smtp 25
$fwcmd add 14200 allow tcp from any to %ip.smtp 25

# POP
$fwcmd add 14300 deny tcp from %deny.pop to %ip.pop 110
$fwcmd add 14400 allow tcp from %allow.pop to %ip.pop 110

# SNMP
$fwcmd add 14500 allow udp from %allow.snmp to %ip.snmp 161,1161

##-----------------------------------------------------------------------------
## Завершающие правила для трафика, адресованного серверу (нумерация с 18000)
##-----------------------------------------------------------------------------

# Разрешаем ICMP-пакеты
$fwcmd add 18000 allow icmp from any to any

# Разрешаем работу traceroute
$fwcmd add 18100 unreach port udp from any to any 33434-33584

# Запрещаем соединения на 113 порт (ident)
$fwcmd add 18200 reset tcp from any to any 113

# Запрещаем соединения на 1080 порт (socks check)
$fwcmd add 18300 reset tcp from any to any 1080

# Запрещаем остальной трафик
$fwcmd add 18400 deny log ip from any to any

##-----------------------------------------------------------------------------
## Броадкасты (нумерация с 20000)
##-----------------------------------------------------------------------------

# Разрешаем SNMP trap'ы от ИБП
$fwcmd add 20000 allow udp from %group.backbone to any 162

# Запрещаем остальной трафик
$fwcmd add 20100 deny log ip from any to any

##-----------------------------------------------------------------------------
## Мультикасты (нумерация с 25000)
##-----------------------------------------------------------------------------

# Разрешаем OSPF-пакеты
$fwcmd add 25000 allow ospf from %group.backbone to 224.0.0.0/24{5,6}

# Запрещаем остальной трафик
$fwcmd add 25100 deny log ip from any to any

###############################################################################
## Исходящий трафик (нумерация с 30000)
###############################################################################

# Преобразовываем ответы DNS-резолвера
$fwcmd add 30000 divert 8669 ip from %ip.dnscache to %allow.resolver_internet

# Динамическое правило для доступа с данного сервера к внешним службам по UDP
$fwcmd add 30100 allow udp from me to any keep-state

##-----------------------------------------------------------------------------
## Аккаунтинг трафика (нумерация с 40000)
##-----------------------------------------------------------------------------

# Трафик почтового сервера (POP)
$fwcmd add 40000 divert 17000 tcp from %ip.pop to %group.accounting

###############################################################################
###############################################################################
###############################################################################


--
Best regards, Vadim.

Vadim Guchenko

unread,
Jul 23, 2007, 4:54:34 AM7/23/07
to

VG> Это всё варианты DoS-атак, тут все верно. Возможная дырявость
VG> established заключается в другом - если за шлюзом сеть с реальными
VG> адресами и в ней есть инсайдер, он может организовать обход файрвола,
VG> обойдясь без начального пакета с SYN, так что все подпадут под
VG> established.

Не понимаю. Можно пример?


--
Best regards, Vadim.

Alex Bakhtin

unread,
Jul 23, 2007, 5:49:07 AM7/23/07
to
>>>>> "VS" == Victor Sudakov writes:
Привет,

>> >> Вероятно при попытке установить соединение с хостом y.y.y.y нат заменяет в

>> >> исходящем пакете src_ip на некий публичный адрес, не входящий в подсеть
>> >> x.x.x.x/27, поэтому правило 220 не срабатывает.

VS> Так и есть. А как же теперь написать правило с keep-state, чтобы
VS> учесть NAT?

>> Используй не allow а skipto. Возможно, в сочетании с навешиванием
>> тега. У меня оно сделано как-то так. Конфиг не полный и до конца не
>> доработанный (нет времени), но практически все, что мне нужно -
>> работает. До выхода релиза семерки трогать ничего не буду, скорее всего.

VS> Посмотрел пример. Очень похоже на Basic двадцатилетней давности :(
VS> Такая же неудобочитаемая мешанина из GOTO, в которой очень легко
VS> запутаться и ошибиться. Это упрёк, конечно, не тебе лично, а
VS> дизайнерам ipfw.

А что делать? Мне надо было слепить что-то с полиси-роутингом и natом
на 2 канала. Уж что слепилось. Я, честно говоря, думал на предмет несколько
лучше структурировать - но до этого не доходят руки, т.к. оно и так
работает. Может быть, когда-нибудь...

>> Два аплинка - через ng0 и ng1. Тег навешивается в целях
>> connection-oriented полиси роутинга. Естественно, one pass выключено.

VS> Не совсем понял, при чём тут one pass. Он же на dummynet влияет, а
VS> никаких pipe или queue я в твоём примере не нашёл.

Ну, они у меня где-то были. Я, видимо, плохо читал доку и мне
казалось, что это и на divert влияет. Ну, раз не влияет - значит хорошо:)

Victor Sudakov

unread,
Jul 24, 2007, 2:31:35 AM7/24/07
to
Vadim Goncharov wrote:

> >>> Вероятно при попытке установить соединение с хостом y.y.y.y нат заменяет в
> >>> исходящем пакете src_ip на некий публичный адрес, не входящий в подсеть
> >>> x.x.x.x/27, поэтому правило 220 не срабатывает.
> VS>> Так и есть. А как же теперь написать правило с keep-state, чтобы
> VS>> учесть NAT?
> >> Используй не allow а skipto. Возможно, в сочетании с навешиванием
> >> тега. У меня оно сделано как-то так. Конфиг не полный и до конца не
> >> доработанный (нет времени), но практически все, что мне нужно -
> >> работает. До выхода релиза семерки трогать ничего не буду, скорее всего.
> VS> Посмотрел пример. Очень похоже на Basic двадцатилетней давности :(
> VS> Такая же неудобочитаемая мешанина из GOTO, в которой очень легко
> VS> запутаться и ошибиться. Это упрёк, конечно, не тебе лично, а
> VS> дизайнерам ipfw.

> То, что ipfw низкоуровневой - его плюс (и минус одновременно). Хочешь
> простоты - возьми pf, большинство задач он решит красиво и элегантно.

Попробую.

Вообще если бы divert не путался под ногами, то на ipfw можно делать
вполне читабельные конструкции. Особенно если сразу придерживаться
принципа - каждое правило обязательно должно содержать привязку к
интерфейсу и указание на направление трафика (по аналогии с цискиными
"ip access-group").

Хотя, dummynet наверное будет мешать не меньше divert.

Andrew Filonov

unread,
Jul 24, 2007, 7:19:44 AM7/24/07
to
>>>>> "VS" == Victor Sudakov writes:

VS> Вообще если бы divert не путался под ногами, то на ipfw можно
VS> делать вполне читабельные конструкции. Особенно если сразу
VS> придерживаться принципа - каждое правило обязательно должно
VS> содержать привязку к интерфейсу и указание на направление трафика
VS> (по аналогии с цискиными "ip access-group").
Пользуй pfnat и проблем с divert'ом не будет.

--
Andrew E. Filonov
If you do something right once, someone will ask
you to do it again.

Andrew Alcheyev

unread,
Jul 24, 2007, 9:21:00 AM7/24/07
to
Здравствуйте, Andrew.

Tuesday July 24 2007 at 15:19, Andrew Filonov wrote to Victor Sudakov:

AF> Пользуй pfnat и проблем с divert'ом не будет.

ага, один ftp-proxy у pfnat'а чего стоит.

поскольку с помощью ipfw и netgraph можно реализовать практически всё, а вопрос
читаемости правил кроется в голове их разработчика, то можно сделать вывод, что
критической массе пользователей-девелоперов не нужны фичи и удобства pf(nat) и
сотоварищи.

тем не менее, я уважаю осознанную свободу выбора и слегка удивляюсь отсутствию
iptables во FreeBSD. :-)

С уважением.

Victor Sudakov

unread,
Jul 24, 2007, 10:53:55 AM7/24/07
to
Andrew Alcheyev wrote:

> AF> Пользуй pfnat и проблем с divert'ом не будет.

> ага, один ftp-proxy у pfnat'а чего стоит.

Это ты в хорошем смысле или с иронией?

Andrew Alcheyev

unread,
Jul 25, 2007, 1:26:00 AM7/25/07
to
Здравствуйте, Victor.

Wednesday July 25 2007 at 05:48, Victor Sudakov wrote to Vadim Goncharov:

>> AF>> Пользуй pfnat и проблем с divert'ом не будет.
>> >> ага, один ftp-proxy у pfnat'а чего стоит.

>> VS> Это ты в хорошем смысле или с иронией?
с иронией.
мне нравится синтаксис pf(nat). но вот лучше бы энергию портирования pf, да на
благое дело (нормализация трафика, traffic inspection, NAT экзотических случаев
и т.п.) для ipfw.

>> С иронией, конечно - оно ж на каждый коннект запускается из inetd.
>> И затем такое же копирование ядро<->юзерлэнд.
VS> А что ещё _не_ умеет pfnat по сравнению с libalias?
Я могу ошибаться, но навскидку гугление и поиск по сорцам libalias и pf
показали, что:
CUSEEME, IRC (DCC), PPTP (несколько сессий к одному серверу), NetBIOS/UDP,
RSTP.

Пока же pf выглядит лишь как средство для переманивания openbsd'истов да для
утешения параноиков.

С уважением.

Andrew Filonov

unread,
Jul 25, 2007, 1:07:35 AM7/25/07
to
>>>>> "AA" == Andrew Alcheyev writes:

AA> с иронией. мне нравится синтаксис pf(nat). но вот лучше бы
AA> энергию портирования pf, да на благое дело (нормализация трафика,
AA> traffic inspection, NAT экзотических случаев и т.п.) для ipfw.
А вот не надо делать монстрика из ipfw

AA> Я могу ошибаться, но навскидку гугление и поиск по сорцам
AA> libalias и pf показали, что: CUSEEME, IRC (DCC), PPTP (несколько
AA> сессий к одному серверу), NetBIOS/UDP, RSTP.
Только на обычном траффике оно работает в разы быстрее.

AA> Пока же pf выглядит лишь как средство для переманивания
AA> openbsd'истов да для утешения параноиков.
Оно выглядит как работающее решение. Случаи когда оно таки не
работают - не слишком массовы и легко решаются.

--
Andrew E. Filonov
The source for an unattributed quotation will appear
in the most hostile review of your work.

Andrew Alcheyev

unread,
Jul 25, 2007, 3:12:00 AM7/25/07
to
Здравствуйте, Andrew.

Wednesday July 25 2007 at 09:07, Andrew Filonov wrote to Andrew Alcheyev:

AF> А вот не надо делать монстрика из ipfw
оно уже монстрик, да хотя бы по сравнению с FreeBSD 2.2.
и что с этого ? ведь есть же pf, который решает! :-D

AF> Только на обычном траффике оно работает в разы быстрее.
оно = pfnat ? или pf вообще ?

если речь про pfnat, то я бы хотел узнать про методику измерения
производительности и результаты проведения забегов между pfnat и ipfw+ng_nat.

С уважением.

Alexey Kouznetsov

unread,
Jul 25, 2007, 4:12:40 AM7/25/07
to
"Vadim Goncharov" <vadimn...@tpu.ru> wrote in message
news:slrnfaca30.219...@hostel.avtf.net...

> AF>> Пользуй pfnat и проблем с divert'ом не будет.
> >> ага, один ftp-proxy у pfnat'а чего стоит.

> VS> Это ты в хорошем смысле или с иронией?

> С иронией, конечно - оно ж на каждый коннект запускается из inetd.
> И затем такое же копирование ядро<->юзерлэнд.

На некоторых видах фтп трафика оно у меня просто трапалось. Причем стояло 2
машины как бакап одна другую, так и трапались то одна то вторая. Дебажить
сильно небыло времени, вычислили только что за клиент (там какой-то был
довнлоадер хитрый) В итоге стоит для всего, кроме фтп pfnat а для ftp ipnat
(все на IPnat не подходит, так как нужно его еще и pfsync. а FTP в том виде
как оно реализуется на pf один хрен не синкается.)


Vadim Goncharov

unread,
Jul 25, 2007, 7:32:56 AM7/25/07
to
Hi Victor Sudakov!

On Wed, 25 Jul 2007 01:48:22 +0000 (UTC); Victor Sudakov wrote about 'Re: ipfw and keep-state':

AF>>> Пользуй pfnat и проблем с divert'ом не будет.
>>> ага, один ftp-proxy у pfnat'а чего стоит.

VS>> Это ты в хорошем смысле или с иронией?
>> С иронией, конечно - оно ж