NET_ADMIN en un contenidor VPN: què pot canviar i on
La capacitat permet canvis d'interfície, ruta i tallafocs dins d'un sol espai de noms de xarxa. Amb xarxa de l'amfitrió, aquest espai és la pila pròpia de l'amfitrió.
NET_ADMIN és la capacitat de Linux que permet a un procés fer administració de xarxa, i en un contenidor fa exactament això dins de l'espai de noms de xarxa on s'executa el procés. No és una llicència per obrir un sòcol ni un substitut d'un dispositiu o d'una ruta. La pregunta interessant no és mai si la capacitat s'ha concedit, sinó quin espai de noms rep el canvi.
Què cobreix la capacitat
Dins del seu espai de noms, un procés amb NET_ADMIN pot aixecar i baixar interfícies, assignar adreces, afegir i treure rutes i escriure regles de tallafocs, que és el grup d'operacions que capabilities(7) recull sota aquesta capacitat. També pot ajustar paràmetres a nivell d'interfície que controlen com el nucli encua i filtra el trànsit. Un client VPN normalment necessita unes quantes d'aquestes en arrencar i res més després. Per això la majoria d'imatges demanen més abast del que fan servir.
Les operacions fora d'aquest espai de noms no hi són cobertes, i els privilegis adjacents són separats. Llegir i escriure paquets crus pertany a NET_RAW, i crear un dispositiu tun necessita tant la capacitat com accés al node del dispositiu. Un procés sense el dispositiu obté un error de permisos que sembla un problema de xarxa i no ho és.
L'espai de noms decideix el radi de l'explosió
Un contenidor a la seva pròpia xarxa bridge arriba al seu loopback, a les seves interfícies i a la seva taula d'encaminament. Concedir-hi NET_ADMIN permet al client VPN construir un túnel sense tocar les decisions d'encaminament de l'amfitrió, que és la disposició que assumeixen la majoria d'imatges de contenidor.
Canvieu aquest contenidor a xarxa de l'amfitrió i la mateixa concessió ara edita les rutes de l'amfitrió i el seu tallafocs, perquè no queda cap espai de noms separat. El client que havia de gestionar un sol túnel pot aleshores redirigir el trànsit de tota la màquina, i una errada al seu script de desmuntatge deixa a l'amfitrió regles que ningú no ha escrit. No ha canviat res de la capacitat; ha canviat el context. És per això que el mateix fitxer compose es comporta diferent en dos amfitrions.
Tres requisits previs que es fusionen en un
Les falles d'arrencada en contenidors VPN solen implicar una de tres coses separades: la capacitat, el dispositiu de túnel i el suport del nucli per al protocol. Concedir les tres alhora funciona, i també fa impossible atribuir la falla següent. Un fragment mínim de compose concedeix la capacitat i passa el node del dispositiu explícitament:
services:
vpn:
image: example/vpn-client:latest
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun
sysctls:
- net.ipv4.conf.all.src_valid_mark=1Llegiu la documentació de la imatge per saber quins sysctl necessita, perquè un sysctl dins d'un contenidor pot requerir un privilegi addicional o un paràmetre a nivell d'amfitrió. On la imatge admet només mode d'espai d'usuari, no cal cap dispositiu i la llista de capacitats s'escurça en conseqüència.
Concediu l'operació estreta, no el mode
El mode privilegiat lliura totes les capacitats i amplia l'accés als dispositius alhora, així que amaga quin dels tres requisits previs faltava. També fa que les maneres de fallar del contenidor no es distingeixin dels canvis de l'amfitrió. Preferiu una llista explícita encara que sigui més llarga d'escriure.
Els desplegaments rootless i amb espais de noms d'usuari canvien què significa una capacitat a la pràctica, perquè el procés només la pot tenir dins d'un espai de noms mapat. Copiar una llista de capacitats d'un exemple rootful a un runtime rootless i esperar el mateix abast és una manera habitual de perdre una tarda.
Els secrets són una decisió a part. Tenir NET_ADMIN no diu res sobre quina identitat de parell presenta el client, quines credencials carrega ni com es renoven. L'administració de xarxa no aporta confiança.
Verifiqueu el canvi i registreu per què existeix la concessió
Confirmeu què ha rebut realment el contenidor abans de depurar el túnel. La inspecció de sota informa de les capacitats afegides i del mode de xarxa, i després mostra com es veu la llista d'interfícies des de dins:
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 routeSi la capacitat hi és i la llista d'interfícies continua buida, el client ha fallat abans de poder crear res, i els registres del contenidor són el lloc següent on mirar. Si el túnel existeix però el trànsit no flueix, la taula d'encaminament dins del contenidor respon la pregunta següent.
Proveu també el camí de desmuntatge, perquè un client que escriu regles de tallafocs les pot deixar enrere. Atureu el contenidor i torneu a comprovar el conjunt de regles de l'amfitrió si feu servir xarxa de l'amfitrió. Una concessió que només cal dos segons en arrencar no s'hauria de descriure al fitxer compose com un requisit permanent sense una nota que ho expliqui.
Escriviu el motiu al costat de cada capacitat: quina operació la necessitava i què falla sense ella. Aquesta nota sobreviu a les actualitzacions d'imatge, i és la diferència entre una llista de privilegis revisada i una que ha crescut a copiar i enganxar.