Linux

Как сделать переадресацию портов с одного IP на другой в одной и той же сети?

Я хотел бы сделать NAT в iptables. Таким образом, чтобы все пакеты, приходящие на 192.168.12.87 и порт 80, будут перенаправляться на 192.168.12.77 и порт 80.

Как это сделать с помощью iptables? Или, любыми другими способами добиться того же самого?

 

Ответ 1

Эти правила должны сработать, если iptables на сервере работает на 192.168.12.87:

#!/bin/sh

echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -F

iptables -t nat -F

iptables -X

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77:80

iptables -t nat -A POSTROUTING -p tcp -d 192.168.12.77 --dport 80 -j SNAT --to-source 192.168.12.87

 

Вам необходимо направить входящий трафик DNAT на порт 80, но вам также потребуется вернуть трафик через SNAT.

Альтернатива (и лучший подход на мой взгляд):

В зависимости от того, какой у вас веб-сервер (Apache, NGinx), вам следует рассмотреть возможность использования HTTP-прокси на своем интерфейсном сервере (192.168.12.87):

  • mod_proxy (Apache)
  • proxy_pass (NGinx)

 Другой вариант использования, для которого это будет полезно, - это если вам нужно временно перенаправить весь трафик, поступающий на одну службу, скажем, squid, на другой ip/порт, чтобы выполнить некоторое обслуживание исходной службы без необходимости перенастраивать всех клиентов.

 

Ответ 2

Причина, по которой, казалось бы, очевидное решение:

iptables -t nat -A PREROUTING -d 192.168.12.87 -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77

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

Вы можете настроить правила, при которых пакеты, отправляемые на 192.168.12.87, будут просто преобразовываться через NAT для 192.168.12.77, но затем c 192.168.12.77 будет отправлены ответы непосредственно обратно клиенту. Эти ответы не будут проходить через хост, на котором ваше правило iptables выполняет NAT, поэтому пакеты в одном направлении транслируются, а пакеты в другом - нет.

Есть три подхода к решению этой проблемы.

  1. На первом хосте выполняйте не только DNAT, но и SNAT, чтобы ответный трафик отправлялся обратно через первый хост. Правило может выглядеть примерно так

iptables -t NAT -A POSTROUTING -d 192.168.12.77 -p tcp --dport 80 -j SNAT --to-source 192.168.12.87

  1. Экспериментируйте с балансировкой нагрузки DSR и DNAT для пакетов на уровне Ethernet, а не на уровне IP. Заменив MAC-адрес назначения пакетов на MAC-адрес 192.168.12.77 и отправив его в Ethernet, не затрагивая IP-уровень, 192.168.12.77 может иметь 192.168.12.87, настроенный на фиктивном интерфейсе, и, таким образом, иметь возможность завершить TCP-соединение. с IP сервера, известным клиенту.

  2. Используйте простое (но не работающее) решение на первом хосте. Затем обработайте ответные пакеты на втором хосте, выполнив SNAT для обратного трафика. Правило может выглядеть так

iptables -t nat -A OUTPUT -p tcp --sport 80 -j SNAT --to-source 192.168.12.87

 

У каждого из этих трех решений есть недостатки, поэтому вам нужно внимательно подумать, действительно ли вам нужно выполнять эту конкретную переадресацию.

  1. Использование SNAT приведет к потере клиентского IP-адреса, поэтому хост 2 будет думать, что все подключения пришли с 192.168.12.87. Кроме того, вы будете использовать полосу пропускания через хост номер 1 для всех ответных пакетов, что будет иметь более прямой маршрут с другими подходами.

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

  3. Использование отслеживания соединений на одном хосте для перевода в одном направлении и отслеживания соединений на другом хосте для перевода в другом направлении просто некрасиво, и есть различные способы, из-за которых это может сломаться. Например, если номера портов изменены NAT на одном из узлов, нет способа восстановить их. Также не факт, что отслеживание соединения будет работать корректно, если первый пакет, который будет отправлен, будет SYN-ACK, а не ACK..

Я думаю, что из трех подходов наиболее вероятно сработает первый. Так что, если вам не нужно знать IP-адреса клиентов, я бы порекомендовал именно их.

Вы также можете полностью забыть о NAT и не пытаться решить проблему на уровне MAC или IP. Лучше пройти весь путь до уровня HTTP и найти там ответ. В этом случае решение, которое вы найдете, - это HTTP-прокси. Если вы установите HTTP-прокси на 192.168.12.87 и настроите его соответствующим образом, можно заставить его перенаправлять запросы на 192.168.12.77 и пересылать ответы обратно. Кроме того, он может вставлять заголовок X-Forwarded-For, сохраняющий исходный IP-адрес клиента. Затем необходимо настроить сервер на 192.168.12.77 для доверия заголовку X-Forwarded-For из 192.168.12.87.

Схожие статьи

Linux

Запуск jmap, получение которого невозможно без открытия файла сокета

Linux

Зачем менять порт ssh по умолчанию?

Linux

Как безопасно соединить две сети через интернет?

Linux

Как избежать сетевых конфликтов с внутренними сетями VPN?

×