URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID10
Нить номер: 4007
[ Назад ]

Исходное сообщение
"Работа PF в OpenBSD"

Отправлено Junior , 08-Окт-08 12:40 
Здравствуйте коллеги.

Изучаю работу пакетного фильтра PF в OpenBSD, после Linux немного напрягает
другая логика работы, но это терпимо, освоюсь.
Вопрос такой: изучая перенаправление соединения со шлюза в DMZ натолкнулся на такой
нюанс - если указать порт назначения через макрос, то пишет ошибку синтаксиса правила,
а если просто вбить цифру порта, то всё нормально.
Т.е.

www="11.22.33.44"
web_in="{ 80 }"

rdr on $ext_if inet proto tcp to $www port $web_in -> $www port $web_in

При такой конструкции пишет ошибку синтаксиса, а вот при такой:

rdr on $ext_if inet proto tcp to $www port $web_in -> $www port 80

всё в порядке. Это нормальное поведение или я что-то упустил из виду?

Спасибо.


Содержание

Сообщения в этом обсуждении
"Работа PF в OpenBSD"
Отправлено eax0r , 08-Окт-08 13:03 
>rdr on $ext_if inet proto tcp to $www port $web_in -> $www port $web_in
>
>При такой конструкции пишет ошибку синтаксиса, а вот при такой:
>
>rdr on $ext_if inet proto tcp to $www port $web_in -> $www port 80

Оба варианта с назначением порта правильные. Если не ошибаюсь, вместо макросов просто подставляются соответствующие значения и все. Ошибка в другом месте. Хоть в правилах и можно опускать некоторые параметры, но попробуй указать от кого трафик редиректить:

rdr on $ext_if inet proto tcp FROM ANY to $www port $web_in -> $www port $web_in


"Работа PF в OpenBSD"
Отправлено Junior , 08-Окт-08 13:08 
>[оверквотинг удален]
>>При такой конструкции пишет ошибку синтаксиса, а вот при такой:
>>
>>rdr on $ext_if inet proto tcp to $www port $web_in -> $www port 80
>
>Оба варианта с назначением порта правильные. Если не ошибаюсь, вместо макросов просто
>подставляются соответствующие значения и все. Ошибка в другом месте. Хоть в
>правилах и можно опускать некоторые параметры, но попробуй указать от кого
>трафик редиректить:
>
>rdr on $ext_if inet proto tcp FROM ANY to $www port $web_in -> $www port $web_in

Да, я пробовал как Вы написали, но результат - ошибка синтаксиса ;(

rdr on $ext_if inet proto tcp from any to $www port $web_in -> $www port $web_in

# pfctl -vnf /etc/pf.conf
---cut---
/etc/pf.conf:57: syntax error
#
В то же время если заменить на порт 80, то всё в порядке.
Мистика какая-то, я был вполне уверен, что макрос для того и нужен, чтобы
не рыскать потом на всему конфигу и править вручную изменения. И влиять
ни на что не должен. А тут такая засада. Остаётся только вообще убрать параметр
port $web_in у хоста, куда перенаправляю. Теоретически он и так должен будет прийти
на необходимый порт. Или нет?


"Работа PF в OpenBSD"
Отправлено Stalker , 09-Окт-08 08:37 
Ошибка в самом написании rdr правила. Смотрим man pf.conf...
rdr-rule       = [ "no" ] "rdr" [ "pass" [ "log" [ "(" logopts ")" ] ] ]
                      [ "on" ifspec ] [ af ]
                      [ protospec ] hosts [ "tag" string ] [ "tagged" string ]
                      [ "->" ( redirhost | "{" redirhost-list "}" )
                      [ portspec ] [ pooltype ] ]
....
Где
portspec       = "port" ( number | name ) [ ":" ( "*" | number | name ) ]

А у Вас во второй части правила совсем не portspec потому что "{ 80 }"
Поэтому и синтаксическая ошибка


"Работа PF в OpenBSD"
Отправлено Junior , 09-Окт-08 08:47 
>[оверквотинг удален]
>portspec ] [ pooltype ] ]
>....
>Где
>portspec       = "port" ( number |
>name ) [ ":" ( "*" | number | name )
>]
>
>А у Вас во второй части правила совсем не portspec потому что
>"{ 80 }"
>Поэтому и синтаксическая ошибка

Большое спасибо за разъяснение!
Просто запутало некоторое усиление акцента на работу с макросами,
посчитал это панацеей некой. Видимо для унификации работы прийдётся
отказаться от использования portspec, не будет ли это ошибкой?
Будет ли правильно перенаправляться соединение? Т.к. пока правила на
синтаксис тестируются на не шлюзовой машине, хочется избежать таких
подводных камней и потом безболезненно портировать всё на боевой сервер.
Т.е. если мне необходимо будет указать прослушивание двух портов на
шлюзе и перенаправление соответствующего трафика на Web-Сервер:

web_in="{ 80, 443 }"
rdr on $ext_if inet proto tcp from any to $www port $web_in -> $www

