DNAT във VPN контейнер: препращане, а не INPUT
След DNAT заявката към адреса на тунела става препратен трафик. Ограничете правилото за препращане, прочетете веригата на Docker и изберете обратен път нарочно.
Заявката пристига с адрес на 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 към шлюза на моста не е тест за приемане на услугата.
Дръжте правилата в поддържаната конфигурация за стартиране на контейнера, защото интерактивните промени изчезват при пресъздаването му. Публикуването на порт на хоста е друг път за излагане и не е необходимо само защото услугата е достъпна през тунела.