Dos recetas de mínimo privilegio pegadas juntas no producen un despliegue más estricto. Un modelo deja que el demonio arranque con privilegios y baje a una cuenta sin privilegios tras la inicialización; el otro hace que el gestor de servicios lo lance con una identidad restringida desde la primera instrucción. Cada uno funciona por sí solo, y la combinación suele producir un servicio que no puede hacer limpiamente ninguno de los dos trabajos. El resto de esto recorre la decisión en orden.

Dos modelos, un solo dueño del cambio

El primer modelo pertenece al demonio. Las opciones OpenVPN de la comunidad user y group cambian la identidad una vez configurados el túnel y las claves, y persist-key más persist-tun mantienen esos recursos utilizables después.

El segundo modelo pertenece al gestor de servicios. Un ajuste systemd User= o Group= decide la identidad con la que arranca el proceso, y las directivas de capacidades deciden qué puede retener. Elegir entre los modelos es una cuestión de empaquetado antes que de seguridad, y el mantenedor del paquete ya la respondió. Su trabajo es encontrar esa respuesta en lugar de inventar una tercera opción.

Ambos son legítimos. El error es tratarlos como capas de un mismo diseño, porque el segundo modelo puede convertir el cambio de identidad del primero en una operación que el proceso ya no tiene permiso de realizar.

Decida dónde cambia la identidad

Si la unidad ya arranca como una cuenta dedicada, añadir una instrucción del demonio para pasar a otra cuenta pide una transición setuid que un servicio endurecido nunca debió hacer. El fallo aparece como un error de permisos al arrancar en lugar de como un mensaje de política claro. Se lee como una capacidad que falta, lo que empuja a la gente hacia un conjunto de límites más amplio en vez de hacia la cuestión de la identidad.

Lea lo que el paquete instalado entrega realmente antes de editar nada, incluido su directorio drop-in. Algunas unidades omiten deliberadamente la caída propia del demonio porque el gestor ya se encarga de ella, y otras dependen de esas opciones para el cambio posterior a la inicialización. Quitar cualquiera de las dos sin saber qué modelo heredó es la forma en que un servicio que funciona deja de arrancar.

Escriba el modelo elegido en una línea: propiedad del gestor o propiedad del demonio. Cada directiva posterior debe ser coherente con esa frase, y una unidad mixta debe tratarse como un error y no como un compromiso.

Las capacidades son límites, no concesiones

Un conjunto de límites de capacidades dice qué puede retener un proceso como máximo. Es un techo, y enumerar una capacidad ahí no concede nada por sí solo, por eso una unidad con un conjunto de límites generoso puede aun así no lograr crear un túnel.

Lo que de verdad coloca una capacidad en el conjunto ambiental de un servicio es AmbientCapabilities=. La referencia de ejecución de systemd documenta las dos directivas por separado, y esa distinción explica la mayor parte de los consejos confusos sobre capacidades que hay en línea.

Añada una capacidad solo después de que la operación que falla la identifique. Un conjunto de límites más amplio oculta la causa real y deja el servicio más privilegiado de lo que el diseño pretendía. También hace la unidad más difícil de revisar, porque el techo ya no describe el trabajo. Retire la capacidad extra una vez corregido el fallo real.

Asigne la autoridad a lo largo del ciclo de vida

Enumere qué debe hacer el proceso en cada etapa: arranque, estado estable, reautenticación y desmontaje. La creación de la interfaz, los cambios de rutas, la lectura de una clave protegida y la invocación de un ayudante no ocurren todos en el mismo momento ni con los mismos requisitos. Ordene la lista por etapa antes de ordenarla por capacidad.

Las opciones de persistencia conservan recursos a través de la renegociación, y no conceden permisos que nunca se tuvieron. Una clave que el proceso no puede leer al arrancar seguirá siendo ilegible después, digan lo que digan los indicadores de persistencia. Los indicadores conservan lo que ya funcionaba.

Use una cuenta dedicada en lugar de una compartida. Los desarrolladores de OpenVPN advierten contra la costumbre de usar nobody como ejemplo genérico, porque otros servicios del host pueden estar ya ejecutándose con esa cuenta y el aislamiento que cree tener no está ahí.

Las funciones que cambian la carga local, como la descarga del canal de datos o una compilación que enlaza de otra forma, pueden desplazar qué operaciones hacen falta. Revise el mapa cuando cambie el paquete, no solo cuando algo se rompa.

Escriba el plan y conserve acceso de recuperación

Un registro de despliegue debería nombrar al gestor, la identidad de arranque, la identidad estable prevista y cada concesión junto con la operación que la requiere. Ese registro es lo que hace revisable el siguiente cambio en lugar de experimental.

Mantenga el acceso a la consola mientras edita, porque una unidad que falla al arrancar es difícil de reparar en remoto. Pruebe un reinicio y un reinicio completo antes de dar el cambio por terminado. Una unidad que sobrevive a un reinicio puede fallar todavía antes de que la red esté lista.

El éxito es un ciclo de vida de autoridad mínima comprendido, no un proceso que resulta que corre bajo un nombre que no es root.

Artículos relacionados