Будет ли такая конструкция жизнеспособна? Будет ли правильно направляться трафик
на Web-сервер?
Спасибо.


"Работа PF в OpenBSD"
Отправлено Stalker , 09-Окт-08 12:45 
Будет но с оговорками.
При загрузке правил ваше правило
rdr on $ext_if inet proto tcp from any to $www port $web_in -> $www

разобъется на два

rdr on значение_$ext_if inet proto tcp from any to значение_$www port 80 -> значение_$www
rdr on значение_$ext_if inet proto tcp from any to значение_$www port 443 -> значение_$www

Оговорки следующие:

Обычно port forwarding используется для перенаправления траффика приходящего на определенные порты с одной машины на другую ( например со шлюза на сервер во внутренней сети )

И это явно не про ваше правило т.к. вы хотите перенаправлять траффик которфй и так идет куда надо.


"Работа PF в OpenBSD"
Отправлено Junior , 09-Окт-08 12:49 
>[оверквотинг удален]
>rdr on значение_$ext_if inet proto tcp from any to значение_$www port 443 -> значение_$www
>
>Оговорки следующие:
>
>Обычно port forwarding используется для перенаправления траффика приходящего на определенные порты с
>одной машины на другую ( например со шлюза на сервер во
>внутренней сети )
>
>И это явно не про ваше правило т.к. вы хотите перенаправлять траффик
>которфй и так идет куда надо.

Видимо так. Просто пока не нашёл иного способа перенаправлять трафик со шлюза
в DMZ. Может быть просто ограничиться разрешающими правилами фильтра?
А маршрутизировать запросы тогда как? Пока голова идёт кругом от нового :)


"Работа PF в OpenBSD"
Отправлено Stalker , 09-Окт-08 14:29 
Если вы редиректите со шлюза в DMZ то rdr правило должно быть вида

rdr on значение_$ext_if inet proto tcp from any to IP_ШЛЮЗА port $www_in -> IP_ПК_в_DMZ


"Работа PF в OpenBSD"
Отправлено Junior , 09-Окт-08 14:41 
>Если вы редиректите со шлюза в DMZ то rdr правило должно быть
>вида
>
>rdr on значение_$ext_if inet proto tcp from any to IP_ШЛЮЗА port $www_in -> IP_ПК_в_DMZ

Спасибо.
А если ситуация такая, что у меня 2 (3, 4, 5) Web-серверов в DMZ, у каждого свой
реальный адрес и своё доменное имя? В таком случае Ваше правило не поможет, наверное.
Как быть в такой ситуации?
Или описывать всё-таки каждым правилом именно адресованное каждому персонально
web-серверу, что логичнее?

web1_ip="11.22.33.44"
web2_ip="22.33.44.55"
web3_ip="33.44.55.66"
web_in="{ 80, 443 }"
rdr on $ext_if inet proto tcp from any to $web1_ip port $web_in -> $web1_ip
rdr on $ext_if inet proto tcp from any to $web2_ip port $web_in -> $web2_ip
rdr on $ext_if inet proto tcp from any to $web3_ip port $web_in -> $web3_ip

Ну и соответствующие правила фильтра. Так будет верно?


"Работа PF в OpenBSD"
Отправлено Stalker , 09-Окт-08 15:03 
>web1_ip="11.22.33.44"
>web2_ip="22.33.44.55"
>web3_ip="33.44.55.66"
>web_in="{ 80, 443 }"
>rdr on $ext_if inet proto tcp from any to $web1_ip port $web_in -> $web1_ip
>rdr on $ext_if inet proto tcp from any to $web2_ip port $web_in -> $web2_ip
>rdr on $ext_if inet proto tcp from any to $web3_ip port $web_in -> $web3_ip
>
>Ну и соответствующие правила фильтра. Так будет верно?

Неверно.
Во первых я уже сказал что rdr правила используются для port forwarding'а с одной машины на другую, т.е. после to должен стоять ip адрес машины на которую приходят запросы ( например адрес шлюза ) а после -> ip адрес машины на которую нужно трафик переправить по соответствующим портам

Во вторых в вашем случае ( если я все правильно понял ) нужно организовать пул адресов что запросы приходящие на на шлюз по портам www_in равномерно распределялись между вашими web серверами.

А вообще-то для разъяснения ситуации хотелось бы услышать стоящую задачу поподробней



"Работа PF в OpenBSD"
Отправлено Junior , 09-Окт-08 15:30 
>Во вторых в вашем случае ( если я все правильно понял )
>нужно организовать пул адресов что запросы приходящие на на шлюз по
>портам www_in равномерно распределялись между вашими web серверами.
>А вообще-то для разъяснения ситуации хотелось бы услышать стоящую задачу поподробней

