LINUX.ORG.RU
ФорумAdmin

iptables - помогите пробросить порт

 ,


0

1

Доброй ночи!

На сервере с адресом 5.5.5.5 порт 6789 (UDP) висит демон. Нужно все пакеты, идущие на 4.4.4.4:1234 перенаправлять на 5.5.5.5:6789. Это UDP, потому никаких балансировщиков нагрузки, и nginx не предлагайте.

Что пробовал:

iptables -t nat -A PREROUTING -i eth0 -p udp --dport 1234 -j REDIRECT --to-port 5678

идеально работает локально, сервер отвечает по обоим портам, IP адрес клиента в обоих случаях правильный. Пытаюсь вместо --to-port поставить параметром --to IP:PORT, получаю ошибку:

REDIRECT: Bad value for "--to-ports" option

Вот такая конфигурация работает,

iptables -t nat -A PREROUTING -i eth0 -p udp --dport 1234 -j DNAT --to 5.5.5.5:6789
iptables -t nat -A POSTROUTING -p udp -d 5.5.5.5 --dport 6789 -j MASQUERADE

но на сервере вместо IP адреса клиента регистрируется IP адрес промежуточного сервера, а так нельзя. При этом если повторить локально (1234 перекидываю на 127.0.0.1:6789) - работает и без второй строчки, и IP адрес сохраняется верный.

Подскажите пожалуйста, как заставить -j REDIRECT работать с удаленным IP адресом либо -j DNAT не портить IP адрес с которого поступает запрос.

1. REDIRECT - это только для локальных
2.

DNAT не портить IP адрес с которого поступает запрос.

А он и не портит, dnat изменяет в пакете адрес назначения.

А вот MASQUERADE (он же snat) меняет адрес источника.

anc ★★★★★ ()

Чего ты понагородил-то? Для проброса входящего трафика тебе надо ДВА правила - PREROUTING с DNAT и разрешение на FORWARD.

targitaj ★★★★★ ()
Ответ на: комментарий от targitaj

Не, ту всего больше. Если это на разных континентах. То проблем в разы больше. Но ТС нам всю «конспирологию» не хочет рассказать. Что за демон и так далее.

anc ★★★★★ ()
Последнее исправление: anc (всего исправлений: 1)
Ответ на: комментарий от buratino

а в openttd. и не помогите, а сам построй.

От души написали :)))) ТС Это к тебе.

anc ★★★★★ ()
Ответ на: комментарий от anc

А можно подробнее?

Если DNAT изменяет адрес назначения - все хорошо. Вы говорите, что MASQUERADE меняет адрес источника, но без этого второго правила ничего не работает (запрос от клиента отваливается, но не сразу как если порт закрыт, а секунд через 5 по таймауту).

Что за демон толку говорить, одна редкая клиент-серверная программа, где IP «клиента» используется для идентификации, потому если все перенаправленные клиенты будут иметь один адрес - это лажа.

и разрешение на FORWARD

/proc/sys/net/ipv5/ip_forward вчера еще поставил 1. Если я добавляю вместо второго правила (POSTROUTING) следующее,

iptables -A FORWARD -d 5.5.5.5 -p udp --dport 1234 -j ACCEPT

то ничего не работает, запрос не доходит до конечного сервера. Из всяких мануалов где пробрасывают 80 порт одной машины на 80 порт другой машины не понятно какой тут указывать порт, 1234 или 6789, но пробовал оба случая и оба не работают. Без второго правила - тоже.

не в iptables, а в openttd

openttd это вообще стратегия какая-то. Не нашел ничего.

Если это на разных континентах.

Нет, 2 сервера в одном городе у разных хостинг-провайдеров.

Dima_228 ()
Ответ на: комментарий от Dima_228

В случае 2 правил (PREROUTING + FORWARD) счетчики изменяются

Chain PREROUTING (policy ACCEPT 630 packets, 103K bytes)
num pkts bytes target prot opt in out source destination
1 1 54 DNAT udp  — eth0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:1234 to:5.5.5.5:6789

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 1 54 ACCEPT udp  — * * 0.0.0.0/0 5.5.5.5 udp dpt:6789

Запустил tcpdump на вывод всего что приходит локально на порт 1234 - все пакеты регистрируются. Запустил на коммуникацию с удаленным сервером на который идет перенаправление

tcpdump -i eth0 dst 5.5.5.5 and port 6789

пакеты тоже успешно уходят

13:29:36.400085 IP [тут hostname моего компа].39775 > 5.5.5.5.6789: UDP, length 26

На целевой сервер 5.5.5.5 ничего не приходит, хотя если стукнуть напрямую по адресу 5.5.5.5.6789 - все регистрируется.

