¿Qué capacidades de Linux necesita tu proceso VPN?
La configuración de la interfaz, las rutas, el acceso a dispositivos y los sockets ordinarios son privilegios separados. Nombra la operación que falló antes de conceder CAP_NET_ADMIN.
Un demonio VPN necesita operaciones de red privilegiadas aunque las aplicaciones ordinarias abren sockets de salida sin ningún privilegio. En esa brecha empiezan la mayoría de los errores de capacidades: alguien ve un error de permisos, concede todo el conjunto y el servicio funciona por motivos que después nadie sabe explicar. El recorrido siguiente parte de la operación que falló, la asigna a una autoridad y luego comprueba el contexto en el que el proceso se ejecuta realmente. Ejecutarse como root sin restricciones es una respuesta válida para algunos despliegues, pero debería ser una decisión y no un valor por defecto.
Empieza por la operación que falló
Lee el error antes de leer un tutorial. «Operación no permitida» al cambiar una interfaz, la negativa a abrir un nodo de dispositivo y un fallo de bind en un puerto bajo son tres problemas distintos con tres concesiones distintas. Si el proceso arranca y solo falla en el primer cambio de ruta, eso también indica que la creación de la interfaz ya tuvo éxito, lo que estrecha mucho la respuesta.
Reproduce el fallo con el servicio detenido y luego inícialo en primer plano con el mismo usuario si la implementación lo permite. Un error que puedes ver es mejor que una línea de registro que tienes que adivinar, y deja evidente la diferencia entre un problema de capacidades y una denegación de SELinux o AppArmor.
Asigna cada operación a una autoridad
La tabla es un mapa inicial, no un sustituto de la documentación de la implementación:
| Operation | Usual authority | Watch for |
|---|---|---|
| Create or configure tun/tap | CAP_NET_ADMIN in the relevant namespace | Creating the device and opening it are separate steps |
| Add routes, rules, firewall entries | CAP_NET_ADMIN | Same capability, different namespace than you think |
| Open /dev/net/tun | Device permissions, not a capability | Group membership or a udev rule may be enough |
| Raw sockets | CAP_NET_RAW | Needed by some user-space tunnel implementations |
| Bind a port below 1024 | CAP_NET_BIND_SERVICE | Irrelevant for most modern tunnel ports |
Las dos filas de esa tabla son las que la gente confunde. Abrir /dev/net/tun es una cuestión de permisos de archivo; pedirle al núcleo que configure lo que has abierto es una cuestión de capacidades. Conceder CAP_NET_ADMIN no arregla un nodo de dispositivo que tu usuario de servicio no puede leer, y arreglar el nodo no te da autoridad sobre las rutas. Comprueba ambas cosas antes de cambiar cualquiera de las dos.
WireGuard en el núcleo y los programas de túnel en espacio de usuario tampoco tienen los mismos requisitos. La vía del módulo del núcleo configura una interfaz existente mediante netlink, mientras que una implementación en espacio de usuario también puede necesitar el dispositivo y, para algunos transportes, sockets sin procesar.
Lee el contexto: servicio, contenedor o shell
Una capacidad en el espacio de nombres de red del anfitrión puede afectar mucho más que la misma operación dentro de una pila deliberadamente aislada. Un entorno de ejecución de contenedores suele empezar con un conjunto de límites reducido; añadir NET_ADMIN a un contenedor que comparte la red del anfitrión es una concesión mucho mayor que añadirlo a uno con su propio espacio de nombres de red y sin montajes del anfitrión.
Para las unidades de systemd, lee lo que se aplica realmente y no lo que parece decir el archivo de unidad: systemctl show -p CapabilityBoundingSet -p AmbientCapabilities informa los valores efectivos, que pueden haber sido fijados por un drop-in que olvidaste. Pide el valor efectivo, nunca el previsto. Las capacidades ambient importan porque un servicio que no es root pierde capacidades a través de exec sin ellas.
Toma como base la configuración compatible del paquete o de la imagen. No añadas permisos de sockets sin procesar ni modo privilegiado porque otro tutorial los haya enumerado para otra herramienta; ese razonamiento no transfiere nada y te cuesta el aislamiento que pagaste. En caso de duda, no concedas nada y lee las notas de la implementación para la operación exacta que necesitas.
Observa qué ocurre cuando caen los privilegios
Muchos demonios arrancan con privilegios, configuran la interfaz y luego pasan a un usuario sin privilegios y mantienen el túnel. Desde ese punto el proceso ya no puede añadir una ruta, reescribir una regla de firewall ni abrir un dispositivo privilegiado nuevo, lo cual está bien hasta que una reconexión necesita justo eso. Las lecturas de archivos y la ejecución de hooks posteriores pueden fallar por el mismo motivo.
Prueba todo el ciclo de vida en lugar del primer segundo: el arranque, una renovación o reconexión y la limpieza al detenerse. Un primer éxito al crear la interfaz no demuestra que toda operación privilegiada posterior siga funcionando, y el fallo suele aparecer horas después en producción.
Las implementaciones que mantienen el túnel abierto durante un cambio de usuario suelen combinarlo con opciones para persistir el túnel y las claves. En el lado de systemd, la pregunta equivalente es si el conjunto de capacidades de la unidad sobrevive al cambio de usuario que configuraste.
Registra la concesión y su motivo
Anota la concesión exacta, la operación que habilita y el error que corrigió. Una línea en las notas de despliegue — «CAP_NET_ADMIN en el espacio de nombres de red de la unidad, necesario para cambios de ruta tras una reconexión» — basta para impedir que la siguiente persona vuelva a ampliar la concesión.
Después relee el conjunto efectivo tras cada actualización. Los proveedores añaden funciones, las imágenes cambian los valores por defecto y una capacidad que el año pasado era innecesaria puede volverse portante sin que nadie se dé cuenta.