Kontti, joka ei tavoita mitään yrityksen VPN:n takaa, elää yleensä eri verkkonimiavaruudessa kuin tunneli. Isäntäasiakkaan reitit, DNS-palvelimet ja palomuurimerkinnät kuuluvat isännän pinoon; siltakontilla on omansa. Tämä yksi tosiasia selittää useimmat alustatiimille tulevat raportit, ja se on myös syy siihen, miksi «VPN on rikki» ja «Docker ohittaa VPN:n» voivat olla molemmat väärin samaan aikaan. Yhden oireen takana piilee kaksi hyvin erilaista kokoonpanoa, joten selvitä, kumpi sinulla on, ennen kuin muutat asetusta.

Selvitä, kenen nimiavaruus omistaa tunnelin

Docker Desktopissa macOS:lle tai Windowsille kontit ajetaan Linux-virtuaalikoneen sisällä. Työpöydälle asennettu VPN-asiakas luo tunnelin työpöydän käyttöjärjestelmään, eikä virtuaalikone näe sitä koskaan. Mikään kontin asetus ei korjaa tätä, koska käyttöliittymä, jonka kontti tarvitsisi, ei yksinkertaisesti ole olemassa sen verkkonimiavaruudessa.

Linux-isännällä tunneli elää isännän nimiavaruudessa, ja siltakontit tavoittavat sen yleensä isännän reititystaulun kautta lähde-NAT:n ollessa käytössä ulospäin. Kun tämä polku epäonnistuu, syy on yleensä edelleenlähetyskäytäntö, käänteisen polun suodatus tai päällekkäinen aliverkko eikä puuttuva reitti. Vahvista, kummassa kahdesta maailmasta olet, ennen kuin luet pidemmälle:

docker info --format '{{.OperatingSystem}}'
docker run --rm --net=host alpine ip route | head -5
docker run --rm alpine ip route | head -5

Näiden kahden reititystaulun ero on koko ongelma yhdellä näytöllä. Jos isännän näkymä sisältää tunneliliittymän eikä sillan näkymä, katsot nimiavaruuksien eristystä, ja kaikki muu on valinta siitä, miten se ylitetään.

Isännän verkko on testi, ei suunnittelu

Kontin ajaminen isännän verkolla, jonka Docker dokumentoi isännän verkkonimiavaruuden jakamiseksi, saa sen perimään tunneliliittymän ja sen reitit suoraan. Jos sama pyyntö sitten onnistuu, reittiteoria on vahvistettu ja vika on nimiavaruuksien eristys eikä tunnistetiedot, DNS tai käyttöoikeussääntö.

docker run --rm --net=host curl -sS -o /dev/null -w '%{http_code}\n' https://api.internal/health

Pidä sitä diagnostiikkana. Isännän verkko luopuu porttien julkaisusta ja suurimmasta osasta eristystä, jonka halusit kontilta, ja Docker Desktopissa «host» tarkoittaa virtuaalikonetta, ei työpöytää, joten onnistuminen tai epäonnistuminen siellä voi johtaa harhaan, jos unohdat, mitä isäntää puhuttelit.

tun-laite ja sen mukanaan tuomat oikeudet

Kontin sisäinen VPN-asiakas tarvitsee tunnelilaitteen ja luvan sen määrittämiseen. Tavallinen oikotie on --privileged, joka myöntää kaikki laitteet ja löysentää tietoturvakäytäntöä koko kontissa. Se on paljon enemmän kuin tämä tehtävä vaatii, ja sitä on vaikea perustella katselmoinnissa.

sudo modprobe tun
docker run --rm -it --device /dev/net/tun --cap-add NET_ADMIN myvpn-client

Kapeampi muoto kartoittaa yksittäisen laitesolmun ja lisää vain verkonhallintakyvyn. Lataa moduuli ensin isännälle, jotta solmu on olemassa. Jos kontti käynnistyy ja asiakas ilmoittaa, ettei voi avata tunnelilaitetta, tarkista kartoitus ennen kuin epäilet profiilia, sillä tämä virhe on yleensä kirjaimellinen.

Tämä suunnittelu tarkoittaa myös, että asiakas ajetaan konttikohtaisesti. Se on oikea vastaus, kun jokainen työkuorma tarvitsee oman tunnelinsa, ja väärä, kun halusit vain isännän tunnelin näkyväksi, mitä alustatiimi luultavasti oletti sinun tekevän.

Sillan NAT muuttaa lähdettä, jonka VPN näkee

Oletussillalla kontin lähtevä liikenne muunnetaan isännän osoitteeksi. Siksi VPN:n takana yrityksen puoli näkee isännän tunneliosoitteen eikä kontin osoitetta, lähdekohtaiset käyttöoikeussäännöt käyttäytyvät kuin isäntä olisi tehnyt pyynnön, ja kahdesta kontista tulee VPN-palvelimelle erottamattomia.

macvlan tai ipvlan antaa kontille sen sijaan LAN-osoitteen, mikä auttaa LAN-löytämistä ja saa kontin näyttämään segmentin vertaiselta. Se myös ohittaa isännän tunnelin kokonaan, joten tällainen kontti ei tavoita vain-VPN-etuliitteitä, ellei VPN ole tavoitettavissa myös kyseisestä LAN:sta.

Molemmat muodot ovat laillisia; ne vastaavat eri vaatimuksiin. Jos vaatimus on «tämän kontin on tavoitettava vain-VPN-palvelu», valitset isännän kautta reitittämisen ja tunnelin päättämisen kontin sisällä välillä. Kirjoita tämä valinta muistiin ennen käyttöönottoa, älä ensimmäisen epäonnistuneen pyynnön jälkeen. Mitä tahansa valitset, kirjaa lähdeosoite, jonka kaukaisin pää näkee, sillä juuri sen sen käyttöoikeussäännöt ja lokit näyttävät. Suunnittelu, joka ei pysty ilmoittamaan tätä osoitetta, ei ole valmis.

DNS seuraa daemonia, ei tunnelia

Kontti saa resolver-asetuksensa käynnistyessään, kopioituna daemonilta tai imagesta. Osoitteet, joita VPN työntää yhteyden jälkeen, saapuvat liian myöhään tälle kopiolle, ja ne työnnetään isännän resolveriin eikä konttiin.

Aseta resolver palvelulle nimenomaisesti tai osoita se sisäiseen resolveriin, joka on tavoitettavissa tunnelin kautta. Kontti, joka ratkaisee yksityisen nimen julkiseksi osoitteeksi, käyttää yleensä julkista resolveria eikä kärsi rikkinäisestä reitistä, ja korjaus kuuluu compose-tiedostoon tai daemonin asetukseen.

Sama päättely pätee lähtöosoitteen kysymykseen. Jos jokaisen kontin on näyttävä eri VPN-osoitteesta, yksi isännän tunneli ei voi tarjota sitä, koska NAT puristaa ne yhdeksi lähteeksi. Toimivat muodot ovat asiakas jokaisen kontin nimiavaruudessa tai sidecar, joka omistaa tunnelin ja jakaa pinonsa, ja molemmat muuttavat sitä, miten sovellus osoitetaan.

Tarkistuslista ennen tiketin sulkemista: tunnista nimiavaruus, joka omistaa tunnelin, todista polku isännän verkolla, kartoita vain tarvittava tun-laite, muista lähdeosoite NAT:n jälkeen, aseta resolver nimenomaisesti ja kohtele konttikohtaisia lähtöosoitteita arkkitehtuuripäätöksenä, älä lippuna.

Aiheeseen liittyvät artikkelit