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

77

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

Как это сделать с помощью iptables?

Или же

Есть ли другие способы добиться того же?

сидел
источник
@ Matthewlfe, по какой-то причине мне нужно перенаправить все запросы apache из (192.168.12.87) в (192.168.12.77).
Сидел
1
@ Matthewlfe, у меня есть два производственных сервера. Один связан с публичным статическим IP-адресом. Из-за некоторых проблем с подключением я не могу подключиться к БД и другим системам 192.168.12.87. Итак, мне нужно отправить все запросы 192.168.12.77.
Сидел
@lain, я не знаком с iptables. И я видел несколько примеров. Но, похоже, требуется два Ethernet. Ссылка: revsys.com/writings/quicktips/nat.html
сидел
Вы также можете использовать прокси-режим в конфигурации вашего веб-сервера для отправки запросов на 192.168.12.77 с 192.168.12.87 (если ваш веб-сервер поддерживает это)
krisFR

Ответы:

75

Эти правила должны работать, предполагая, что 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):

krisFR
источник
Работает до тех пор, пока UFW отключен, хотя порт в UFW разрешен, но если UFW включен, эта функция переадресации не работает, вы понимаете?
Судхир N
1
Отличный вопрос с отличным ответом. Другой вариант использования, для которого это полезно, - это если вам нужно временно перенаправить весь трафик, приходящий к одному сервису, скажем, squid, на другой ip / порт, чтобы выполнить некоторое обслуживание оригинального сервиса без необходимости перенастраивать все клиенты! Очень удобно!
PF4Public
3
«но вам также нужно SNAT трафика обратно». -> Ты спас мой день. Спасибо
обейхан
Это решение не работает для меня. Мне нужно перенаправить из eth0 в виртуальную сеть (virb0), которая используется KVM-гостем. Я попытался добавить опции -i и -o, но -o не разрешен для предварительной маршрутизации. Какие-либо предложения?
lostiniceland
Будьте осторожны с этим решением. Теперь я полностью потерял доступ к своей удаленной машине.
Сёрен
28

Причина, по-видимому очевидная 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, но затем 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
  2. Вдохновитесь балансировкой нагрузки DSR и DNAT пакетов на уровне Ethernet, а не на уровне IP. Заменив MAC назначения пакетов на MAC 192.168.12.77 и отправив его по Ethernet, не касаясь уровня IP, тогда 192.168.12.77 может иметь 192.168.12.87, настроенный на фиктивном интерфейсе, и, таким образом, сможет разорвать соединение TCP с IP-адресом сервера, известным клиенту.
  3. Используйте наивное (но не работающее) решение на первом хосте. Затем обработайте ответные пакеты на втором хосте, выполнив 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.

kasperd
источник
Я удивлен, что -j MASQUERADEздесь не упоминается; Разве это не обычный подход с DNAT?
Ремрам
3
@remram Я упоминал SNATвместо MASQUERADE, потому что это то, что говорится в документации. Точная формулировка в документации:It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target.
kasperd