Dima_228 ()

Подскажите пожалуйста, как заставить -j REDIRECT работать с удаленным IP адресом либо -j DNAT не портить IP адрес с которого поступает запрос.

Средствами одного (одних?) лишь iptables это сделать невозможно. IP пакеты ходят по маршруту в зависимости от того, какие адреса в них указаны. Если вам нужно и маршрут особенный иметь (ходить на 5.5.5.5, но через 4.4.4.4), и адреса сохранять, тогда по-любому нужен туннель.

spirit ★★★★★ ()
Ответ на: комментарий от spirit

Мне нужен не особенный маршрут, а перенаправление трафика с одного сервера на другой без изменения настроек на клиентах. Часть клиентов будут подключаться на новый IP, часть все еще на старый, но держать 2 сервера нельзя из-за проблем синхронизации данных.

Я когда-то делал подобную задачу через PREROUTING + POSTROUTING, но там было плевать на IP адреса. Сейчас узнал что можно обойтись без POSTROUTING но с FORWARD, причем правильный пакет от моего адреса (с правильным адресом отправителя) отправляется с первого сервера на второй, но туда почему-то не доходит. Нужно решить только эту проблему, но я не знаю как.

тогда по-любому нужен туннель

Что за туннель? VPN? Чем он лучше прямой передачи данных (оба сервера имеют белые IP)

Dima_228 ()

Нарисуй схему соединения.

И если для 4.4.4.4 твой 5.5.5.5 является шлюзом, то правила одни, а если нет - то другие.

Ты ещё можешь посмотреть в сторону haproxy.

anonymous ()
Ответ на: комментарий от anonymous

Да нет никакой схемы. 2 разных сервера у разных хостинг-провайдеров, но в одном городе. Пинг одинаковый. Клиенты территориально находятся везде. Шлюзы у всех разные и на их изменение у меня нет прав. Хостеры никакую маршрутизацию для меня делать не будут. PREROUTING + POSTROUTING работает, пакеты проходят в оба направления (только портится IP клиента). PREROUTING + FORWARD отправляет пакет правильный, но до сервера назначения он не доходит. Если бы он дошел, но потерялся ответ - я бы это все равно видел в консоли приложения, так что он не дошел.

haproxy не работает с UDP.

Dima_228 ()
Последнее исправление: Dima_228 (всего исправлений: 1)
Ответ на: комментарий от Dima_228

Если бы он дошел, но потерялся ответ - я бы это все равно видел в консоли приложения, так что он не дошел

Скорее всего у вас происходит следующее, вы поменяли DST IP, пакет ушел на другой сервер, он ответил и пакет пошёл клиенту. Клиент видит, что к нему пришёл непонятный пакет от сервера, с кем он не устанавливал никакую UDP-конекцию (а из-за отсутствия connect на udp можно только оперировать IP:PORT) и пакет отбрасывается как неизвестный.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Стоп. Протокол UDP. Никакого соединения Syn/Ack нет. Пакет идет от клиента на сервер 1, сервер 2 либо через сервер 1 к серверу 2 и во всех случаях сервер видит этот пакет и пишет IP адрес клиента в консоли, я это могу увидеть. Ушел ответ от сервера клиенту или нет - это вопрос второй. Да, со стороны клиента таймаут может возникать как при потере запроса, так и при потере ответа, но различить я их в данном случае могу.

Я поменял DST IP, пакет ушел на другой сервер, но он туда не дошел. Основная проблема сейчас в этом. Как только он туда дойдет с правильным IP адресом клиента, но возникнет проблема с ответом - это другая проблема, но надеюсь что ее тоже возможно будет решить.

Dima_228 ()
Ответ на: комментарий от Dima_228

Стоп. Протокол UDP. Никакого соединения Syn/Ack нет.

Читать вначале надо внимательнее, прежде чем отвечать. Именно об этом и было отдельно разжевано.

Основная проблема сейчас в этом.

