NET_ADMIN er Linux-kapabiliteten som lar en prosess utføre nettverksadministrasjon, og i en container gjør den nøyaktig dette inne i det nettverksnavnerommet prosessen kjører i. Den er ikke en lisens til å åpne en socket, og den er ikke en erstatning for en enhet eller en rute. Det interessante spørsmålet er aldri om kapabiliteten er gitt, men hvilket navnerom som mottar endringen.

Hva kapabiliteten dekker

Inne i navnerommet sitt kan en prosess med NET_ADMIN ta grensesnitt opp og ned, tildele adresser, legge til og fjerne ruter og skrive brannmurregler, som er gruppen av operasjoner som capabilities(7) samler under denne kapabiliteten. Den kan også justere innstillinger på grensesnittnivå som styrer hvordan kjernen køer og filtrerer trafikk. En VPN-klient trenger vanligvis noen få av disse ved oppstart og ingenting annet etterpå. Derfor ber de fleste images om større rekkevidde enn de bruker.

Operasjoner utenfor dette navnerommet dekkes ikke, og tilstøtende privilegier er separate. Lesing og skriving av råpakker tilhører NET_RAW, og oppretting av en tun-enhet krever både kapabiliteten og tilgang til enhetsnoden. En prosess uten enheten får en tillatelsesfeil som ser ut som et nettverksproblem og ikke er det.

Navnerommet bestemmer skadens radius

En container på sitt eget bro-nettverk når sitt eget loopback, sine egne grensesnitt og sin egen rutingtabell. Å gi NET_ADMIN der lar VPN-klienten bygge en tunnel uten å berøre vertens rutingbeslutninger, som er ordningen de fleste container-images forutsetter.

Bytt den containeren til vertsnettverk, og den samme tildelingen redigerer nå vertens ruter og vertens brannmur, fordi det ikke er noe separat navnerom igjen. Klienten som skulle administrere én tunnel kan da omdirigere trafikk for hele maskinen, og en feil i nedrivningsskriptet etterlater verten med regler ingen har skrevet. Ingenting i selve kapabiliteten endret seg; konteksten gjorde det. Derfor oppfører den samme compose-filen seg ulikt på to verter.

Tre forutsetninger som smelter sammen til én

Oppstartsfeil i VPN-containere involverer vanligvis én av tre separate ting: kapabiliteten, tunellenheten og kjernestøtte for protokollen. Å gi alle tre på én gang virker, og det gjør også den neste feilen umulig å tilskrive. Et minimalt compose-utdrag gir kapabiliteten og sender enhetsnoden eksplisitt:

services:
  vpn:
    image: example/vpn-client:latest
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1

Les imagets egen dokumentasjon for hvilke sysctls det trenger, fordi en sysctl i en container kan kreve et ekstra privilegium eller en innstilling på vertsnivå. Der imaget bare støtter brukermodus, er det ikke behov for noen enhet i det hele tatt, og kapabilitetslisten krymper tilsvarende.

Gi den smale operasjonen, ikke modusen

Privilegert modus overleverer hver kapabilitet og utvider enhetstilgangen samtidig, så det skjuler hvilken av de tre forutsetningene som manglet. Det gjør også containerens feilmoduser umulige å skille fra endringer på verten. Foretrekk en eksplisitt liste selv når den er lengre å skrive.

Rootless- og brukernavneromsutrullinger endrer hva en kapabilitet betyr i praksis, siden prosessen bare kan holde den inne i et mappet navnerom. Å kopiere en kapabilitetsliste fra et rootful eksempel til et rootless kjøretidsmiljø og forvente samme rekkevidde er en vanlig måte å miste en ettermiddag.

Hemmeligheter hører til en egen beslutning. Å holde NET_ADMIN sier ingenting om hvilken peer-identitet klienten presenterer, hvilke legitimasjoner den laster eller hvordan de roteres. Nettverksadministrasjon gir ikke tillit.

Bekreft endringen og noter hvorfor tildelingen finnes

Bekreft hva containeren faktisk mottok før du feilsøker tunnelen. Inspeksjonen nedenfor rapporterer de tilføyde kapabilitetene og nettverksmodusen, og viser deretter hvordan grensesnittlisten ser ut innenfra:

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 route

Hvis kapabiliteten er til stede og grensesnittlisten fortsatt er tom, feilet klienten før den kunne opprette noe, og containerloggene er det neste stedet å se. Hvis tunnelen finnes men trafikken ikke flyter, svarer rutingtabellen inne i containeren på det neste spørsmålet.

Test også nedrivningsveien, fordi en klient som skriver brannmurregler kan etterlate dem. Stopp containeren og kontroller vertens regelsett på nytt hvis vertsnettverk brukes. En tildeling som bare trengs i to sekunder ved oppstart, bør ikke beskrives i compose-filen som et permanent krav uten en merknad som forklarer det.

Skriv årsaken ved siden av hver kapabilitet: hvilken operasjon som trengte den og hva som feiler uten den. Den merknaden overlever image-oppdateringer, og den er forskjellen mellom en gjennomgått privilegieliste og en som har vokst ved kopiering og liming.

Relaterte artikler