Запрос приходит с адресом IP туннеля и покидает тот же контейнер с адресом соседнего сервиса. Между этими двумя моментами DNAT переписал назначение, и пакет перестал быть входным для контейнера VPN. Теперь это пересылаемый трафик, оцениваемый другим правилом. Это изменение объясняет, почему правило брандмауэра, которое выглядит верным для адреса туннеля, не влияет на преобразованное соединение.

Проследите пакет после преобразования

Возьмите пул клиентов 10.90.0.0/24 и адрес туннеля 10.90.0.1. Два контейнера стоят на одном мосту: 192.0.2.2 запускает VPN, а 192.0.2.3 запускает приложение. Клиент подключается к 10.90.0.1:8080, и правило DNAT в пространстве имён контейнера VPN переписывает это на реальный адрес и порт приложения. Затем маршрут отправляет пакет через мост. Эти адреса иллюстративны, это не рецепт развёртывания.

Порт, на котором приложение действительно слушает, может отличаться от любого порта, опубликованного на хосте. Читайте слушателя внутри контейнера, а не предполагайте, что оба числа совпадают.

Разрешение относится к пути пересылки

Контейнеру VPN нужна пересылка IP и решение о пересылке, ограниченное пулом клиентов, адресом приложения и нужным портом. Установленным ответам нужно собственное разрешение. Правило, совпадающее с исходным адресом туннеля, не совпадёт после DNAT, потому что назначение уже изменилось. Разрешение INPUT — неправильный хук для трафика, который больше не адресован этому хосту.

Держите область узкой: один диапазон источников, одно назначение, одна служба. Разрешающее правило пересылки легче написать и гораздо труднее защитить потом.

docker exec vpn-container ip route get 192.0.2.3
docker exec vpn-container iptables -t nat -S
docker exec vpn-container iptables -S FORWARD

Цепочки Docker — не цепочки вашего контейнера

Правила внутри пространства имён контейнера — не правила хоста Docker. Когда трафик переходит с интерфейса туннеля на мост, брандмауэр моста на хосте может принять другое решение. При бэкенде iptables в Docker документированные цепочки пересылки и точки сопоставления после DNAT — это место, где такое решение появляется.

Справочник Docker по брандмауэру описывает эти цепочки и сопоставление после DNAT. Не исправляйте отсутствующее разрешение отключением управления брандмауэром Docker или разрешением каждой цепочки, потому что это убирает границу, которую вы пытаетесь использовать.

Сделайте обратный путь осознанным выбором

Если адрес источника сохраняется, приложение видит 10.90.0.x и должно направлять ответы обратно через контейнер VPN. Иначе его обычный шлюз Docker отправит их на хост, который не владеет туннелем. Альтернатива — узко ограниченное преобразование источника в контейнере VPN, которое упрощает ответ, но скрывает клиента от приложения. Выбирайте осознанно и запишите, что выбрали.

Проверьте новое разрешённое соединение с обычного клиента, затем убедитесь, что несвязанные порты остаются закрытыми. Когда пакет исчезает, изучите пространство имён VPN, пространство имён приложения и собственный журнал приложения. Ping до шлюза моста не является приёмочным тестом службы.

Держите правила в поддерживаемой конфигурации запуска контейнера, потому что интерактивные правки исчезают при его пересоздании. Публикация порта на хосте — другой путь воздействия, и она не нужна только потому, что служба доступна через туннель.

Похожие статьи