Назад | Перейти на главную страницу

Как перенаправить / NAT весь трафик на один интерфейс / IP-адрес на удаленный IP-адрес?

У меня есть один "сервер A", к которому подключено несколько IP-адресов, например:

eth0:0 1.1.1.1
eth0:1 1.1.1.2
eth0:2 1.1.1.3

У меня есть еще один «сервер B», к которому также подключено несколько IP-адресов, например:

eth0:0 2.2.2.1
eth0:1 2.2.2.2
eth0:2 2.2.2.3

Теперь я хочу настроить iptables на «сервере A» для пересылки / NAT всего входящего трафика на «eth0: 2» на IP 2.2.2.3 на «сервере B».

Я проверил, что «Сервер A» может «разговаривать» с «Сервером B» по IP 2.2.2.3. Ping и telnet для открытия портов работают нормально, и у меня включен флаг пересылки (net.ipv4.ip_forward = 1)

Я пробовал несколько разных способов, DNAT, SNAT, MASQUERADE и т. Д., Но у меня ничего не работает.

Эта строка отлично работает, если я пытаюсь перенаправить трафик между IP-адресами на ОДНОМ сервере:

iptables -t nat -A PREROUTING -d 1.1.1.3 -j DNAT --to-destination 1.1.1.2

Но если я отключу «1.1.1.2» на «2.2.2.3», это не сработает.

Я предполагаю, что мне нужно второе правило iptable, чтобы решить эту проблему. Я безуспешно пробовал со следующими правилами POSTROUTING (не одновременно):

iptables -t nat -A POSTROUTING -d 2.2.2.3 -j MASQUERADE
iptables -t nat -A POSTROUTING -d 2.2.2.3 -j SNAT --to 1.1.1.3
iptables -t nat -A POSTROUTING -j MASQUERADE

Что мне не хватает?

РЕДАКТИРОВАТЬ 1:

Я наконец заставил его работать, используя следующее:

net.bridge.bridge-nf-call-iptables=0

iptables -t nat -A PREROUTING -d 1.1.1.3 -j DNAT --to-destination 2.2.2.3
iptables -t nat -A POSTROUTING -d 2.2.2.3 -j SNAT --to 1.1.1.3

Однако теперь возникла другая проблема. Все журналы и т. Д. На сервере 2.2.2.3 показывают, что ВЕСЬ трафик теперь исходит из 1.1.1.3, например журналы apache, почтовые журналы и т. Д. Я предполагаю, что это природа NAT.

Однако, когда я выполняю стандартную переадресацию портов на моем домашнем маршрутизаторе на свой ноутбук, на котором запущен apache, я вижу в журналах исходный «IP-адрес запрашивающей стороны». Итак, как роутер это делает? И как я могу сделать то же самое при настройке моего сервера?

В итоге, я хочу перенаправить весь трафик с сервера A (1.1.1.3) на сервер B (2.2.2.3), НО я также хочу видеть, откуда пришел трафик на сервере B (2.2.2.3), т.е. журналы apache должны показывать исходный IP-адрес запрашивающей стороны.

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

Еще одна вещь: IP-адреса, подключенные к серверу A и серверу B, ЗАБЛОКИРОВАНЫ для каждого соответствующего сервера. Таким образом, Сервер A НЕ может отправлять трафик с IP 2.2.2.3. Он заблокирован моим провайдером в роутере.

Краткий ответ на ваш измененный вопрос: есть два способа сделать это; оба требуют, чтобы вы удалили второй шаг NAT (который уничтожает информацию, которую вы ищете). Ваши варианты после этого:

1) Сделайте сервер A следующим переходом для сервера B для рассматриваемого трафика, поэтому он работает для вашего маршрутизатора, как упоминалось. Этого можно достичь, в порядке непонятности, сделав сервер A маршрутом по умолчанию для сервера B или используя политика маршрутизации, или используя какие-то причудливые iptables, или используя какой-то туннель.

2) «Вручную» реверсирование NAT сервера A на сервере B, что приводит к асимметричному потоку трафика (обычно не рекомендуется). Что-то вроде iptables -t nat -I POSTROUTING -j SNAT -s 2.2.2.3 --to 1.1.1.3

Я уверен в варианте (1) на 100%. Я примерно на 90% уверен в (2).

