NET_ADMIN VPN konteineryje: ką ir kur jis gali pakeisti
Šis pajėgumas leidžia keisti sąsajas, maršrutus ir užkardą vienoje tinklo vardų erdvėje. Su pagrindinio kompiuterio tinklu ta erdvė yra paties pagrindinio kompiuterio dėklas.
NET_ADMIN yra Linux pajėgumas, leidžiantis procesui atlikti tinklo administravimą, o konteineryje jis daro būtent tai toje tinklo vardų erdvėje, kurioje veikia procesas. Tai nėra licencija atidaryti lizdą ir nepakeičia įrenginio ar maršruto. Įdomus klausimas niekada nėra, ar pajėgumas suteiktas, o tai, kuri vardų erdvė gauna pakeitimą.
Ką apima pajėgumas
Savo vardų erdvėje procesas su NET_ADMIN gali kelti ir nuleisti sąsajas, priskirti adresus, pridėti ir šalinti maršrutus bei rašyti užkardos taisykles, o tai yra operacijų grupė, kurią capabilities(7) surenka pagal šį pajėgumą. Jis taip pat gali koreguoti sąsajos lygio nustatymus, kurie kontroliuoja, kaip branduolys išdėsto ir filtruoja srautą. VPN klientui paprastai reikia kelių jų paleidimo metu ir nieko daugiau po to. Todėl dauguma atvaizdų prašo didesnių teisių, nei naudoja.
Operacijos už tos vardų erdvės ribų neapimamos, o gretimos privilegijos yra atskiros. Neapdorotų paketų skaitymas ir rašymas priklauso NET_RAW, o tun įrenginio kūrimui reikia ir pajėgumo, ir prieigos prie įrenginio mazgo. Procesas be įrenginio gauna leidimų klaidą, kuri atrodo kaip tinklo problema, bet ja nėra.
Vardų erdvė nulemia žalos spindulį
Konteineris savo tilto tinkle pasiekia savo loopback, savo sąsajas ir savo maršruto lentelę. Suteikus ten NET_ADMIN, VPN klientas gali pastatyti tunelį neliesdamas pagrindinio kompiuterio maršruto sprendimų, o tai yra išdėstymas, kurį daro prielaidą dauguma konteinerių atvaizdų.
Perjunkite tą konteinerį į pagrindinio kompiuterio tinklą ir tas pats suteikimas dabar redaguoja pagrindinio kompiuterio maršrutus ir užkardą, nes atskiros vardų erdvės nebeliko. Klientas, turėjęs valdyti vieną tunelį, gali nukreipti visos mašinos srautą, o jo išardymo scenarijaus klaida palieka pagrindiniam kompiuteriui taisykles, kurių niekas nerašė. Pačiame pajėgume niekas nepasikeitė; pasikeitė kontekstas. Štai kodėl tas pats compose failas skirtingai elgiasi dviejuose kompiuteriuose.
Trys sąlygos, sujungiamos į vieną
VPN konteinerių paleidimo gedimai paprastai susiję su vienu iš trijų atskirų dalykų: pajėgumu, tunelio įrenginiu ir branduolio palaikymu protokolui. Visų trijų suteikimas iš karto veikia, ir tai taip pat padaro kitą gedimą nepriskiriamą. Minimalus compose fragmentas suteikia pajėgumą ir aiškiai perduoda įrenginio mazgą:
services:
vpn:
image: example/vpn-client:latest
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun
sysctls:
- net.ipv4.conf.all.src_valid_mark=1Skaitykite paties atvaizdo dokumentaciją, kokių sysctl jam reikia, nes sysctl konteineryje gali reikalauti papildomos privilegijos arba pagrindinio kompiuterio lygio nustatymo. Ten, kur atvaizdas palaiko tik vartotojo erdvės režimą, įrenginio visai nereikia, o pajėgumų sąrašas atitinkamai sumažėja.
Suteikite siaurą operaciją, o ne režimą
Privilegijuotas režimas perduoda visus pajėgumus ir tuo pačiu išplečia prieigą prie įrenginių, todėl paslepia, kurios iš trijų sąlygų trūko. Jis taip pat padaro konteinerio gedimų būdus neatskiriamus nuo pagrindinio kompiuterio pakeitimų. Pirmenybę teikite aiškiam sąrašui, net jei jį rašyti ilgiau.
Diegimai be root ir vartotojo vardų erdvėse keičia tai, ką pajėgumas reiškia praktiškai, nes procesas gali jį turėti tik priskirtoje vardų erdvėje. Pajėgumų sąrašo kopijavimas iš root turinčio pavyzdžio į root neturinčią vykdymo aplinką ir tos pačios apimties tikėjimasis yra įprastas būdas prarasti popietę.
Paslaptys priklauso atskiram sprendimui. Turėti NET_ADMIN nieko nesako apie tai, kokį partnerio tapatumą klientas pateikia, kokius prisijungimo duomenis įkelia ar kaip jie keičiami. Tinklo administravimas nesuteikia pasitikėjimo.
Patikrinkite pakeitimą ir užsirašykite, kodėl suteikimas egzistuoja
Prieš derindami tunelį patvirtinkite, ką konteineris iš tikrųjų gavo. Toliau pateikta patikra praneša apie pridėtus pajėgumus ir tinklo režimą, o tada parodo, kaip sąsajų sąrašas atrodo iš vidaus:
docker inspect --format '{{.HostConfig.CapAdd}} {{.HostConfig.NetworkMode}} {{.HostConfig.Privileged}}' vpn
docker exec vpn sh -c 'grep CapEff /proc/self/status'
docker exec vpn ip -br addr
docker exec vpn ip routeJei pajėgumas yra, o sąsajų sąrašas vis dar tuščias, klientas nepavyko dar prieš ką nors sukurdamas, ir toliau žiūrėti reikėtų konteinerio žurnaluose. Jei tunelis yra, bet srautas neina, į kitą klausimą atsako maršruto lentelė konteinerio viduje.
Išbandykite ir išardymo kelią, nes užkardos taisykles rašantis klientas gali jas palikti. Sustabdykite konteinerį ir dar kartą patikrinkite pagrindinio kompiuterio taisyklių rinkinį, jei naudojamas pagrindinio kompiuterio tinklas. Suteikimas, kurio reikia tik dvi sekundes paleidžiant, neturėtų būti aprašytas compose faile kaip nuolatinis reikalavimas be jį paaiškinančios pastabos.
Šalia kiekvieno pajėgumo parašykite priežastį: kuri operacija jo reikalavo ir kas nepavyksta be jo. Ta pastaba išlieka po atvaizdo naujinimų, ir būtent ji skiria peržiūrėtą privilegijų sąrašą nuo sąrašo, išaugusio kopijuojant ir įklijuojant.