Jump to content
Калькуляторы

Как переслать пакет на другой порт? FreeBSD, pf

Мне нужно пакеты 53/udp, приходящие на интерфейс em1, переслать на порт 5353/udp того же интерфейса.

И ответ с порта 5353/udp отправить с порта 53.

И что-то не получается.

Форвардинг выключен (net.inet.ip.forwarding=0), но если его включить, ничего не меняется.

Пробовал такие три варианта:

rdr on em1 proto udp from <net> port 53 -> em1 port 5353

pass in on em1 proto udp from <net> to em1 port 53 rdr-to em1 port 5353

nat on em1 proto udp from <net> to em1 port 53 -> em1 port 5353

Share this post


Link to post
Share on other sites

Через старый добрый 3proxy делается в одну строку. Это ж обычный портмаппинг. Через pf хз, я не знаю, что это. )

Share this post


Link to post
Share on other sites

3proxy не подойдет, мне нужно делать смену порта только для IP-адресов, указанных в <net>.

У меня на сервере работают два сервиса, 53/udp и 5353/udp.

Запросы из <net>, поступающие на 53/udp, нужно перенаправить на 5353/udp.

Ну а всех остальных (не из <net>) нужно не трогать.

Share this post


Link to post
Share on other sites

rdr proto udp from <net> port 53 -> 127.0.0.1 port 5353

pass in on em1 proto udp from <net> to self port 5353

 

Возможно 127.0.0.1 нужно будет заменить на адрес на em1.

 

Через старый добрый 3proxy делается в одну строку. Это ж обычный портмаппинг. Через pf хз, я не знаю, что это. )

PF делает тоже самое только в ядре.

А три таких строчки: http://www.netlab.linkpc.net/forum/index.php?topic=645.0 вообще убивают весь смысл существования подобных программ.

 

-j REDIRECT --to-ports 5353

# -j REDIRECT --to-ports 5353

-j: Command not found.

Exit 1

Share this post


Link to post
Share on other sites

-j REDIRECT --to-ports 5353

Это iptables? У меня pf.

 

Ivan_83, спасибо. А чтобы в обратных пакетах порт с 5353 на 53 менялся, зеркальное правило нужно? Или pf сам сделает?

Share this post


Link to post
Share on other sites

# -j REDIRECT --to-ports 5353

-j: Command not found.

Exit 1

Остряк. На вот ещё остроту:

$ rdr proto udp from <net> port 53 -> 127.0.0.1 port 5353
Python error: <stdin> is a directory, cannot continue

Share this post


Link to post
Share on other sites

А чтобы в обратных пакетах порт с 5353 на 53 менялся, зеркальное правило нужно? Или pf сам сделает?

Ты перенаправляешь пакет в пределах хоста, это не трансляция адреса, а замена/перенаправление.

Сервис получит пакет и ответит на него напрямую юзеру.

Я вроде так делал, самсунговский смарт разницы не увидел.

Ещё я всегда так делаю с 80 портом - перенаправляю на 8080.

Но если пакет уходит на другой хост, то нужно делать трансляцию и перенаправление, пример/инструкция была в том же посте по ссылке, там только под себя эти три строчки поправить.

 

 

Остряк. На вот ещё остроту

Просто не хотелось в очередной раз писать гадости про линукс и что это оффтоипк :)

Он тут меня на днях обломил с ограничениями в splice().

И ещё раз atomic_*() / intrlocked_*() функции мне захотелось, но их там не нашлось, хотя во фре и венде это есть.

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

И в очередной раз я вспомнил что RCV_LOWAT в линуксе не работает, потому он жрёт проц почём зря, хотя мог бы жрать почти в два раза меньше с тем же результатом.

Share this post


Link to post
Share on other sites

rdr proto udp from <net> port 53 -> 127.0.0.1 port 5353

pass in on em1 proto udp from <net> to self port 5353

Наверное перед port пропущено to?

Проверял запросы с онлайна - почему-то запросы проходят через один.

Возможно нужно порт отправителя в ответах тоже заменять.

Share this post


Link to post
Share on other sites

Возможно нужно порт отправителя в ответах тоже заменять.