Чтобы понять это, нужно понимать поток трафика.

  1. Клиент X отправляет пакет в 1.1.1.3.
  2. Сервер A преобразует получатель этого пакета через NAT до 2.2.2.3 предварительной маршрутизации, затем направляет трафик на 2.2.2.3, затем NAT преобразует источник этого пакета в пост-маршрутизацию 1.1.1.3, затем отправляет пакет на сервер B.
  3. Сервер B получает пакет на 2.2.2.3 и видит адрес источника 1.1.1.3 на втором этапе NAT. Он обрабатывает пакет и отправляет ответ обратно его источнику (1.1.1.3).
  4. Сервер A получает пакет на 1.1.1.3, меняет исходный NAT, маршрутизирует пакет, меняет NAT назначения и отправляет пакет обратно клиенту X.
  5. Клиент X получает ответ от 1.1.1.3

А теперь представим, что было бы, если бы у вас не было второго NAT:

  1. Клиент X отправляет пакет в 1.1.1.3.
  2. Сервер A NAT преобразует получатель этого пакета в предварительную маршрутизацию 2.2.2.3, затем направляет трафик в 2.2.2.3, но оставляет адрес источника как X, когда он отправляет пакет на сервер B.
  3. Сервер B получает пакет на 2.2.2.3 и видит адрес источника X. Он обрабатывает пакет и отправляет ответ обратно своему источнику X.
  4. Клиент X получает ответ от 2.2.2.3 и отбрасывает его, потому что он не знает 2.2.2.3 от Адама!

Чтобы клиент X мог понять пакет, он должен прибыть к клиенту X с тем же адресом источника, что и место назначения исходного пакета.

Обычно это происходит, когда сервер B имеет возможность отменить предварительную маршрутизацию NAT. Чтобы это произошло, вам нужно, чтобы пакет прошел через него позже. В настоящее время вы делаете это, изменяя адрес источника пакета, но это уничтожает информацию, которую вы запрашиваете в пересмотренном вопросе.

Итак, первый шаг вашего ответа: вы не можете выполнить второй шаг NAT (пост-маршрутизация SNAT): на сервере A запустить iptables -t nat -D POSTROUTING -j SNAT --to 1.1.1.3.

Теперь перед вами стоит задача отменить первый шаг NAT.

Если сервер B собирается это сделать, вам нужен сервер B для приема пакетов.

  • Это относительно просто, если сервер A имеет адрес C в той же локальной сети, что и сервер B. На сервере B: ip route replace default via C, ИЛИ ip route add default via C table a; ip rule add from 2.2.2.3 table a.
  • В противном случае с туннелями придется потрудиться.

Если, однако, маршрутизатор в местоположении Сервера B не особенно сложен (постоянно проверяет пакеты и отклоняет те, которые не находятся в правильной последовательности для известного потока трафика), у вас есть несколько более простой, хотя и супер-уродливый вариант: изменить NAT на сервере B на основе ваших знаний о том, что было сделано на сервере A: на сервере B iptables -t nat -I POSTROUTING -j SNAT -s 2.2.2.3 --to 1.1.1.3 следует сделать это на предложенном примере. Это оставит систему отслеживания соединений Linux в A и B несколько сбитой с толку (серверы не смогут связать обратный трафик с входящим, поэтому их отслеживание соединений оставит соединения в состоянии UNREPLIED), но это должно нормально работать для большей части трафика в сотни мегабит.

Последний раз пройти через транспортный поток в этом случае:

  1. Клиент X отправляет пакет в 1.1.1.3.
  2. Сервер A NAT преобразует пункт назначения этого пакета в предварительную маршрутизацию 2.2.2.3, затем направляет трафик в 2.2.2.3, но оставляет адрес источника как X, когда он отправляет пакет на сервер B.
  3. Сервер B получает пакет на 2.2.2.3 и видит адрес источника X. Он обрабатывает пакет и направляет ответ обратно своему источнику X, но перед его отправкой NAT после маршрутизации отправляет адрес источника на 1.1.1.3. .
  4. Клиент X получает ответ от 1.1.1.3 и доволен.

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

Во-первых, в ядре должна быть включена пересылка пакетов (по умолчанию это не так):

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

Вам также необходимо убедиться, что iptables разрешает прямой трафик (посмотрите на вашу цепочку FORWARD).

Этого и правила DNAT должно быть достаточно, чтобы пакет шел в одном направлении. Однако, если вам нужен поток TCP, вы также должны убедиться, что у вас также есть упомянутые вами правила SNAT (в противном случае удаленный хост будет думать, что существует проблема, поскольку сервер в 2.2.2.3 отвечает на отправленный им пакет. как 1.1.1.3).

Кстати, по соображениям производительности лучше использовать SNAT вместо MASQUERADE, если у вас статический IP.