Docker контейнер VPN-ийн цаана байгаа хост руу яагаад хүрэхгүй вэ
Гүүрэн контейнерууд өөрийн нэрний орон зайтай тул хостны туннель тэдэнд харагдахгүй. DNS-ийг өөрчлөхөөс өмнө хостны сүлжээ, tun төхөөрөмж, macvlan-ыг харьцуулна уу.
Корпорацийн VPN-ийн цаана юунд ч хүрч чаддаггүй контейнер ихэвчлэн туннелээс өөр сүлжээний нэрний орон зайд амьдардаг. Хост клиентийн маршрут, DNS сервер, галт хананы тэмдэглэгээ нь хостны стект хамаарна; гүүрэн сүлжээний контейнер өөрийн стектэй. Энэ нэг баримт платформ багт ирдэг тайлангийн ихэнхийг тайлбарлаж, «VPN эвдэрсэн» ба «Docker VPN-ийг тойрч гардаг» хоёулаа нэгэн зэрэг буруу байж болох шалтгаан болдог. Нэг шинж тэмдгийн цаана хоёр огт өөр тохиргоо нуугдаж байгаа тул ямар нэг тохиргоог өөрчлөхөөс өмнө аль нь таных болохыг тодорхойлно уу.
Туннель хэний нэрний орон зайд хамаарахыг олж мэдээрэй
macOS эсвэл Windows-ийн Docker Desktop дээр контейнерууд Linux виртуал машины дотор ажилладаг. Ажлын ширээн дээр суулгасан VPN клиент ажлын ширээний үйлдлийн системд туннель үүсгэдэг бөгөөд виртуал машин үүнийг хэзээ ч хардаггүй. Ямар ч контейнерын тохиргоо үүнийг засдаггүй, учир нь контейнерт хэрэгтэй интерфейс түүний сүлжээний нэрний орон зайд огт байхгүй.
Linux хост дээр туннель хостны нэрний орон зайд амьдардаг бөгөөд гүүрэн контейнерууд ихэвчлэн гарах замд эх сурвалжийн NAT хэрэглэсэн хостны маршрутжуулалтын хүснэгтээр дамжин хүрдэг. Тэр зам бүтэлгүйтэх үед шалтгаан нь ихэвчлэн дутуу маршрут биш, харин дамжуулах бодлого, урвуу замын шүүлтүүр эсвэл давхцсан дэд сүлжээ байдаг. Цааш уншихаас өмнө хоёр ертөнцийн алинд нь байгаагаа батална уу:
docker info --format '{{.OperatingSystem}}'
docker run --rm --net=host alpine ip route | head -5
docker run --rm alpine ip route | head -5
Тэр хоёр маршрутжуулалтын хүснэгтийн ялгаа нь нэг дэлгэц дээрх бүх асуудал юм. Хэрэв хостны харагдац туннелийн интерфейсийг агуулж, гүүрний харагдац агуулахгүй бол та нэрний орон зайн тусгаарлалтыг харж байна, бусад бүх зүйл түүнийг хэрхэн давах тухай сонголт.
Хостны сүлжээ бол шалгалт, дизайн биш
Контейнерыг хостны сүлжээгээр ажиллуулах нь, үүнийг Docker хостны сүлжээний нэрний орон зайг хуваалцах гэж баримтжуулдаг, түүнд туннелийн интерфейс болон түүний маршрутыг шууд өвлүүлдэг. Хэрэв мөн тэр хүсэлт дараа нь амжилттай болбол маршрутын онол батлагдаж, алдаа нь нэрний орон зайн тусгаарлалт бөгөөд итгэмжлэл, DNS эсвэл хандалтын дүрэм биш.
docker run --rm --net=host curl -sS -o /dev/null -w '%{http_code}\n' https://api.internal/health
Үүнийг оношилгоо болгон хадгал. Хостны сүлжээ нь порт нийтлэх болон контейнерээс хүссэн тусгаарлалтын ихэнхээс татгалздаг, Docker Desktop дээр «host» нь виртуал машиныг илэрхийлдэг, ажлын ширээг биш, тиймээс аль хостод хандсанаа мартвал тэндхийн амжилт эсвэл бүтэлгүйтэл таныг төөрөгдүүлж болно.
tun төхөөрөмж ба түүнтэй хамт ирэх эрх
Контейнер доторх VPN клиентэд туннелийн төхөөрөмж болон түүнийг тохируулах зөвшөөрөл хэрэгтэй. Нийтлэг товчлол нь --privileged бөгөөд бүх төхөөрөмжийг өгч, бүх контейнер даяар аюулгүй байдлын бодлогыг сулруулдаг. Энэ нь энэ ажлын шаардлагаас хамаагүй илүү бөгөөд хяналтад зөвтгөхөд хэцүү.
sudo modprobe tun
docker run --rm -it --device /dev/net/tun --cap-add NET_ADMIN myvpn-client
Илүү нарийн хэлбэр нь ганц төхөөрөмжийн зангилааг зураглаж, зөвхөн сүлжээний удирдлагын чадварыг нэмдэг. Зангилаа байхын тулд эхлээд модулийг хост дээр ачаална уу. Хэрэв контейнер ажиллаж, клиент туннелийн төхөөрөмжийг нээж чадахгүй гэж мэдээлбэл, профайлд сэжиглэхээс өмнө зураглалыг шалга, учир нь тэр алдаа ихэвчлэн шууд утгаараа байдаг.
Энэ дизайн нь клиент контейнер бүрт ажиллана гэсэн үг. Ажлын ачаалал бүрт өөрийн туннель хэрэгтэй үед энэ нь зөв хариулт, зөвхөн хостны туннель харагдахыг хүссэн үед буруу хариулт — платформ баг таныг ингэж хийж байна гэж таамагласан байх.
Гүүрний NAT нь VPN-ийн хардаг эх сурвалжийг өөрчилдөг
Өгөгдмөл гүүрээр контейнерын гадагшлах урсгал хостны хаяг руу хөрвүүлэгддэг. Тиймээс VPN-ийн цаана корпорацийн тал контейнерын бус, хостны туннелийн хаягийг хардаг, эх сурвалжаар хандах дүрэм нь хүсэлтийг хост илгээсэн мэт ажиллаж, хоёр контейнер VPN серверт ялгагдахгүй болдог.
macvlan эсвэл ipvlan оронд нь контейнерт LAN хаяг өгч, энэ нь LAN-д илрүүлэхэд тусалж, контейнерыг сегмент дээр тэнцүү гишүүн мэт харуулдаг. Энэ нь хостны туннелийг бүрэн тойрч гардаг тул ийм контейнер зөвхөн-VPN префиксүүдэд хүрэхгүй, хэрэв VPN тэр LAN-аас ч хүрэхгүй бол.
Хоёр хэлбэр хоёулаа хууль ёсны; тэд өөр өөр шаардлагад хариулдаг. Хэрэв шаардлага нь «энэ контейнер зөвхөн-VPN үйлчилгээнд хүрэх ёстой» бол та хостээр дамжих маршрутжуулалт ба контейнер дотор туннелийг дуусгах хоёрын хооронд сонгоно. Энэ сонголтыг байршуулахаас өмнө бичээрэй, эхний бүтэлгүй хүсэлтийн дараа биш. Юу ч сонгосон, алслагдсан тал харах эх сурвалжийн хаягийг бүртгэ, учир нь түүний хандалтын дүрэм, лог яг түүнийг харуулна. Тэр хаягийг хэлж чадахгүй дизайн дуусаагүй.
DNS нь туннель биш, демоныг дагадаг
Контейнер ажиллах үедээ шийдэгчийн тохиргоог авдаг бөгөөд энэ нь демон эсвэл дүрсээс хуулагдсан байдаг. VPN холбогдсоны дараа түлхдэг хаягууд нь тэр хуулбарт хэт оройтож ирдэг бөгөөд тэдгээр нь контейнер руу биш, хостны шийдэгч рүү түлхэгддэг.
Үйлчилгээнд зориулж шийдэгчийг тодорхой тохируулах эсвэл туннелээр хүрэх боломжтой дотоод шийдэгч рүү чиглүүл. Хувийн нэрийг нийтийн хаяг руу шийддэг контейнер ихэвчлэн нийтийн шийдэгч ашигладаг, эвдэрсэн маршрутад зовдоггүй бөгөөд засвар нь compose файл эсвэл демоны тохиргоонд хамаарна.
Яг ижил логик гарах хаягийн асуудалд ч хамаарна. Хэрэв контейнер бүр өөр VPN хаягаас харагдах ёстой бол нэг хостны туннель үүнийг хангаж чадахгүй, учир нь NAT тэдгээрийг нэг эх сурвалжид нэгтгэдэг. Ажиллах хэлбэр нь контейнер бүрийн нэрний орон зай дахь клиент эсвэл туннелийг эзэмшиж, стекийг хуваалцдаг sidecar бөгөөд хоёулаа програмын хаяглалтыг өөрчилдөг.
Тасалбарыг хаахаас өмнөх шалгах хуудас: туннелийг эзэмшдэг нэрний орон зайг тодорхойл, замыг хостны сүлжээгээр батал, зөвхөн хэрэгтэй tun төхөөрөмжийг зурагла, NAT-ын дараах эх сурвалжийн хаягийг сана, шийдэгчийг тодорхой тохируулж, контейнер бүрийн гарах хаягийг туг биш, архитектурын шийдвэр гэж үз.