Miks Dockeri konteiner ei jõua VPN-i taga olevate hostideni
Sillakonteineritel on oma nimeruum, seega on hosti tunnel neile nähtamatu. Võrrelge hosti võrku, tun-seadet ja macvlani enne DNS-i muutmist.
Konteiner, mis ei jõua millenigi ettevõtte VPN-i taga, elab tavaliselt teises võrgu nimeruumis kui tunnel. Hostkliendi marsruudid, DNS-serverid ja tulemüüri märgised kuuluvad hosti virnale; sildvõrgu konteineril on oma. See üks tõsiasi seletab enamikku aruandeid, mis jõuavad platvormimeeskonnani, ja see on ka põhjus, miks «VPN on katki» ja «Docker möödub VPN-ist» võivad mõlemad korraga valed olla. Ühe sümptomi taga peitub kaks väga erinevat seadistust, seega tehke kindlaks, milline neist on teie oma, enne kui sätet muudate.
Tehke kindlaks, kelle nimeruum tunnelit omab
Docker Desktopis macOS-i või Windowsi jaoks töötavad konteinerid Linuxi virtuaalmasinas. Töölauale paigaldatud VPN-klient loob tunneli töölaua operatsioonisüsteemis ja virtuaalmasin ei näe seda kunagi. Ükski konteineri seadistus ei paranda seda, sest liides, mida konteiner vajaks, ei eksisteeri tema võrgu nimeruumis üldse.
Linuxi hostis elab tunnel hosti nimeruumis ja sildkonteinerid jõuavad selleni tavaliselt hosti marsruutimistabeli kaudu, kusjuures väljumisel rakendatakse lähtepõhist NAT-i. Kui see tee ebaõnnestub, on põhjuseks tavaliselt edastuspoliitika, vastupidi tee filtreerimine või kattuv alamvõrk, mitte puuduv marsruut. Kinnitage, millises kahest maailmast te olete, enne kui edasi loete:
docker info --format '{{.OperatingSystem}}'
docker run --rm --net=host alpine ip route | head -5
docker run --rm alpine ip route | head -5
Nende kahe marsruutimistabeli erinevus on kogu probleem ühel ekraanil. Kui hosti vaade sisaldab tunneliliidest ja silla vaade mitte, näete nimeruumi isolatsiooni ja kõik muu on valik, kuidas seda ületada.
Hosti võrk on test, mitte disain
Konteineri käivitamine hosti võrguga, mida Docker dokumenteerib hosti võrgu nimeruumi jagamisena, paneb selle otseselt pärima tunneliliidest ja selle marsruute. Kui sama päring siis õnnestub, on marsruuditeooria kinnitatud ja tõrge on nimeruumi isolatsioon, mitte mandaat, DNS ega juurdepääsureegel.
docker run --rm --net=host curl -sS -o /dev/null -w '%{http_code}\n' https://api.internal/health
Hoidke seda diagnostikavahendina. Hosti võrk loobub pordi avaldamisest ja suuremast osast isolatsioonist, mida te konteinerilt tahtsite, ja Docker Desktopis tähendab «host» virtuaalmasinat, mitte töölauda, seega võib sealne õnnestumine või ebaõnnestumine teid eksitada, kui unustate, millise hosti poole pöördusite.
tun-seade ja sellega kaasnevad õigused
Konteineri sees olev VPN-klient vajab tunneliseadet ja luba selle seadistamiseks. Tavaline otsetee on --privileged, mis annab kõik seadmed ja lõdvendab turbepoliitikat kogu konteineris. See on palju rohkem, kui see ülesanne nõuab, ja seda on ülevaatusel raske põhjendada.
sudo modprobe tun
docker run --rm -it --device /dev/net/tun --cap-add NET_ADMIN myvpn-client
Kitsam vorm kaardistab üksiku seadmekomplekti ja lisab ainult võrgu haldamise võime. Laadige moodul esmalt hosti, et sõlm oleks olemas. Kui konteiner käivitub ja klient teatab, et ei saa tunneliseadet avada, kontrollige vastendust enne profiili kahtlustamist, sest see viga on tavaliselt sõnasõnaline.
See disain tähendab ka seda, et klient töötab iga konteineri kohta. See on õige vastus, kui iga töökoormus vajab oma tunnelit, ja vale vastus, kui te lihtsalt tahtsite, et hosti tunnel oleks nähtav, mida platvormimeeskond tõenäoliselt eeldas, et te teete.
Silla NAT muudab allikat, mida VPN näeb
Vaikimisi silla korral tõlgitakse konteineri väljuv liiklus hosti aadressiks. Seega näeb ettevõtte pool VPN-i taga hosti tunneli aadressi, mitte konteineri oma, lähtepõhised juurdepääsureeglid käituvad nii, nagu oleks päringu teinud host, ja kaks konteinerit muutuvad VPN-serveri jaoks eristamatuks.
macvlan või ipvlan annab konteinerile seevastu LAN-aadressi, mis aitab LAN-i avastamist ja paneb konteineri segmendis võrdseks osaliseks paistma. See möödub ka hosti tunnelist täielikult, seega selline konteiner ei jõua ainult-VPN-i prefiksitele, kui VPN pole kättesaadav ka sellest LAN-ist.
Mõlemad vormid on õiguspärased; need vastavad erinevatele nõuetele. Kui nõue on «see konteiner peab jõudma ainult-VPN-i teenuseni», valite hosti kaudu marsruutimise ja tunnelis konteineri sees lõpetamise vahel. Kirjutage see valik enne juurutamist üles, mitte pärast esimest ebaõnnestunud päringut. Mida iganes valite, kirjutage üles lähteaadress, mida kaugem pool näeb, sest just seda näitavad tema juurdepääsureeglid ja tema logid. Disain, mis ei suuda seda aadressi nimetada, pole valmis.
DNS järgib deemonit, mitte tunnelit
Konteiner saab oma resolveri seadistuse käivitumisel, kopeerituna deemonilt või pildilt. Aadressid, mida VPN pärast ühendamist lükkab, jõuavad selle koopia jaoks liiga hilja ja need lükatakse hosti resolverisse, mitte konteinerisse.
Määrake resolver teenuse jaoks selgesõnaliselt või suunake see sisemisele resolverile, mis on tunneli kaudu kättesaadav. Konteiner, mis lahendab privaatse nime avalikuks aadressiks, kasutab tavaliselt avalikku resolverit, mitte ei kannata katkise marsruudi all, ja parandus kuulub compose-faili või deemoni seadistusse.
Sama loogika kehtib väljumisaadressi küsimuse kohta. Kui iga konteiner peab paistma erinevalt VPN-aadressilt, ei suuda üks hosti tunnel seda pakkuda, sest NAT surub need ühte allikasse. Toimivad vormid on klient iga konteineri nimeruumis või sidecar, mis omab tunnelit ja jagab oma virna, ja mõlemad muudavad seda, kuidas rakendust adresseeritakse.
Kontrollnimekiri enne pileti sulgemist: tehke kindlaks tunnelit omav nimeruum, tõestage tee hosti võrguga, kaardistage ainult vajalik tun-seade, pidage meeles lähteaadressi pärast NAT-i, määrake resolver selgesõnaliselt ja käsitlege konteineripõhiseid väljumisaadresse arhitektuurilise otsusena, mitte lipuna.