Чтобы лучше понять, как работают AWS VPC (и NAT в целом), я читал этот вопрос, цель которого заключалась в следующем:
# GOAL
172.31.0.0/16 local
A.B.C.D/32 nat-451b3be9
0.0.0.0/0 igw-b4ac67d0
Вот что меня заинтриговало:
Обратите внимание, что конфигурация, которую вы пытаетесь выполнить, разрешает исходящие, но никогда не разрешает входящие подключения (инициированные извне) с адреса A.B.C.D к чему-либо в этой подсети, поскольку обратный маршрут асимметричен через шлюз NAT.
Шлюз NAT не предназначен для создания в какой-либо подсети, для которой он предоставляет услуги NAT. Экземпляры достигают внешних ресурсов через таблицу маршрутов своей подсети (указывает на NAT-GW для экземпляров без общедоступного IP-адреса, указывает на IGW для экземпляров с общедоступным IP-адресом), а NAT-GW выходит в Интернет через свою таблицу маршрутов подсети (указывает на IGW).
Если экземпляр использует свой собственный общедоступный IP-адрес, он должен направлять ответы через IGW, потому что именно отсюда поступает входящий трафик, и он не может пытаться уйти через NAT-GW, потому что внешний узел увидит ответ. поступает с неправильного IP-адреса источника, если трафик был переведен.
Я пытаюсь понять, почему он разрешает исходящий, но не входящий трафик. Вот что я думаю: предположим, что экземпляр EC2 имеет эластичный IP-адрес и находится в подсети с таблицей маршрутизации, как указано выше. Тогда NAT находится в отдельной подсети. Сказать A.B.C.D
инициировал соединение с эластичным IP-адресом EC2. Разве соединение не войдет в VPC, таблица маршрутизации отправит его через NAT, который затем перейдет к экземпляру, а затем вернется через NAT? Однако, поскольку он был отправлен через NAT, адрес был преобразован (как сказано выше), и одноранговый узел отбросил бы пакет, поскольку он пришел не с IP-адреса экземпляра EC2. Это правильное понимание? Он все равно достигнет экземпляра EC2, но ответные пакеты никогда не будут получены A.B.C.D
?
Интернет-шлюз логически обеспечивает преобразование адресов от имени вашего экземпляра, поэтому, когда трафик покидает вашу подсеть VPC и переходит в Интернет, в поле адреса ответа устанавливается общедоступный IPv4-адрес или эластичный IP-адрес вашего экземпляра, а не его частный Айпи адрес. Когда трафик поступает в VPC, он преобразует общедоступный IP-адрес обратно в частный адрес экземпляра и отправляет запрос на маршрутизатор VPC, который направляет пакет в экземпляр.
Однако для исходящего трафика маршрутизатор VPC выбирает наиболее конкретный маршрут и пересылает пакеты на NAT GW, который выполняет преобразование адресов и отправляет пакеты в IGW (через маршрутизатор VPC). IGW затем заменяет адрес назначения общедоступным IP-адресом NAT GW. Пир разорвет соединение, поскольку IP-адреса не совпадают.
Если соединение инициируется партнером:
Одноранговый узел -> (общедоступный IP-адрес EC2) -> IGW -> (частный IP-адрес EC2) -> EC2
Если соединение инициируется EC2:
EC2 -> (IP-адрес назначения) -> NAT GW -1-> IGW -2-> Peer
Во втором случае трансляция адресов происходит дважды:
Допустим, A.B.C.D инициировал соединение с эластичным IP-адресом EC2. Разве соединение не входило бы в VPC, таблица маршрутизации отправила бы его через NAT ...
Нет, по двум причинам:
Таблицы маршрутов VPC касаются только место назначения адреса в пакетах - не адреса источника.
Входящий трафик фактически не сверяется с таблицей маршрутов VPC. Таблицы маршрутов VPC прикреплены к подсетям и используются для выбора маршрута для пакетов, поступающих с компьютеров в подсетях, прикрепленных к таблице маршрутизации, путем поиска шлюза назначения в таблице.
Когда трафик поступает в VPC извне, интернет-шлюз переводит адрес назначения пакета из EIP экземпляра в частный IP-адрес экземпляра, и поиск в таблице маршрутов не используется - IGW отправляет трафик непосредственно экземпляру.
Затем экземпляр ответит, и адрес назначения внешнего компьютера - через поиск в таблице маршрутов VPC - приведет к отправке ответов устройству NAT, что приведет к описанной асимметрии.
Другими словами, единственные входящие пакеты, которые отправляются через шлюз NAT, - это пакеты, адресом назначения которых является EIP шлюза NAT.
У меня была точно такая же проблема. Это можно предотвратить с помощью балансировщика нагрузки, который не использует ту же таблицу маршрутов, что и ваши серверы приложений.
Например, если вы хотите, чтобы серверы приложений перенаправляли запросы к внешним службам через шлюз NAT, введите новую таблицу маршрутизации, которая только используется серверами приложений.
# app server route-table
172.31.0.0/16 local
A.B.C.D/32 nat-451b3be9
0.0.0.0/0 igw-b4ac67d0
Исходящие запросы от серверов приложений теперь будут маршрутизироваться через шлюз NAT для IP A.B.C.D.
Входящие запросы к серверам приложений должны маршрутизироваться через балансировщик нагрузки. Балансировщик нагрузки (и, возможно, остальная часть вашей инфраструктуры) должен использовать таблицу маршрутов по умолчанию, которая не ссылается на шлюз NAT:
# default route-table
172.31.0.0/16 local
0.0.0.0/0 igw-b4ac67d0
Затем любые входящие запросы будут маршрутизироваться следующим образом: удаленный хост -> балансировщик нагрузки -> сервер приложений -> балансировщик нагрузки (поскольку он использует локальный IP-адрес LB) -> удаленный хост - без прохождения через шлюз NAT.