OpenBSD 4.7, PPPoE, проброс портов.

Весь мозг сломал, в OpenBSD и PF впервые.

Пытаюсь сделать на сабже шлюз. "Натить" получилось прекрасно, все работает, снаружи он тоже виден, не проблема. Но порты внутрь не прокидываются.

Внешний статический IP выдается провайдером после подключения PPPoE. Конфигов перепробовал кучу. В частности полностью скопировал с корректировкой под себя этот (ну мало ли дурак, чего не заметил пока свой писал), листинг в конце страницы.
http://www.openbsd.org/faq/pf/example1.html
Нат фурычит, порты не прокидываются.

Сейчас сделал свой, вообще в два правила:


ext_if = "tun0" # PPPoE провайдера
int_if = "re0" # Мой внутренний интерфейс
str_if = "re1" # Смотрит к провайдеру
ext_ip = "21.21.21.21" # Тут мой IP
server = "192.168.10.10" # Куда надо попасть по ряду портов, эксперементирую на 80-ом :)

pass out on $ext_if from $int_if:network nat-to $ext_ip # nat чудесно работает, из под него пишу.

pass in on $ext_if proto tcp from any to $ext_ip port 80 rdr-to $server # ни фига, и через match писал, как только не изгалялся.

80-ый порт наружу закрыт, хотя процессы самой системы все, что нужно, слушают.

devon@macpro ~ $ nmap 21.21.21.21

Starting Nmap 5.21 ( http://nmap.org ) at 2010-05-31 23:27 MSD
Nmap scan report for 21.21.21.21
Host is up (0.00029s latency).
Not shown: 995 closed ports
PORT STATE SERVICE
13/tcp open daytime
22/tcp open ssh
37/tcp open time
53/tcp open domain
113/tcp open auth

Nmap done: 1 IP address (1 host up) scanned in 12.19 seconds

Что я упускаю? Где грабли? Ничего не понимаю :( Перетыкаю в шлюз на Линупсе + iptables, все работает.

Аватар пользователя test00

pass in on $ext_if proto


pass in on $ext_if proto tcp from any to $ext_ip port 80 rdr-to $server # ни фига, и через match писал, как только не изгалялся.

А кто pass out за вас делать будет? Матчасть: rdr-же, как и NAT, есть тип трансляции, потому пакет проходит через pf дважды: будучи in и будучи out. "In" он у вас прошёл, так как pass in указан в правиле для rdr, а "out" - не может. Добавьте:
pass out on $ext_if proto tcp from any to $server

P.S.: вот мой пример с rdr который работал в старом pf:

rdr  on     $ext_if inet proto tcp from any to $ext_me port 20000 -> 172.16.1.2 port ssh
pass in  on $ext_if inet proto tcp from any to 172.16.1.2 port ssh user root
pass out on $ext_if inet proto tcp from any to 172.16.1.2 port ssh user unknown

Пакет сначала проходит правило rdr, потом идёт тут же на фильтрацию и обрабатывается правилом pass in, затем ядро делает его out, он снова попадает в pf и обрабатывается правилом с pass out. В тонкостях нового синтаксиса с rdr не разбираюсь.

Аватар пользователя Devon

pass out on $ext_if proto tcp from any to $server

По новому синтаксису строка некорректна.

Pass out я делал на все так:
pass out quick
как в примере http://www.openbsd.org/faq/pf/example1.html#allrules
Не работает.

Вот пример, полностью пердранный оттуда:

# macros

int_if="re0"

tcp_services="{ 22, 113 }"
icmp_types="echoreq"

comp3="192.168.10.10"

# options

set block-policy return
set loginterface tun0
set skip on lo

# match rules

match out on egress inet from !(egress) to any nat-to (egress:0)

# filter rules

block in log
pass out quick

antispoof quick for { lo $int_if }

pass in on egress inet proto tcp from any to (egress) \
port $tcp_services

pass in on egress inet proto tcp from any to (egress) port 80 \
rdr-to $comp3

pass in inet proto icmp all icmp-type $icmp_types

pass in on $int_if

NAT работает, проброс нет.

Аватар пользователя alexm

tcpdump'ом

tcpdump'ом послушай внешний и-фейс и дальше по цепочке

Аватар пользователя Devon

tcpdump

Вчера пробовал. Любая попытка открыть соединение на внешний IP по 80-му порту - это всего две строчки, запрос на соединение, как я понял и ответ, больше ничего. Позже смогу выложить.

Аватар пользователя Devon

Я слепой кретин.

Я сделал обе перечисленные ошибки, надо было курить доки внимательнее. Сбило то, что на iptables все работает и так. Я подозревал подобное, но нечем было проверить. Мало того, мое уважение к PF и OpenBSD после этого только возросло :) Ну и правила я за это время научился писать хорошо в любом виде и форме :)))) И главное по вчерашнему выводу tcpdump-а можно было догадаться, но уже сильно спать хотелось :)


But when the redirection rule is tested from a client on the LAN, it doesn't work. The reason is that redirection rules apply only to packets that pass through the specified interface ($ext_if, the external interface, in the example). Connecting to the external address of the firewall from a host on the LAN, however, does not mean the packets will actually pass through its external interface. The TCP/IP stack on the firewall compares the destination address of incoming packets with its own addresses and aliases and detects connections to itself as soon as they have passed the internal interface. Such packets do not physically pass through the external interface, and the stack does not simulate such a passage in any way. Thus, PF never sees these packets on the external interface, and the redirection rule, specifying the external interface, does not apply.

Adding a second redirection rule for the internal interface does not have the desired effect either. When the local client connects to the external address of the firewall, the initial packet of the TCP handshake reaches the firewall through the internal interface. The redirection rule does apply and the destination address gets replaced with that of the internal server. The packet gets forwarded back through the internal interface and reaches the internal server. But the source address has not been translated, and still contains the local client's address, so the server sends its replies directly to the client. The firewall never sees the reply and has no chance to properly reverse the translation. The client receives a reply from a source it never expected and drops it. The TCP handshake then fails and no connection can be established.

Аватар пользователя slav83

Devon, у меня

Devon, у меня такая-же проблема( Подскажи, в чем причина ?? (С английским плохо - сократом перевел цитату, но ничего не понял)

Аватар пользователя test00

Проблема была в

Проблема была в том, что всё работало, но автор тестил работоспособность из локальной сети куда делается rdr, а не из реального инета, потому был облом, ибо так оно работать не будет. В другом абзаце объясняется что rdr нельзя использовать для перенаправления трафика внутрисетевого трафика на какой-то gw из-за того что PF сильно умный, и пакеты реально не проходят через _внешний_ интерфейс (если нужна именно такая конфигурация нужно настраивать соответственно). Так что мораль - тестируйте с реально удалённого сервака, например зайдите туда по ssh и оттуда попытайтесь зайти на свой сервис, для которого делаете rdr.

Аватар пользователя Devon

Именно

Причем есть три метода решения - натить самого себя внутрь своей же сети (не рекомендуется), делать заглушку на днс (рекомендуется), вывести сервер из прямого доступа из сети клиента (вланом ли, другой подсетью - думаю пофиг, особо рекомендуется в виду повышения секьюрности в целом.)