Нет разницы, что вы там поставили в очередь что первой проблемой, что потом. Всё равно работать не будет по описанной в моём комменте причине. Решение вам уже дали — надо делать туннель до второго сервера, биндить тот сервис для клинетов на интерфейс туннеля, перенаправлять ответы policy routing-ом с дефолта на туннель и отправлять на первый сервер. Только тогда там сработает восстановление DST взад.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Ладно, следующая проблема. Поднял OpenVPN (используя openvpn-install.sh - настройки по умолчанию) туннель между серверами (без смены default gateway, закомментировал пару строчек в конфиге ovpn сервера), на сервере 10.8.0.1:6789 (он же раньше был 5.5.5.5), на перенаправляющем сервере 10.8.0.2. Правила PREROUTING + FORWARD, только адрес поменял. Демон слушает 0.0.0.0 то есть обязан отвечать на все интерфейсы. ping в обе стороны проходит, tcpdump -i tun0 на обоих машинах ICMP пакеты видит. Как только осуществляю запрос - на перенаправляющем сервере виден пакет, ушедший с моего домашнего адреса на 10.8.0.1:6789, но на стороне VPN сервера этого пакета нет. Внутри туннеля та же потеря пакета «туда», что будет происходить с пакетом-ответом еще не знаю. Что дальше делать? Что за policy routing? На какой машине и как его настраивать?

Dima_228 ()
Ответ на: комментарий от Dima_228

но на стороне VPN сервера этого пакета нет.

Во-первых, с терминами надо аккуратнее, не PREROUTING, а DNAT. Если вы не поменяли DST с внешнего IP втого сервера на адрес туннеля, то толку не будет.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Старые правила все удалил, новые поставил:

iptables -t nat -A PREROUTING -i eth0 -p udp --dport 1234 -j DNAT --to 10.8.0.1:6789
iptables -A FORWARD -d 10.8.0.1 -p udp --dport 6789 -j ACCEPT

Это на машине 10.8.0.2, которая перенаправляет, она является openvpn клиентом. На 10.8.0.1 тот сервер куда нужно перенаправлять и, по совместительству, OpenVPN сервер.

На 10.8.0.1 командой

tcpdump -i tun0

не регистрируются UDP пакеты, только пинг между хостами по IP адресам туннеля. Значит, пакет по какой-то причине не уходит с 10.8.0.2

Dima_228 ()
Последнее исправление: Dima_228 (всего исправлений: 1)
Ответ на: комментарий от Dima_228

УМВР. Вот копирую со своего маршрутизатора:

iptables -t nat -A PREROUTING -p udp -d $IP_GW --dport 4433 -j DNAT --to-destination 10.68.12.23:4433
Отличие только в том, что не i eth0, а -d IP маршрутизатора. Так в принципе правильнее, если хочется проверять и изнутри тоже.

Но это всё равно только маленькая часть дела. Еще надо делать правила рутинга на втором серере, где надо указать, что ответы от сервиса надо напраплять не по дефолту, а по второму каналу через туннель.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Да, разница не велика но учту на будущее.

В том то и дело что ответы от сервиса нужно будет направлять туда откуда они пришли, либо из интернета через дефолт, либо из туннеля. Определить это по IP адресу клиента невозможно, то есть NAT или кто там рядом, должен запоминать откуда пришел тот или иной пакет… Если какой-то сервер слушает UDP порт на адресе 0.0.0.0, как-то система (стек TCP/IP или как оно реализовано я не в курсе) знает через какой интерфейс нужно слать ответ?

Dima_228 ()
Ответ на: комментарий от Dima_228

знает через какой интерфейс нужно слать ответ?

В том то и дело, что не знает. Это стандартная проблема более одного канала. Решается правилами маршрутизации совместно с iptables. Вначале пакеты метятся, потом пакеты с меткой отправляются в нужный канал.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

То есть проблема стандартная и решение стандартное? Если у меня грубо говоря 2 канала (общий интернет и труба, т.е. туннель на другой сервер) значит можно? Где-то есть готовые решения как для случая обычных 2 каналов? как это настроить?

Dima_228 ()
Ответ на: комментарий от vodz

Ознакомился, всё выглядит достаточно сложно для реализации. А можно как-то сделать 2 правила

REDIRECT –to-port 5678 работающих в следующем режиме:

  1. реальный сервер слушает, скажем, 127.0.0.1:6789
  2. 5.5.5.5:6789 перенаправляется на 127.0.0.1:6789, все ответы идут через default gateway
  3. С сервера 4.4.4.4:1234 все идет в туннель 10.8.0.1:1234
  4. на 5.5.5.5 10.8.0.1:1234 с помощью REDIRECT –to-port кидает все на 127.0.0.1:6789, и все что пришло по этому пути возвращается через OpenVPN туннель 10.8.0.1-10.8.0.2.

Подозреваю ухудшение latency и возможные потери пакетов, но надо чтобы хоть как-то работало.

Dima_228 ()
Ответ на: комментарий от Dima_228

реальный сервер слушает, скажем, 127.0.0.1:6789

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

vodz ★★★★★ ()
Ответ на: комментарий от Dima_228

Ознакомился, всё выглядит достаточно сложно для реализации.

И чего сложного вы нашли? Всего «полторы команды» и профит.

anc ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.