Un tiempo de actividad largo solo demuestra que el arranque tuvo éxito con los privilegios que el demonio tenía en ese momento. Los fallos que importan aquí llegan después: un cliente nuevo se conecta, se reemplaza una lista de revocación, un script auxiliar necesita escribir un archivo. Cada uno es una apertura nueva realizada por la cuenta sin privilegios, con su propia pregunta de permisos y su propio mensaje de error. Tres decisiones separan una configuración que sigue funcionando de otra que falla en el siguiente evento.

Separe lo que se cargó pronto de lo que se abre más tarde

Un descriptor es un manejador sobre una descripción de archivo abierta, y el modo de acceso se fijó al crear esa descripción. Cambiar el usuario del proceso después no cierra el manejador, por eso un archivo de clave leído como root sigue funcionando tras la caída. El modo tampoco cambia: un manejador abierto para lectura no se vuelve escribible, y un manejador escribible no se revoca solo porque la cuenta perdió sus derechos sobre la ruta. Estos dos hechos explican la mayor parte del comportamiento sorprendente de estos informes.

La otra mitad es memoria. Un demonio puede analizar un certificado, conservar el material analizado y cerrar el archivo; lo que queda en uso son datos, no un archivo abierto. Por eso el tráfico continuo no demuestra ni que haya un descriptor abierto ni que el nombre de la ruta sea alcanzable. Solo demuestra que el material necesario para la sesión actual se obtuvo antes.

Una apertura posterior es otra transacción. Se ejecuta con las credenciales actuales, el contexto de seguridad actual y la vista de montaje actual, así que una ruta legible en el arranque puede ser rechazada en la siguiente conexión. La rotación añade una trampa: escribir un archivo nuevo sobre el mismo nombre de ruta deja un descriptor existente unido al objeto antiguo, así que una recarga puede parecer exitosa mientras el demonio aún usa el contenido anterior. Compare el inodo que mantiene el proceso con el del disco antes de creer que la rotación surtió efecto.

Nombre las tres lecturas de ejecución y cuándo se dispara cada una

Tres recursos se abren normalmente mucho después de la inicialización, y fallan en momentos distintos. Un archivo de configuración de un cliente concreto se lee cuando ese cliente se conecta, así que puede romperse para un usuario mientras los demás continúan. Los datos de revocación se consultan durante la autenticación del par y otra vez cuando se reemplaza el archivo. Un directorio temporal solo se toca cuando un script o un complemento escribe algo.

Ninguno de los tres pertenece a la ruta de arranque, por eso un servidor que ha estado sano durante semanas puede fallar en la siguiente conexión. La categoría también nombra al dueño de la corrección: los dos primeros son permisos de lectura sobre la configuración bajo la cuenta del demonio, y el tercero es una ubicación escribible con un propósito estrecho.

Path reopened laterWhat triggers the openFirst sign when it fails
Client configuration fileA connection for that client identityOne client rejected while others connect
Revocation dataPeer authentication, including after replacementRevoked and valid peers both refused
Script or plugin temporary directoryA helper needs to create a fileThe helper exits with a path error

persist-key responde a una pregunta más estrecha de lo que la mayoría supone. Mantiene el archivo de clave abierto durante los reinicios documentados de SIGUSR1 y ping-restart, y no hace nada por los archivos CCD, los datos de revocación, los ejecutables auxiliares ni un reinicio completo del proceso. Estos siguen sus propias rutas de apertura, bajo la cuenta que esté en marcha en ese momento.

Confirme la cuenta y la vista que realmente tiene

Pregunte al demonio en ejecución qué cuenta usa en lugar de confiar en el archivo de unidad, y luego compare la respuesta con lo que la unidad establece. Una discrepancia es lo primero que hay que resolver, porque cada comprobación de permisos posterior se ejecuta como quien es realmente el proceso. Después recorra la ruta componente a componente; el cruce se evalúa en cada nivel, así que un archivo legible dentro de un directorio no atravesable sigue sin ser legible. El modo final del archivo es la última pregunta, no la primera.

Los espacios de nombres y las cajas de arena de servicio añaden fronteras que la propiedad y los bits de modo no describen. Una ruta visible en su shell puede faltar o ser de solo lectura dentro de un chroot, un espacio de nombres de montaje o una unidad que oculta los directorios personales. Los módulos de seguridad añaden otra capa, así que un archivo que parece legible puede ser denegado al abrirse.

ps -o user:12,pid,args -C openvpn
systemctl show -p User -p Group -p ProtectHome -p RootDirectory [email protected]
sudo -u openvpn namei -l /etc/openvpn/ccd/alice

Una lectura correcta en la shell del administrador no prueba ninguna de esas condiciones combinadas. Ejecute la comprobación con la cuenta del demonio, con el mismo espacio de nombres y la misma caja de arena, o acepte que el resultado describe su shell y no el servidor. El tercer comando es la versión barata de esa prueba: imprime el modo de cada componente y falla en el primero que la cuenta del demonio no puede atravesar.

Conceda la escritura de ejecución en un directorio propio

La lectura es solo la mitad del inventario. Un script auxiliar puede necesitar crear un archivo de estado, un complemento puede necesitar escribir estado junto a su configuración, y esas escrituras no quedan cubiertas por hacer escribible el árbol de configuración. Dé al directorio concreto el permiso de escritura que su función necesita, con un dueño y un modo que pueda explicar. Prefiera el acceso de solo lectura para todo lo que solo se lee.

Mantenga los permisos de la clave privada separados de los archivos de política. Una clave que debe releerse tras un reinicio tiene un requisito distinto del de un archivo de cliente que se lee en cada conexión, y un solo modo permisivo para ambos concede más acceso del que pide el problema. Una cuenta de demonio dedicada con propiedad estrecha es más fácil de auditar que un grupo amplio. Cuando la clave debe sobrevivir a los reinicios, persist-key elimina la relectura en lugar de ampliar el directorio.

Decida a partir del evento que puede reproducir

Un túnel activo demuestra un solo camino por el código. El evento que necesita el archivo es la única prueba que cubre la apertura que le importa, ya sea una conexión de cliente nueva, un archivo de revocación sustituido, un reinicio suave permitido o un reinicio planificado. Elija el evento, ejecútelo y quédese con el primer error en lugar del último.

Para un reinicio suave, una señal y el registro de la unidad muestran si la clave se leyó de nuevo. Envíe la señal y luego lea las últimas líneas que escribió la unidad:

systemctl kill -s SIGUSR1 [email protected]
journalctl -u [email protected] -n 40 --no-pager

No concluya que un demonio comprometido ya no puede modificar archivos solo porque se bajaron los privilegios. Lo que aún puede hacer depende de las credenciales restantes, sus capacidades, los directorios en los que puede escribir y cualquier descriptor escribible que todavía mantenga. La reducción de privilegios estrecha la autoridad, y el inventario de aperturas de ejecución es lo que muestra hasta dónde. Escriba esa frontera junto a la configuración para que la siguiente persona no tenga que redescubrirla.

Artículos relacionados