Нет, постараюсь объяснить.
Есть шлюз, есть web-сервера, каждый из которых имеет свой реальный адрес (маршрутизируемый),
web-сервера находятся в DMZ. На каждый из web-серверов имеется соответствующая запись
в DNS. Нужно просто контролировать и пропускать трафик на шлюзе, предназначенный для
этих серверов. Также имеется LAN, где обитают фейковые адреса машин, которым также нужно
иметь доступ в DMZ и в интернет.
Примерно такая ситуация:

ext_if="rl0"                 # Наш внешний интерфейс
lan_if="rl1"                 # Наш интерфейс в LAN
dmz_if="rl2"                 # Наш интерфейс в DMZ
ext_ip="11.22.33.99"         # Адрес на внешнем интерфейсе
lan_net="192.168.1.0/24"     # Внутренняя сетка
dmz_net="11.22.33.0/28"      # Сеть DMZ
web1_ip="11.22.33.1"         # Адрес 1-го web-сервера
web2_ip="11.22.33.2"         # Адрес 2-го web-сервера
web3_ip="11.22.33.3"         # Адрес 3-го web-сервера
web_in="{ 80, 443 }"         # Порты, на которых принимают соединения web-серверы

Т.к. каждый из серверов имеет свой зарегистрированный адрес, то и соединения он
будет ожидать на своём адресе, но находясь в DMZ они не имеют прямого соединения
с интернетом, к ним нужно разрешить доступ. Вот и задача, контролировать доступ к ним
на шлюзе. Это не пул одинаковых серверов, это совершенно разные сервера-сайты, не
являющиеся виртуальными хостингами. 1 адрес -> 1 сервер -> 1 доменное имя.
Хотелось бы грамотно организовать к ним доступ. Вот, в принципе и вся задача.



"Работа PF в OpenBSD"
Отправлено Stalker , 09-Окт-08 16:26 
>[оверквотинг удален]
>
>будет ожидать на своём адресе, но находясь в DMZ они не имеют
>прямого соединения
>с интернетом, к ним нужно разрешить доступ. Вот и задача, контролировать доступ
>к ним
>на шлюзе. Это не пул одинаковых серверов, это совершенно разные сервера-сайты, не
>
>являющиеся виртуальными хостингами. 1 адрес -> 1 сервер -> 1 доменное имя.
>Хотелось бы грамотно организовать к ним доступ. Вот, в принципе и вся
>задача.

Ну раз адреса у этих web серверов адреса маршрутизируемые алреса то и rdr-правила для них не нужны.
Все должно решиться правилами фильтрации.


"Работа PF в OpenBSD"
Отправлено Junior , 09-Окт-08 16:29 
>Ну раз адреса у этих web серверов адреса маршрутизируемые алреса то и
>rdr-правила для них не нужны.
>Все должно решиться правилами фильтрации.

Спасибо за советы!
Буду пробовать.


"Работа PF в OpenBSD"
Отправлено vagif zeynalov , 09-Окт-08 19:32 

>Спасибо.
>А если ситуация такая, что у меня 2 (3, 4, 5) Web-серверов
>в DMZ, у каждого свой
>реальный адрес и своё доменное имя? В таком случае Ваше правило не
>поможет, наверное.

Погоди, а причем тут доменные имена? В firewall'е же ты не можешь разбирать доменные имена. Тут ты прописываешь ТОЛЬКО адреса и порты.

>web1_ip="11.22.33.44"
>web2_ip="22.33.44.55"
>web3_ip="33.44.55.66"
>web_in="{ 80, 443 }"
>rdr on $ext_if inet proto tcp from any to $web1_ip port $web_in -> $web1_ip
>rdr on $ext_if inet proto tcp from any to $web2_ip port $web_in -> $web2_ip
>rdr on $ext_if inet proto tcp from any to $web3_ip port $web_in -> $web3_ip

как firewall в твоих правилах поймет, что один пакет на 80ом порту для одного домена, а другой для другого?

Эта задача совершенно не для firewall'а.

Я например это решаю с помощью nginx, в роли reverse proxy.
То есть все что приходит на 80 порт сваливается в него, а он уже в зависимости от доменного имени форвардит на нужный внутренний сервер (в моем случае в jail)


"Работа PF в OpenBSD"
Отправлено Junior , 09-Окт-08 20:29 
>Погоди, а причем тут доменные имена? В firewall'е же ты не можешь
>разбирать доменные имена. Тут ты прописываешь ТОЛЬКО адреса и порты.

Чтобы не раздувать ненужную полемику, скажу, что я понял советы Stalker-а, за что ему
большое спасибо. Он понял, что я хотел этим сказать, а я - что он советовал.

>[оверквотинг удален]
>
>как firewall в твоих правилах поймет, что один пакет на 80ом порту
>для одного домена, а другой для другого?
>
>Эта задача совершенно не для firewall'а.
>
>Я например это решаю с помощью nginx, в роли reverse proxy.
>То есть все что приходит на 80 порт сваливается в него, а
>он уже в зависимости от доменного имени форвардит на нужный внутренний
>сервер (в моем случае в jail)

Спасибо за Ваш совет, я учту его как вариант.