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

Перенаправление порта на экземпляр без общедоступного IP-адреса в подсети

Классический способ сделать это с помощью iptables DNAT и включения пересылки IPv4 с помощью syctl, похоже, работает. Документация Google также предполагает это.

Однако все трафик, поступающий на внутреннюю виртуальную машину, похоже, исходит из головного узла (исходный IP заменен на локальный IP головного узла). Излишне говорить, что это ломает многие вещи, потому что серверная виртуальная машина не знает, откуда происходит соединение (например, для целей идентификации и ведения журнала).

Правило перенаправления порта 8000 на бэкэнд:

iptables -t nat -A PREROUTING -p tcp -i eth0 -d <1-local> --dport 8000 -j DNAT --to-destination <2-local>

Правило исходящего трафика обратно на головной узел:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Обозначения: <1-local> = локальный IP-адрес головы, <2-local> = локальный IP-адрес серверной ВМ

Обратите внимание, что маршрут был добавлен в сеть для исходящего трафика согласно документации Google (работает нормально). Я понимаю, что в разделе «Балансировка нагрузки» есть очень обширная функция перенаправления портов, но, честно говоря, я понятия не имею, как ее использовать в таком простом случае, как этот.

Как мне убедиться, что исходные исходные IP-адреса сохранены? Я что-то упускаю, или это «особенность» подсетей GCE?

Наконец я нашел решение и успешно протестировал его в производственной сети.

Проблема с переадресацией портов в GCE заключается в том, что экземпляры имеют только один сетевой интерфейс, поэтому пакеты, пересылаемые с помощью DNAT, заменяют свой исходный IP-адрес на SNAT немедленно, когда они проходят через цепочку POSTROUTING. Поскольку это происходит до того, как они достигнут своего экземпляра назначения, похоже, что DNAT не работает. Исправление теперь состоит в том, чтобы защитить перенаправленные пакеты после DNAT от немедленного SNAT, пропустив это правило в POSTROUTING. Второе правило ниже делает именно это:

iptables -t nat -A PREROUTING -i eth0 -p tcp -d <1-local> --dport 8000 -j DNAT --to-destination <2-local>
iptables -t nat -A POSTROUTING -o eth0 -p tcp -d <2-local> --dport 8000 -j RETURN

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

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source <1-local>

Сетевой шлюз заменяет <1-local> общедоступным IP-адресом перед отправкой пакетов обратно в Интернет.

Обратите внимание, что необходимо добавить правило брандмауэра GCE, чтобы разрешить все перенаправленные порты из любого места, как на головном (бастион), так и на внутреннем экземпляре.

Это решение обеспечивает переадресацию портов на серверные экземпляры без общедоступного IP-адреса, в то время как эти экземпляры также имеют полный доступ к Интернету. Для последнего также требуется, чтобы для головного узла была включена переадресация IP, а в подсеть был добавлен маршрут по умолчанию, как описано здесь: https://cloud.google.com/compute/docs/networking в разделе «Настроить NAT-шлюз».

Вы можете использовать HTTP Load Balancer с целевым прокси-сервером и сохранить IP-адрес клиента из поля X-Forwarded в заголовке запроса. Более подробную информацию об этом можно найти в Справочном центре. статья.

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

Вы можете создать несколько балансировщиков нагрузки, используя один общедоступный IP-адрес, если эти балансировщики нагрузки используют разные номера портов.

Балансировщик нагрузки UDP или TCP только с одним сервером и без проверки работоспособности очень похож на традиционную переадресацию портов.