Трафік кантэйнераў Docker абыходзіць VPN хасцяра: як гэта праверыць
VPN хасцяра ахоплівае толькі прастору імёнаў хасцяра. Скарыстайцеся гэтымі праверкамі, каб высветліць, ці трапляе трафік кантэйнераў на мосце ў тунель, ці выходзіць наўпрост.
Браўзер на хасцяры паказвае адрас выхаду VPN, кантэйнер паведамляе пра ваша хатняе злучэнне, і нехта называе гэта ўцечкай. Нічога не ўцякло. Тунель хасцяра — гэта набор інтэрфейсаў, маршрутаў і правілаў, якія належаць сеткавай прасторы імёнаў хасцяра, а кантэйнер на мосце — гэта іншая прастора імёнаў са сваім маршрутам па змаўчанні. Я сядзеў на стэку Compose, дзе кліент VPN быў падключаны тыднямі, і ніводзін пакет кантэйнера так і не трапіў у яго.
Праверце прастору імёнаў раней за значок у трэі
Прастора імёнаў — гэта ўвесь аргумент. Калі Docker запускае кантэйнер у сетцы моста, ён стварае сеткавую прастору імёнаў, далучае адзін канец пары veth унутры яе і дае гэтай прасторы адрас і маршрут па змаўчанні. Інтэрфейс тунеля, як бы ён ні называўся, жыве ў прасторы імёнаў хасцяра. Трафік унутры кантэйнера не бачыць яго, і ніякая налада кліента не змяняе гэтага звонку.
Ёсць два падтрыманыя хады, каб выйсці з ізаляцыі. --network host змяшчае кантэйнер унутры прасторы імёнаў хасцяра, таму ён успадкоўвае маршруты хасцяра і, такім чынам, тунель. --network container:vpn абагульвае прастору імёнаў іншага кантэйнера, і менавіта так большасць архітэктур з бакавым кантэйнерам накіроўваюць нагрузку праз кантэйнер VPN. Абодва — відавочныя выбары; звычайна толькі адзін з іх ёсць тым, што меў на ўвазе чалавек, які разгортвае.
Рэжым хасцяра — не бясплатнае павышэнне. Кантэйнер перастае мець уласны адрас, публікацыя портаў перастае дзейнічаць, а працэс, які трымае NET_ADMIN там, можа перапісаць маршрутызацыю хасцяра. Прыняць гэта можа быць правільным рашэннем. Меркаваць, што гэта ўжо ўключана, — гэта тое, як людзі праводзяць вечар, адладжваючы тунель, якога ніколі не было на шляху.
Прасочыце пакет за межы моста
Кантэйнер на мосце адпраўляе свой пакет на шлюз па змаўчанні, якім з'яўляецца інтэрфейс моста на хасцяры. Затым хасцяр перасылае пакет і ў тыповай канфігурацыі транслюе адрас крыніцы ў свой уласны, перш чым пакет выйдзе. Менавіта гэты крок трансляцыі ціха знішчае палітыку.
Да таго часу, як пакет дасягне канчатковай кропкі тунеля, ён нясе адрас хасцяра. Любое правіла, палітычны маршрут або рашэнне аб раздзеленым тунелі, прывязанае да зыходнага адраса кантэйнера, перастае супадаць, і два кантэйнеры, прызначаныя выйсці праз розныя выхады, нельга адрозніць толькі па крыніцы. Калі вам патрэбна маршрутызацыя для кожнага кантэйнера, рашэнне павінна адбывацца да трансляцыі або ўнутры прасторы імёнаў, якой вы кіруеце.
Docker сам падтрымлівае гэтыя правілы, праз той бэкэнд фаервала, з якім быў наладжаны дэман. Правілы, напісаныя ўручную па-за падтрымліваным кручком для перасылаемага трафіку, DOCKER-USER, могуць быць перапарадкаваныя або скінутыя, калі дэман перазапускаецца або хасцяр абнаўляецца. Дакументацыя Docker па фільтрацыі пакетаў паказвае парадак ланцугоў; практычны момант у тым, што кожнае правіла патрабуе ўладальніка і шлях перазагрузкі, які вы сапраўды праверылі.
Праверце дзве сістэмы асобна
Доказы з адной прасторы імёнаў нічога не кажуць пра іншую. Запыт, выкананы ўнутры кантэйнера VPN, даказвае, што тунель працуе для гэтага кантэйнера. Гэта не доказ пра хасцяра, і тая ж каманда, выкананая з кантэйнера --network host, не з'яўляецца доказам пра мост.
# host namespace
ip route get 1.1.1.1
ip -brief addr show
# a fresh container on the same bridge network
docker run --rm --network appnet alpine sh -c 'ip route; cat /etc/resolv.conf; ip -6 route'
Затым паўтарыце тэст унутры сапраўднага кантэйнера праграмы, а не падобнага вобраза. Праграма можа несці дадатковы маршрут, зменную асяроддзя проксі або іншы рэзалвер, і кожнае з гэтага змяняе адказ. Правярайце развязанне імёнаў і другое сямейства адрасоў кожны раз: кантэйнеры на мастах, вызначаных карыстальнікам, развязваюцца праз убудаваны рэзалвер Docker па адрасе 127.0.0.11, а маршрут па змаўчанні IPv6 на мосце можа выносіць трафік вонкі, пакуль вы занятыя тэставаннем тунеля толькі для IPv4.
Прачытайце заканамернасць, перш чым кранаць уліковыя даныя
Калі хасцяр працуе, а кантэйнер не, прычына амаль заўсёды структурная, і перазапуск ключоў або пераўстаноўка кліента марнуе палову дня. Спачатку ўпарадкуйце сімптом, і выпраўленне звычайна само сябе называе.
| What you see | Usual cause | First check |
|---|---|---|
| Host exits through the VPN, container shows the ISP address | The container never entered the tunnel | Default route inside the container |
| Container works until the daemon restarts, then stops | Rules outside the supported hook, or a changed backend | Daemon's reported firewall backend and DOCKER-USER |
| Container loses internal hosts after the tunnel comes up | VPN prefix overlaps the Docker bridge subnet | ip route on the host, then docker network inspect |
| Small replies arrive, large ones hang | Tunnel MTU or missing MSS clamping | Link MTU on both ends of the tunnel |
| Container falls back to the ISP address when the tunnel drops | Nothing enforces the kill switch for forwarded traffic | Stop the tunnel with a request in flight |
Радок пра перакрыццё заслугоўвае асобнага сказа. Профіль VPN, які праштурхоўвае маршрут для 172.17.0.0/16 або для 10.0.0.0/8, які выпадкова змяшчае прэфікс вашага моста, прымушае тунель прэтэндаваць на падсетку кантэйнераў, і адказы на трансяваныя адрасы пачнуць ісці ў няправільным кірунку або знікнуць. Перанумараваць сетку Docker звычайна чысцей, чым назапашваць выключэнні.
Зрабіце пакрыццё відавочным, а затым зламайце яго наўмысна
Дзве архітэктуры вытрымліваюць разгляд. Абагуліце прастору імёнаў кантэйнера VPN, і кожная ахопленая нагрузка выкарыстоўвае адзін тунель з адной мяжой перазапуску, што проста, пакуль адной службе не спатрэбіцца іншы выхад або ўласны шлях DNS. Або накіруйце сетку кантэйнераў на шлюз VPN на хасцяры: перасылка ўключана, прэфікс моста накіраваны на тунель, зваротны трафік апрацаваны відавочна. Гэта дае кантроль для кожнай сеткі і каштуе вам набор правілаў, які трэба падтрымліваць падчас абнаўленняў дэмана і кліента.
Так ці інакш, важны тэст — гэта выпадак збою. Спрычыніце тунель з запытам кантэйнера ў палёце і паглядзіце, куды ідзе пакет. Калі ён вяртаецца на прамы шлях, пакрыццё ніколі не было забяспечана, бо перамыкач забівання кліента кіруе ўласным трафікам кліента, а не перасылаемымі пакетамі з моста. Пасля гэтага перазапусціце дэман і хасцяра і пацвердзіце вынік другі раз; менавіта ў гэты момант знікаюць правілы, напісаныя ўручную.
Перш чым назваць гэта завершаным, пацвердзіце чатыры рэчы: інтэрфейс тунеля знаходзіцца ў той жа прасторы імёнаў, што і трафік, тэст кантэйнера выконваўся ўнутры сапраўднага кантэйнера, развязанне імёнаў і абодва сямействы адрасоў былі правераныя, і тэст збою тунеля па-ранейшаму праходзіць закрыта. Затым запішыце бэкэнд фаервала, версію кліента і ўладальніка кожнага правіла. Менавіта гэты запіс не дазваляе наступнаму абнаўленню пакінуць недакументаваную сумесь старых здагадак на месцы.