Похоже что да. Сделал трансляцию, теперь проходят все запросы.

Ivan_83, просьба проверить, не упустил ли чего?

if_ext = "em1"
if_dns = "xx.yy.124.12"
table <netpub> { xx.yy.124.0/22 aa.bb.104.0/21 }
rdr on $if_ext proto {tcp udp} from !<netpub> to $if_dns port 53 -> $if_dns port 5353
nat on $if_ext proto {tcp udp} from !<netpub> to $if_dns port 53 -> $if_dns port 5353
nat on $if_ext proto {tcp udp} from $if_dns port 5353 to !<netpub> -> $if_dns port 53
...
<нормализация, общие фильтры>
...
pass out quick on $if_ext to any
pass in quick on $if_ext proto {tcp udp} to self port 53
pass in quick on $if_ext proto {tcp udp} from !<netpub> to $if_dns port 5353

Смысл следующий. На сервере работают два DNS-сервера, один кеширующий (на порту 53), другой авторитетный (на порту 5353).

Кеширующий обслуживает запросы только из <netpub>. Авторитетный обслуживает все запросы, но только в своей зоне.

Внешние сети (те, что в <netpub> не входят) должны перенаправляться на авторитетный сервер.

Share this post


Link to post
Share on other sites

Смысл следующий. На сервере работают два DNS-сервера, один кеширующий (на порту 53), другой авторитетный (на порту 5353).

Кеширующий обслуживает запросы только из <netpub>. Авторитетный обслуживает все запросы, но только в своей зоне.

Внешние сети (те, что в <netpub> не входят) должны перенаправляться на авторитетный сервер.

 

Что мешало использовать bind на одном порту?

Pазграничить с помощью ACL пробовали?

Share this post


Link to post
Share on other sites

В каком смысле bind? Если речь о BIND, то я решил попробовать другие реализации. Как работает Unbound мне нравится больше.

А если речь про слушающий сокет, то как я на одном порту запущу два сервиса?

Share this post


Link to post
Share on other sites

Ivan_83, просьба проверить, не упустил ли чего?

Если работает то работает :)

 

В каком смысле bind? Если речь о BIND, то я решил попробовать другие реализации. Как работает Unbound мне нравится больше. А если речь про слушающий сокет, то как я на одном порту запущу два сервиса?

bind() - системный вызов, ассоцирующий сокет с адресом L4 (порт для udp/tcp), делается перед началом приёма трафика.

Можно без фаервола навешать на разные ip на 53 порт разные софтины, для этого в конфиге вместо 0.0.0.0 нужно указывать адрес интерфейса на котором слушать.

Share this post


Link to post
Share on other sites

Я объясню на примере того что у меня опубликовано.

 

rdr inet proto tcp from any to (self) port $host_port_ext -> $host_addr port $host_port

К нам на порт $host_port_ext пришёл пакет, мы его пересылаем на другой хост $host_addr и порт $host_port.

При пересылке dst ip и dst порт заменяются и пакет ставится в очередь на отправку.

 

nat on $int_if inet proto tcp from any to $host_addr port $host_port -> ($int_if)

Здесь мы перед тем как отправить пакет заменяем в нём src ip и src порт на свои.

src ip берётся с $int_if.

Это делается для того, чтобы хост куда мы пересылаем отвечал нам, при этом nat сделает обратное преобразование и отправит пакет хосту от которого пакет пришёл в rdr правило изначально.

 

nat on $ext_if inet proto tcp from $host_addr port $host_port to any -> ($ext_if)

Тут мы перед отправкой хосту от которого пришёл первый пакет заменяем src ip и порт на свои с $ext_if интерфейса, потому что до попадания в это правило src ip = $host_addr.

Это нужно чтобы получатель знал что пакет к нему пришёл от нас а не от неведомого хоста куда мы на самом деле пересылали пакет.

 

В целом это так.

Возможно в части замены портов в заголовках я где то допустил ошибки, но для IP адресов всё как описано.

Share this post


Link to post
Share on other sites

Ладно, работает - значит не буду трогать.

Просто была мысль, что rdr лишний.

Мне нужен двухсторонний порт-маппинг. Или bi-nat, но для портов, а не IP-адресов.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.