Сообраќајот на Docker контејнерите го заобиколува VPN-от на домаќинот: како да проверите
VPN-от на домаќинот го покрива само мрежниот простор на имиња на домаќинот. Со овие проверки утврдете дали сообраќајот на контејнерите на мостот влегува во тунелот или излегува директно.
Прелистувачот на домаќинот ја покажува излезната адреса на VPN-от, контејнерот пријавува вашата домашна врска, а некој тоа го нарекува истекување. Ништо не истече. Тунелот на домаќинот е збир од интерфејси, рути и правила што му припаѓаат на мрежниот простор на имиња на домаќинот, а контејнерот на мост е друг простор на имиња со своја стандардна рута. Сум седел на Compose стек каде VPN клиентот бил поврзан со недели и ниту еден контејнерски пакет никогаш не влегол во него.
Проверете го просторот на имиња пред иконата во системската лента
Просторите на имиња се целиот аргумент. Кога Docker стартува контејнер на мостовна мрежа, тој создава мрежен простор на имиња, прикачува еден крај од veth пар внатре во него и му дава на тој простор адреса и стандардна рута. Интерфејсот на тунелот, како и да се вика, живее во просторот на имиња на домаќинот. Сообраќајот внатре во контејнерот не може да го види, и ниту едно поставување на клиентот тоа не го менува однадвор.
Два поддржани чекори ве извлекуваат од изолацијата. --network host го става контејнерот во просторот на имиња на домаќинот, па тој ги наследува рутите на домаќинот и со тоа тунелот. --network container:vpn го дели просторот на имиња на друг контејнер, и токму така повеќето sidecar решенија испраќаат работно оптоварување низ VPN контејнер. Двете се експлицитни избори; обично само едниот од нив е она што го имал на ум лицето што распоредува.
Режимот на домаќин не е бесплатно надградување. Контејнерот престанува да има своја адреса, објавувањето порти престанува да важи, а процес што држи NET_ADMIN таму може да го препише рутирањето на домаќинот. Прифаќањето на тоа може да е вистинската одлука. Претпоставката дека веќе е вклучено е начинот на кој луѓето минуваат една вечер отстранувајќи грешки на тунел што никогаш не бил на патеката.
Следете го пакетот надвор од мостот
Контејнер на мост го испраќа својот пакет до својата стандардна порта, која е интерфејсот на мостот на домаќинот. Потоа домаќинот го препраќа пакетот и во стандардната конфигурација ја преведува изворната адреса во својата пред пакетот да излезе. Токму тој чекор на преведување тивко ја поразува политиката.
Додека пакетот стигне до крајната точка на тунелот, тој ја носи адресата на домаќинот. Секое правило, политичка рута или одлука за поделен тунел што се потпира на оригиналната адреса на контејнерот престанува да се совпаѓа, а два контејнера наменети да излезат низ различни излези не можат да се разликуваат само по изворот. Ако ви треба рутирање по контејнер, одлуката мора да се донесе пред преведувањето или во простор на имиња што го контролирате.
Docker сам ги одржува овие правила, преку кој и да е firewall backend со кој бил конфигуриран демонот. Правилата напишани рачно надвор од поддржаната кука за препратен сообраќај, 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 порта на домаќинот: препраќањето вклучено, префиксот на мостот насочен кон тунелот, повратниот сообраќај експлицитно обработен. Тоа купува контрола по мрежа и ве чини збир правила што треба да ги одржувате низ надградби на демонот и клиентот.
Како и да е, тестот што е важен е случајот на отказ. Запрете го тунелот со барање на контејнер во лет и гледајте каде оди пакетот. Ако се врати на директната патека, покривањето никогаш не било спроведено, зашто kill switch на клиентот управува со сопствениот сообраќај на клиентот, а не со препратените пакети од мост. Потоа рестартирајте ги демонот и домаќинот и потврдете го резултатот втор пат; тоа е моментот кога рачно напишаните правила исчезнуваат.
Пред да го наречете готово, потврдете четири работи: интерфејсот на тунелот е во истиот простор на имиња како сообраќајот, тестот на контејнерот се изведе внатре во вистинскиот контејнер, разрешувањето на имиња и двете семејства адреси беа проверени, и тестот на отказ на тунелот сѐ уште не успева затворено. Потоа запишете го firewall backend-от, верзијата на клиентот и сопственикот на секое правило. Токму тој запис спречува следната надградба да остави недокументирана смеса од стари претпоставки.