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

Исходный IP-адрес потерян из-за NAT IPTables на другой сервер

Я пытаюсь перенаправить весь HTTP-трафик с одного сервера EC2 linux (внешний IP-адрес 11.11.11.11) на другой (внешний IP-адрес 22.22.22.22), следующие правила:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 22.22.22.22:80
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
sudo service iptables save
sudo service iptables restart

Но при запуске CURL от клиента конечный сервер видит 11.11.11.11 как исходный IP-адрес запроса. Итак, я попробовал то, что предлагалось в аналогичном вопросе, добавил -d 11.11.11.11 к первой команде, так это выглядит так:

sudo iptables -t nat -A PREROUTING -d 11.11.11.11 -p tcp --dport 80 -j DNAT --to-destination 22.22.22.22:80

Но теперь попытка CURL до 11.11.11.11 приводит к Connection refused ошибка.

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

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

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

Вероятно, наиболее распространенный подход - это обратный прокси-сервер HTTP; Существуют HAProxy, squid, varnish, apache, nginx и многие другие решения этой проблемы. Они работают, вставляя новый заголовок, обычно X-Forwarded-For: в заголовки HTTP-запроса, идентифицируя клиента, подключающегося к целевому веб-серверу.

Это ваше самое простое решение. NAT не подходит для того, что вам нужно.

В качестве альтернативы, HAProxy и, возможно, некоторые другие платформы поддерживают то, что называется PROXY Протокол, который передает IP-адрес и порт клиента (а также исходный IP-адрес и порт назначения) в псевдо-внеполосном формате, прежде чем прорезать фактическую полезную нагрузку по соединению. в отличие от X-Fowarded-For: решение, которое может быть интерпретировано вашим приложением (путем доступа к заголовкам HTTP-запроса), если оно не поддерживается фактическим веб-сервером, PROXY Протокол требует, чтобы целевой сервер понимал этот протокол. С другой стороны, эта альтернатива работает с большинством протоколов на основе потоков TCP (в дополнение к http), поскольку не требует изменения самого запроса.