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

Iptables не перенаправляет ssh-доступ экземпляру в публичной подсети

У меня такой сценарий:

1 - Экземпляр бастиона (NAT), который я использую в качестве шлюза для перенаправления доступа ssh ко всем моим частным экземплярам (с использованием iptables) [Частный IP: 10.10.1.10 Общедоступный IP: 200.147.160.24]

2 - Публичный экземпляр под тем же vpc (но не в той же подсети) в качестве моего экземпляра-бастиона (который использует интернет-шлюз) [Частный IP: 10.10.9.23 Общедоступный IP: 186.192.90.5]

Я хотел бы получить доступ к своему общедоступному экземпляру (2) через iptables вперед в бастионе (1), но я могу это сделать. Это приводит к таймауту. (все остальные форварды в частные экземпляры работают).

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

Это правило iptables, которое я использую в своем бастионе:

iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 1500 -j DNAT --to-destination 10.10.9.23:22

Это работает: ssh user@186.192.90.5

Это работает (внутри бастиона (1)): ssh user@10.10.9.23

Это не работает (тайм-аут): ssh -p 1500 user@200.147.160.24

Любые мысли приветствуются.

У вас здесь ситуация с асимметричной маршрутизацией, включающая NAT, и это не сработает.

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

Назовем клиентскую машину C, бастион B, и целевой экземпляр T.

Поступает трафик: исходный IP = C, целевой IP = B.

B переводит: IP-адрес источника = C, IP-адрес назначения = T. Отправить в T.

T принимает: IP-адрес источника = C, IP-адрес назначения = T.

T отвечает: исходный IP = T, целевой IP = C.

Куда уходит ответный трафик? Не в бастион - он идет к Интернет-шлюзу ... пакет ответа на поток TCP, о котором шлюз никогда не слышал. Шлюз по всем правилам должен отбросить его или послать TCP RST отправляющему экземпляру T, чтобы разорвать это недопустимое соединение.

Клиент C не должен видеть этот ответ, но даже если он это сделал, клиент теперь видит ...

Исходный IP = T, целевой IP = C.

Этого не ожидает ни клиент, ни какие-либо промежуточные межсетевые экраны с отслеживанием состояния, поэтому трафик отбрасывается или отклоняется.

С вашими машинами с частным адресом их маршрут VPC по умолчанию (я предполагаю) указывает на хост-бастион, поэтому здесь нет асимметричной ситуации. Бастион может переводить адреса в обратном направлении на обратном пути в C, и все работает.

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

Оставив DNAT правило на месте, вам понадобится что-то вроде этого ...

iptables -t nat -A POSTROUTING -d 10.10.9.23/32 -p tcp --dport 22 -j SNAT 

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

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

Другой способ добиться этого - использовать HAProxy на бастионе. Исходный адрес, видимый T-сервером, по-прежнему будет внутренним адресом хоста-бастиона ... но теперь у вас есть хорошие файлы журнала на хосте-бастионе для отслеживания IP-адресов. В случае, если мне нужно было открыть внутреннюю службу TCP для Интернета, это мой предпочтительный подход, а не DNAT, поскольку прокси-сервер предоставляет доступ к журналам, контролю доступа и статистике подключений. (HAProxy является одновременно балансировщиком нагрузки с поддержкой HTTP и балансировщиком нагрузки TCP, не зависящим от полезной нагрузки. Я не связан с продуктом, просто фанат).

Я не уверен, что происходит, но подозреваю, что проблема / несоответствие маршрутизации возможны. Вы пробовали использовать такой инструмент, как tcpdump, чтобы проверить, доставляются ли пакеты и какой маршрут проходит?