La autenticación mediante PAM puede tener éxito cuando ejecuta el cliente a mano y fallar con AUTH_FAILED en cuanto systemd inicia el mismo perfil. La contraseña no cambia entre esas ejecuciones; lo que cambia es el conjunto de restricciones en torno al proceso que pregunta a PAM. PAM responde mediante un ayudante cuya capacidad de cambiar sus propias credenciales es exactamente lo que elimina una unidad endurecida. Encuentre ese ayudante y el límite que necesita antes de tocar una lista de capacidades.

unix_chkpwd es el binario que responde a la pregunta de PAM

Con autenticación local por contraseña, pam_unix rara vez lee el propio archivo hash. Ejecuta unix_chkpwd, que las distribuciones instalan como setuid root o setgid shadow para que una contraseña pueda comprobarse en nombre de un proceso que no tiene nada que hacer leyendo /etc/shadow. Quite la capacidad de adquirir esa identidad y el ayudante no podrá completar la comprobación, así que el módulo devuelve un simple fallo de autenticación.

El fallo entonces parece un problema de credenciales en todos los registros que el cliente puede ver. Esa es la trampa: el cliente informa de lo que PAM le dijo, y PAM solo informa de que la pila dijo no. Ejecutar el ayudante a mano como root tampoco demuestra nada, porque ejercita una ruta de privilegios que el servicio nunca usa. Lea la unidad que systemd cargó realmente y después el registro del sistema para el intento que hizo. Esas dos vistas separan un problema de sandbox de un problema de contraseña incorrecta.

Lea la unidad antes de leer el registro de contraseñas

Una unidad empaquetada puede llevar un drop-in que usted no escribió, y la configuración efectiva es el resultado combinado. Imprima la unidad tal como la ve systemd, junto con los ajustes de sandbox que deciden si el ayudante puede elevarse. La inspección de solo lectura es suficiente en esta etapa.

systemctl cat [email protected]
systemctl show [email protected] -p User -p Group -p CapabilityBoundingSet -p AmbientCapabilities -p NoNewPrivileges
journalctl -u [email protected] -b

El primer comando muestra de dónde vienen la unidad y sus drop-ins, lo cual importa porque una anulación añadida hace meses sobrevive a la memoria de por qué existe. El segundo imprime los valores de sandbox de los que dependen las dos secciones siguientes.

Compare lo que ve con un host funcional de la misma distribución y versión. Una diferencia en User, CapabilityBoundingSet o NoNewPrivileges es una pista concreta; una diferencia en comentarios de prosa no lo es. Anote los valores antes de cambiar nada, porque una comparación posterior contra un objetivo móvil no demuestra nada. Si el servicio se ejecuta con una cuenta sin privilegios y un conjunto bounding vacío, el ayudante casi no tiene con qué trabajar.

Transformación de credenciales, acceso a archivos y política son tres límites

Empiece por lo que ocurre durante exec. Un binario setuid o un archivo con capacidades de archivo desencadena una transformación de credenciales, así que la identidad resultante no es una continuación del llamador. El conjunto bounding limita lo que puede adquirir ese binario, y NoNewPrivileges bloquea directamente las adquisiciones de setuid, setgid y capacidades de archivo. Cualquiera de las tres puede detener al ayudante dejando intactas las demás funciones del servicio.

A continuación, separe la elusión discrecional amplia del acceso de lectura estrecho. CAP_DAC_OVERRIDE omite las comprobaciones discrecionales casi en todas partes, mientras que CAP_DAC_READ_SEARCH cubre la lectura y el recorrido de directorios con sus propios poderes adicionales. Son herramientas distintas con radios de impacto distintos, y ninguna es una forma de escribir deja que PAM lea el archivo shadow.

Por último, pregunte si la política obligatoria permite la acción siquiera. Una capacidad de Linux no anula SELinux, y poseer una no demuestra nada sobre una regla de type enforcement. Trate una denegación de acceso a archivo y una denegación de capacidad como pruebas distintas, porque nombran correcciones distintas y a menudo propietarios distintos. Lea cada campo del registro en lugar de la sola palabra denied. Qué ejecutable realizó la acción, en qué dominio se ejecutó, qué tipo de objetivo tocó, qué clase de objeto estaba implicada y qué permiso denegó la política: cada uno estrecha la respuesta de una manera diferente.

Extraiga la denegación del registro de auditoría

En un host en modo de aplicación, el rastro de auditoría es el único lugar que registra una denegación. Consulte los eventos recientes y léalos contra la marca de tiempo del inicio de sesión fallido, no contra la hora en que empezó a investigar.

ausearch -m AVC,USER_AVC -ts recent

Un resultado vacío no es prueba de inocencia. Significa que o bien la auditoría no recopila, o bien su ventana se perdió el intento, y ambas posibilidades deben descartarse antes de descartar la política.

La guía de solución de problemas de SELinux de Red Hat sitúa las comprobaciones de etiquetas y configuración antes de generar reglas de allow, que también es el orden correcto para este problema. Un ayudante mal etiquetado y un hueco de política producen denegaciones similares pero necesitan reparaciones distintas. Generar una regla de allow para un error de etiquetado oculta la falla y deja que la siguiente actualización del paquete la reintroduzca. Confirme la etiqueta del ayudante instalado antes de escribir cualquier política.

Demuestre el cambio con un inicio de sesión aceptado y otro rechazado

Cambie solo el límite que ha demostrado y luego pruebe ambos resultados. Una cuenta que debería autenticarse debe tener éxito, y una cuenta con contraseña incorrecta debe seguir fallando. Un cambio que hace que todos los intentos tengan éxito ha eliminado la autenticación en lugar de repararla.

Realice un intento de conexión real y lea el diario inmediatamente después. La línea que demuestra la corrección es la entrada pam_unix(openvpn:auth) de ese intento: debería indicar autenticación correcta, y ningún registro AVC debería llevar el mismo segundo.

journalctl -u [email protected] -n 30 --no-pager
ss -tnp | grep openvpn

Un túnel funcional también necesita una reconexión, porque los cambios de sandbox rompen la segunda conexión más a menudo que la primera. Compruebe el socket establecido tras la reconexión y confirme que la misma unidad sigue sirviéndolo.

Artículos relacionados