Здравствуйте коллеги.Изучаю работу пакетного фильтра 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
всё в порядке. Это нормальное поведение или я что-то упустил из виду?
Спасибо.
>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
>[оверквотинг удален]
>>При такой конструкции пишет ошибку синтаксиса, а вот при такой:
>>
>>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 у хоста, куда перенаправляю. Теоретически он и так должен будет прийти
на необходимый порт. Или нет?
Ошибка в самом написании 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 }"
Поэтому и синтаксическая ошибка
>[оверквотинг удален]
>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-сервер?
Спасибо.
Будет но с оговорками.
При загрузке правил ваше правило
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 используется для перенаправления траффика приходящего на определенные порты с одной машины на другую ( например со шлюза на сервер во внутренней сети )
И это явно не про ваше правило т.к. вы хотите перенаправлять траффик которфй и так идет куда надо.
>[оверквотинг удален]
>rdr on значение_$ext_if inet proto tcp from any to значение_$www port 443 -> значение_$www
>
>Оговорки следующие:
>
>Обычно port forwarding используется для перенаправления траффика приходящего на определенные порты с
>одной машины на другую ( например со шлюза на сервер во
>внутренней сети )
>
>И это явно не про ваше правило т.к. вы хотите перенаправлять траффик
>которфй и так идет куда надо.Видимо так. Просто пока не нашёл иного способа перенаправлять трафик со шлюза
в DMZ. Может быть просто ограничиться разрешающими правилами фильтра?
А маршрутизировать запросы тогда как? Пока голова идёт кругом от нового :)
Если вы редиректите со шлюза в DMZ то rdr правило должно быть видаrdr on значение_$ext_if inet proto tcp from any to IP_ШЛЮЗА port $www_in -> IP_ПК_в_DMZ
>Если вы редиректите со шлюза в 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Ну и соответствующие правила фильтра. Так будет верно?
>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 серверами.
А вообще-то для разъяснения ситуации хотелось бы услышать стоящую задачу поподробней
>Во вторых в вашем случае ( если я все правильно понял )
>нужно организовать пул адресов что запросы приходящие на на шлюз по
>портам 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 доменное имя.
Хотелось бы грамотно организовать к ним доступ. Вот, в принципе и вся задача.
>[оверквотинг удален]
>
>будет ожидать на своём адресе, но находясь в DMZ они не имеют
>прямого соединения
>с интернетом, к ним нужно разрешить доступ. Вот и задача, контролировать доступ
>к ним
>на шлюзе. Это не пул одинаковых серверов, это совершенно разные сервера-сайты, не
>
>являющиеся виртуальными хостингами. 1 адрес -> 1 сервер -> 1 доменное имя.
>Хотелось бы грамотно организовать к ним доступ. Вот, в принципе и вся
>задача.Ну раз адреса у этих web серверов адреса маршрутизируемые алреса то и rdr-правила для них не нужны.
Все должно решиться правилами фильтрации.
>Ну раз адреса у этих web серверов адреса маршрутизируемые алреса то и
>rdr-правила для них не нужны.
>Все должно решиться правилами фильтрации.Спасибо за советы!
Буду пробовать.
>Спасибо.
>А если ситуация такая, что у меня 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)
>Погоди, а причем тут доменные имена? В firewall'е же ты не можешь
>разбирать доменные имена. Тут ты прописываешь ТОЛЬКО адреса и порты.Чтобы не раздувать ненужную полемику, скажу, что я понял советы Stalker-а, за что ему
большое спасибо. Он понял, что я хотел этим сказать, а я - что он советовал.>[оверквотинг удален]
>
>как firewall в твоих правилах поймет, что один пакет на 80ом порту
>для одного домена, а другой для другого?
>
>Эта задача совершенно не для firewall'а.
>
>Я например это решаю с помощью nginx, в роли reverse proxy.
>То есть все что приходит на 80 порт сваливается в него, а
>он уже в зависимости от доменного имени форвардит на нужный внутренний
>сервер (в моем случае в jail)Спасибо за Ваш совет, я учту его как вариант.