Уявіце хост Linux, які завяршае VPN і адначасова запускае кантэйнер у сетцы macvlan. Лакальная сетка — 192.168.60.0/24, кантэйнер займае 192.168.60.210, а VPN-кліенты прыходзяць з 10.95.0.0/24. Кліент дасягае сэрвісу, адказ ніколі не вяртаецца, і кожнае правіла файрвола на хосце выглядае слушным. Гэты сімптом ствараюць дзве асобныя стрымлівальныя ўмовы, і выпраўленне адной з іх пакідае другую на месцы.

Дзве ўмовы, адзін сімптом

Першая ўмова — ізаляцыя: драйвер macvlan у Docker не дазваляе кантэйнеру размаўляць з уласным хостам праз бацькоўскі інтэрфейс. Трафік паміж стэкам хоста і кантэйнерам не мае шляху, як бы ні былі запісаны маршруты на хосце.

Другая ўмова — зваротны шлях. Шлюз па змаўчанні ў кантэйнера звычайна раўняецца маршрутызатару лакальнай сеткі, таму адказ, адрасаваны VPN-кліенту, выходзіць праз гэты маршрутызатар. Калі маршрутызатар не мае маршруту назад да пула VPN, адказ адкідаецца недзе пасярэдзіне.

З боку кліента гэтыя дзве паломкі выглядаюць аднолькава: запыт прыходзіць, а адказ не прыходзіць ніколі. Яны патрабуюць розных выпраўленняў, і шырокае правіла masquerade можа схаваць, якая з іх яшчэ зламаная. Таму першая праверка — гэта захоп на баку кантэйнера, а не чарговая змена файрвола. Калі запыт там не з’яўляецца зусім, значыць, дзейнічае ўмова ізаляцыі.

Пабудуйце пракладку на баку хоста, вузка

Другі інтэрфейс macvlan на хосце, далучаны да таго ж бацькоўскага інтэрфейса ў рэжыме моста, дае стэку хоста ўласную ідэнтычнасць у гэтым сегменце лакальнай сеткі. Зарэзервуйце для яго адрас па-за пулам DHCP і па-за дыяпазонам кантэйнераў, а праз пракладку накіроўвайце толькі кантэйнер.

ip link add macvlan-vpn link eth0 type macvlan mode bridge
ip address add 192.168.60.250/32 dev macvlan-vpn
ip link set macvlan-vpn up
ip route add 192.168.60.210/32 dev macvlan-vpn src 192.168.60.250

Першая каманда стварае інтэрфейс у рэжыме моста — гэта дакументаваная прадвызначаная налада для гэтага драйвера і менавіта той рэжым, які патрэбны для трафіку паміж хостам і кантэйнерам. Другая прызначае /32, каб адрас не супадаў з прэфіксам лакальнай сеткі, а чацвёртая накіроўвае праз пракладку толькі адрас кантэйнера.

Не перанакіроўвайце ўсю лакальную сетку праз новы інтэрфейс. Звычайны падключаны маршрут застаецца як ёсць, а маршрут хоста наўмысна вузкі, каб адзін кантэйнер атрымаў шлях, не змяняючы паводзіны астатняга сегмента. Маршрут па змаўчанні, накіраваны на пракладку, быў бы іншым рашэннем з іншымі наступствамі. Трымайце яго дакладным — і зона ўплыву застанецца малой.

Гэтыя каманды змяняюць сеткавыя налады на працуючым хосце. На апаратным прыстасаванні або кіраванай платформе выкарыстоўвайце падтрыманы механізм канфігурацыі гэтай платформы, бо інтэрактыўная змена праз root-shell можа не перажыць абнаўленне.

Вырашыце, як захаваць крыніцу

Калі пракладка на месцы, кантэйнер можа дасягнуць хоста, і пытанне пераўтвараецца ў тое, які адрас крыніцы нясе адказ. Захаванне зыходнай крыніцы VPN — больш чыстая мадэль: кантэйнер бачыць сапраўдны адрас кліента, і журналы сэрвісу разам з правіламі доступу могуць ім карыстацца.

Каб гэта працавала, сеткавая канфігурацыя кантэйнера павінна для гэтага шляху накіроўваць трафік 10.95.0.0/24 на 192.168.60.250 як на сваю браму. Гэта падтрыманая налада маршруту або брамы ўнутры ўласнай канфігурацыі кантэйнера, а не хітрасць на баку хоста. Пацвердзіце яе знутры кантэйнера, а не мяркуйце, што налада ўжо дзейнічае. Брама па змаўчанні, якая ўсё яшчэ паказвае на маршрутызатар лакальнай сеткі, будзе і далей адпраўляць адказы ў тую ж дзірку.

Калі зацверджанае рашэнне, наадварот, хавае крыніцы VPN, абмяжуйце пераўтварэнне вузка: сапраўдны пул VPN, пракладка як зыходны інтэрфейс і канкрэтны кантэйнер і сэрвіс.

iptables -t nat -A POSTROUTING -s 10.95.0.0/24 -o macvlan-vpn -j SNAT --to-source 192.168.60.250

Супастаўце пракладку як выходны інтэрфейс, а не тунель. Правіла, якое называе тунель выходным інтэрфейсам, не супадзе з пакетам, накіраваным да кантэйнера, і менавіта гэтую памылку звычайна змяшчае падобная схема. Трымайце правіла такім жа вузкім, як сказ вышэй, і пераглядайце яго, калі пул змяняецца.

Правярайце з боку кліента, а не хоста

Запыт ад самога хоста, прывязаны да адраса пракладкі, даказвае, што пракладка можа дасягнуць кантэйнера. Ён не даказвае, што кантэйнер можа вярнуць трафік да захаванай крыніцы 10.95.0.x, бо адрас крыніцы ў гэтай праверцы — уласны адрас пракладкі.

curl -sS --interface 192.168.60.250 -o /dev/null -w '%{http_code}\n' http://192.168.60.210:8080/health
sudo tcpdump -ni macvlan-vpn host 192.168.60.210

Першая каманда правярае звяно ад хоста да кантэйнера, а другая паказвае, што насамрэч праходзіць праз пракладку, пакуль сапраўдны VPN-кліент робіць запыт. Паглядзіце на адрас крыніцы на шляху ўваходу і на тое, ці з’яўляецца адказ у тым жа патоку.

На хосце трэба ўключыць перасыланне, і шляху перасылання патрэбны дазвол для пула VPN да пракладкі на порце сэрвісу, а таксама для ўсталяваных адказаў. Правіла INPUT на хосце не дазваляе перасылаемы трафік — гэта частая прычына таго, што пакет адкідаецца пасля таго, як маршрутызацыя выглядае слушнай.

Запусціце сапраўдную праграму з сапраўднымі ўліковымі данымі, затым праверце, што другая, не звязаная служба на тым жа кантэйнеры ўсё яшчэ адмаўляе вам. Калі адзіным спосабам прымусіць гэта працаваць было адкрыць усе правілы перасылання, рашэнне не завершана. Заўважце таксама, які адрас крыніцы запісаў сэрвіс, бо менавіта яго будуць выкарыстоўваць яго ўласныя правілы доступу.

Падобныя артыкулы