Un dimoni VPN necessita operacions de xarxa privilegiades encara que les aplicacions ordinàries obrin sockets de sortida sense cap privilegi. Aquest buit és on comencen la majoria d’errors de capacitats: algú veu un error de permisos, concedeix tot el conjunt i el servei funciona per motius que ningú no pot explicar després. El recorregut següent parteix de l’operació que ha fallat, la relaciona amb una autoritat i després comprova el context en què el procés s’executa realment. Executar-se com a root sense restriccions és una resposta vàlida per a alguns desplegaments, però hauria de ser una decisió i no un valor per defecte.

Partiu de l’operació que ha fallat

Llegiu l’error abans de llegir un tutorial. «Operació no permesa» en un canvi d’interfície, una negativa a obrir un node de dispositiu i un error de bind en un port baix són tres problemes diferents amb tres concessions diferents. Si el procés arrenca i només falla en el primer canvi de ruta, això també indica que la creació de la interfície ja ha tingut èxit, cosa que estreta molt la resposta.

Reproduïu la fallada amb el servei aturat i després inicieu-lo en primer pla amb el mateix usuari si la implementació ho permet. Un error que podeu veure és millor que una línia de registre que heu d’endevinar, i fa evident la diferència entre un problema de capacitats i una denegació de SELinux o AppArmor.

Relacioneu cada operació amb una autoritat

La taula és un mapa inicial, no un substitut de la documentació de la implementació:

OperationUsual authorityWatch for
Create or configure tun/tapCAP_NET_ADMIN in the relevant namespaceCreating the device and opening it are separate steps
Add routes, rules, firewall entriesCAP_NET_ADMINSame capability, different namespace than you think
Open /dev/net/tunDevice permissions, not a capabilityGroup membership or a udev rule may be enough
Raw socketsCAP_NET_RAWNeeded by some user-space tunnel implementations
Bind a port below 1024CAP_NET_BIND_SERVICEIrrelevant for most modern tunnel ports

Les dues files d’aquesta taula són les que la gent confon. Obrir /dev/net/tun és una qüestió de permisos de fitxer; demanar al nucli que configuri el que heu obert és una qüestió de capacitats. Concedir CAP_NET_ADMIN no arregla un node de dispositiu que el vostre usuari de servei no pot llegir, i arreglar el node no us dona autoritat sobre les rutes. Comproveu les dues coses abans de canviar qualsevol de les dues.

WireGuard al nucli i els programes de túnel en espai d’usuari tampoc no tenen els mateixos requisits. La via del mòdul del nucli configura una interfície existent mitjançant netlink, mentre que una implementació en espai d’usuari també pot necessitar el dispositiu i, per a alguns transports, sockets crus.

Llegiu el context: servei, contenidor o shell

Una capacitat a l’espai de noms de xarxa de l’amfitrió pot afectar molt més que la mateixa operació dins d’una pila deliberadament aïllada. L’entorn d’execució de contenidors sol començar amb un conjunt de límits reduït; afegir NET_ADMIN a un contenidor que comparteix la xarxa de l’amfitrió és una concessió molt més gran que afegir-lo a un amb espai de noms de xarxa propi i sense muntatges de l’amfitrió.

Per a les unitats de systemd, llegiu què s’aplica realment i no què sembla que diu el fitxer d’unitat: systemctl show -p CapabilityBoundingSet -p AmbientCapabilities informa dels valors efectius, que poden ser establerts per un drop-in que hàgiu oblidat. Demaneu el valor efectiu, mai el previst. Les capacitats ambient importen perquè un servei que no és root perd capacitats a través de exec sense elles.

Preneu com a base la configuració suportada del paquet o de la imatge. No afegiu permisos de sockets crus ni mode privilegiat perquè un altre tutorial els ha llistat per a una altra eina; aquest raonament no trasllada res i us costa l’aïllament que heu pagat. En cas de dubte, no concediu res i llegiu les notes de la implementació per a l’operació exacta que necessiteu.

Mireu què passa després que caiguin els privilegis

Molts dimonis comencen amb privilegis, configuren la interfície i després baixen a un usuari sense privilegis i mantenen el túnel. A partir d’aquell moment el procés ja no pot afegir una ruta, reescriure una regla de firewall o obrir un dispositiu privilegiat nou, cosa que va bé fins que una reconnexió necessita exactament això. Les lectures de fitxers i l’execució d’hooks posteriors poden fallar pel mateix motiu.

Proveu tot el cicle de vida i no el primer segon: l’arrencada, una renovació o reconnexió i la neteja en aturar-se. Un primer èxit en la creació de la interfície no estableix que tota operació privilegiada posterior continuï funcionant, i la fallada sol aparèixer hores després en producció.

Les implementacions que mantenen el túnel obert durant un canvi d’usuari solen combinar-ho amb opcions per persistir el túnel i les claus. A la banda de systemd, la pregunta equivalent és si el conjunt de capacitats de la unitat sobreviu al canvi d’usuari que heu configurat.

Anoteu la concessió i el seu motiu

Anoteu la concessió exacta, l’operació que habilita i l’error que ha corregit. Una línia a les notes de desplegament — «CAP_NET_ADMIN a l’espai de noms de xarxa de la unitat, necessari per als canvis de ruta després d’una reconnexió» — n’hi ha prou per impedir que la persona següent torni a ampliar la concessió.

Després rellegiu el conjunt efectiu després de cada actualització. Els proveïdors afegeixen funcions, les imatges canvien els valors per defecte i una capacitat que l’any passat era innecessària pot esdevenir portant sense que ningú no se n’adoni.

Articles relacionats