Een VPN-daemon heeft geprivilegieerde netwerkbewerkingen nodig, terwijl gewone applicaties uitgaande sockets helemaal zonder bevoegdheid openen. In dat gat beginnen de meeste capability-fouten: iemand ziet een rechtenfout, kent de hele set toe, en de dienst werkt om redenen die niemand later kan uitleggen. De wandeling hieronder begint bij de mislukte bewerking, koppelt die aan één bevoegdheid en controleert daarna de context waarin het proces werkelijk draait. Draaien als onbeperkte root is voor sommige implementaties een geldig antwoord, maar het hoort een beslissing te zijn en geen standaard.

Begin bij de bewerking die mislukte

Lees de fout voordat je een handleiding leest. „Bewerking niet toegestaan“ bij een interfacewijziging, een weigering om een apparaatknooppunt te openen en een bind-fout op een lage poort zijn drie verschillende problemen met drie verschillende toekenningen. Als het proces start en pas bij de eerste routewijziging faalt, betekent dat ook dat het aanmaken van de interface al is gelukt, wat het antwoord flink vernauwt.

Reproduceer de fout met de dienst gestopt en start hem dan op de voorgrond onder dezelfde gebruiker als de implementatie dat toestaat. Een fout die je kunt zien is beter dan een logregel die je moet raden, en het maakt het verschil tussen een capability-probleem en een weigering van SELinux of AppArmor duidelijk.

Koppel elke bewerking aan één bevoegdheid

De tabel is een startkaart, geen vervanging voor de documentatie van de implementatie:

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

De twee rijen in die tabel zijn degene die mensen door elkaar halen. Het openen van /dev/net/tun is een kwestie van bestandsrechten; de kernel vragen te configureren wat je hebt geopend is een kwestie van capabilities. CAP_NET_ADMIN toekennen lost geen apparaatknooppunt op dat je dienstgebruiker niet kan lezen, en het knooppunt repareren geeft je geen routetoestemming. Controleer beide voordat je een van beide wijzigt.

Kernel-WireGuard en tunnelprogramma's in gebruikersruimte hebben ook geen identieke eisen. Het kernelmodulepad configureert een bestaande interface via netlink, terwijl een implementatie in gebruikersruimte ook het apparaat nodig kan hebben en, voor sommige transporten, ruwe sockets.

Lees de context: dienst, container of shell

Een capability in de netwerknaamruimte van de host kan veel meer effect hebben dan dezelfde bewerking in een bewust geïsoleerde stack. Een container-runtime begint meestal met een verkleinde begrenzing; NET_ADMIN toevoegen aan een container die het hostnetwerk deelt is een veel grotere toekenning dan het toevoegen aan een container met een eigen netwerknaamruimte en zonder hostmounts.

Lees bij systemd-units wat werkelijk wordt toegepast in plaats van wat het unitbestand lijkt te zeggen: systemctl show -p CapabilityBoundingSet -p AmbientCapabilities rapporteert de effectieve waarden, die door een vergeten drop-in zijn gezet. Vraag om de effectieve waarde, nooit om de bedoelde. Ambient-capabilities zijn belangrijk omdat een dienst zonder root zonder hen capabilities verliest over exec heen.

Neem de ondersteunde opzet van het pakket of de image als uitgangspunt. Voeg geen ruwe-socketrechten of geprivilegieerde modus toe omdat een andere handleiding ze voor een ander hulpmiddel noemde; die redenering draagt niets over en kost je de isolatie waarvoor je betaalde. Bij twijfel ken je niets toe en lees je de implementatienotities voor de exacte bewerking die je nodig hebt.

Let op wat er gebeurt nadat de privileges wegvallen

Veel daemons starten geprivilegieerd, configureren de interface en schakelen dan over naar een onbevoorrechte gebruiker en houden de tunnel. Vanaf dat punt kan het proces geen route meer toevoegen, geen firewallregel herschrijven en geen nieuw geprivilegieerd apparaat openen, wat prima is tot een herverbinding precies dat nodig heeft. Latere bestandslezingen en hook-uitvoering kunnen om dezelfde reden mislukken.

Test de hele levenscyclus in plaats van de eerste seconde: opstarten, een vernieuwing of herverbinding en opruimen bij stoppen. Een eerste geslaagde interface-aanmaak bewijst niet dat elke latere geprivilegieerde bewerking nog werkt, en de fout verschijnt meestal uren later in productie.

Implementaties die de tunnel openhouden tijdens een gebruikerswissel combineren dat meestal met opties om de tunnel en sleutels te bewaren. Aan de systemd-kant is de gelijkwaardige vraag of de capability-set van de unit de gebruikerswissel overleeft die je hebt geconfigureerd.

Leg de toekenning en de reden vast

Schrijf de exacte toekenning op, de bewerking die zij mogelijk maakt en de fout die zij heeft opgelost. Eén regel in de deployment-notities — „CAP_NET_ADMIN in de netwerknaamruimte van de unit, nodig voor routewijzigingen na een herverbinding“ — is genoeg om te voorkomen dat de volgende persoon de toekenning weer verbreedt.

Lees daarna na elke upgrade de effectieve set opnieuw. Leveranciers voegen functies toe, images wijzigen standaardwaarden, en een capability die vorig jaar overbodig was kan dragend worden zonder dat iemand het merkt.

Gerelateerde artikelen