Soluciones de Problemas Relativos con SELinux

Mat McCabe, Joe Walker, Peter Boy (pboy) Version F36 and newer Last review: 2023-06-18

Si planifica habilitar SELinux en sistemas donde han sido previamente deshabilitados o si ejecuta un servicio dentro de una configuración no estándar, quizá necesite solucionar problemas de situaciones potencialmente bloqueados por SELinux. Note que en muchos casos, SELinux deniega son signos de ausencia de configuración.

Identificar denegaciones SELinux

Siga solamente los pasos necesarios desde este procedimiento; en muchos casos, necesita realizar tan solo el paso 1.

Procedimiento

  1. Cuando SELinux bloquea su escenario, el archivo /var/log/audit/audit.log es el primer lugar donde buscar más información sobre una denegación. Para consultar los registros de auditoría, utilice la herramienta ausearch. Dado que las decisiones de SELinux, como permitir o denegar el acceso, se almacenan en caché, y esta caché se conoce como Caché de Vector de Acceso (AVC), utilice los valores AVC y USER_AVC para el parámetro de tipo de mensaje, por ejemplo:

    $ sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent

    Si no hay coincidencias, marque si el demonio Audit está en ejecución. Si no lo está, repita el escenario denegado tras iniciar auditd y compruebe la bitácora Audit de nuevo.

  2. En el caso de auditd esté ejecutándose, pero no hay coincidencias dentro de la salida de ausearch, marque los mensajes proporcionados por el diario Journal de systemd:

    $ sudo journalctl -t setroubleshoot
  3. Si está activo SELinux y la demonio Audit no está ejecutándose en su sistema, entonces busque ciertos mensajes de SELinux en la salida del comando dmesg:

    $ sudo dmesg | grep -i -e type=1300 -e type=1400
  4. Incluso después de las tres comprobaciones anteriores, es posible que no haya encontrado nada. En este caso, las denegaciones de AVC pueden silenciarse gracias a las reglas dontaudit.

    Para inhabilitar temporalmente reglas de dontaudit, siga todas las denegaciones a estar en la bitácora:

    $ sudo semodule -DB

    Después de volver a ejecutar el escenario denegado y encontrar los mensajes de denegación utilizando los pasos anteriores, el siguiente comando vuelve a habilitar las reglas dontaudit en la normativa de nuevo:

    $ sudo semodule -B
  5. Si aplicas todos los cuatro pasos anteriores, y el problema aún continúa sin identificarlo, considera si SELinux realmente está bloqueando tu escenario:

    • Intercambiar a modo permisivo:

      $ sudo setenforce 0
      $ getenforce
      Permissive
    • Repita su escenario.

Si el problema aún sucede, algo diferente que SELinux está bloqueando su escenario.

Analizar SELinux deniega mensajes

Tras identificar que SELinux está bloqueando su escenario, tal vez necesita analizar la causa raíz antes de elegir una reparación.

Prerequisitos

  • Los paquetes policycoreutils-python-utils y setroubleshoot-server están instalados en su sistema.

Procedimiento

  1. Enumera más detalles sobre una denegación de acceso utilizando la instrucción sealert, por ejemplo:

    $ sealert -l "*"
    SELinux está previniendo /usr/bin/passwd desde acceso de escritura en el archivo
    /root/test.
    
    ***** Fugas de complementos (86'2 confidencia) sugeridas *****************************
    
    Si quieres ignorar passwd intentando escribir acceder al archivo de prueba,
    porque lo crees que no necesitaría este acceso.
    Entonces tendrías que informar esto como un bug.
    Puede generar un módulo de normativa local a dontaudit este acceso.
    Haga
    # ausearch -x /usr/bin/passwd --raw | audit2allow -D -M mi-passwd
    # semodule -X 300 -i my-passwd.pp
    
    ***** Fugas de complementos (86'2 confidencia) sugeridas *****************************
    
    …
    
    Mensajes de sonido sin formato
    type=AVC msg=audit(1553609555.619:127): avc:  denied  { write } for
    pid=4097 comm="passwd" path="/root/test" dev="dm-0" ino=17142697
    scontext=unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023
    tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0
    
    ..
    
    Hash: passwd,passwd_t,admin_home_t,file,write
  2. Si la salida obtenida en el paso anterior no contiene sugerencias claras:

    • Habilite la auditoría de ruta completa para ver todas las rutas para los objetos accedidos y para realizar campos visibles de evento de Auditoría de Linux:

      $ sudo auditctl -w /etc/shadow -p w -k shadow-write
    • Vacía la caché de setroubleshoot:

      $ sudo rm -f /var/lib/setroubleshoot/setroubleshoot.xml
    • Reproduzca el problema.

    • Repita el paso 1.

      Tras finalizar el proceso, deshabilite auditoría de ruta completa:

      $ sudo auditctl -W /etc/shadow -p w -k shadow-write
  3. Si sealert solo devuelve sugerencias de catchall o sugiere añadir una regla nueva utilizando la herramienta audit2allow, coincide su problema con ejemplos listados y explicados en denegaciones SELinux en la bitácora de Auditoría.

Recursos adicionales

  • Página man de sealert(8)

Fijando denegación de SELinux analizado

En muchos casos, las sugerencias proporcionadas por la herramienta sealert le proporciona la guía correcta sobre como reparar problemas relacionados para la directiva SELinux. Consulte Análisis SELinux denegación de mensajes para información como utilizar sealert para analizar denegaciones de SELinux.

Sea cuidadoso cuando la herramienta sugiere utilizar la herramienta audit2allow para cambios de configuración. No utilizaría audit2allow para generar un módulo de directiva local como su primera opción cuando vea una denegación de SELinux. La solución de problemas iniciaría con una comprobación si hay un problema de etiquetado. El segundo más a menudo es que te has cambiado una configuración de proceso, y olvidaste decirle a SELinux acerca de eso.

Problema laberinto

Una causa común de problemas de marcaje es cuando un directorio no estándar está utilizado para un servicio. Por ejemplo, en vez de utilizar /var/www/html/ para un sitio web, un administrador podría querer uso /srv/myweb/. En Empresa de Sombrero Rojo Linux, el /srv el directorio está etiquetado con el var_t tipo. Los archivos y los directorios crearon en /srv heredan este tipo. También, nuevamente creó objetos en directorios de nivel superior, como /myserver, puede ser etiquetados con el tipo default_t. SELinux impide el Servidor HTTP de Apache (httpd) desde acceder ambos estos tipos. Para dejar acceso, SELinux tiene que saber que los archivos en /srv/myweb/ están para ser accesible por httpd:

$ sudo semanage fcontext -a -t httpd_sys_content_t "/srv/myweb(/.*)?"

El comando semanage agrega el contexto del directorio /srv/myweb/ y todos los archivos y directorios por debajo de ello para la configuración de contexto de archivos SELinux. La utilidad semanage no modifica el contexto. Como usuario root, utilice la utilidad restorecon para aplicar los cambios:

$ sudo restorecon -R -v /srv/myweb

*Contexto Incorrecto La utilidad matchpathcon comprueba el contexto de una ruta de lo compara a la etiqueta por defecto para esa ruta. El ejemplo siguiente demuestra el uso de matchpathcon en un directorio que contiene archivos incorrectamente etiquetados:

$ matchpathcon -V /var/www/html/*
/var/www/html/index.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
/var/www/html/page1.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0

En este ejemplo, los archivos index.html y page1.html son etiquetados con el tipo user_home_t. Este tipo está utilizado para archivos en el directorios home del usuario. Utilizando el comando mv para mover los archivos de su directorio de home puede resultar en los archivos etiquetados con el tipo user_home_t. Este tipo no existiría externo a los directorios home. Use la utilidad restorecon para restaurar tales archivos a su tipo correcto:

$ sudo restorecon -v /var/www/html/index.html
restorecon reset /var/www/html/index.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_content_t:s0

Para restaurar el contexto de todos los archivos de un directorio, utilice la opción -R:

$ sudo restorecon -R -v /var/www/html/
restorecon reset /var/www/html/page1.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
restorecon reset /var/www/html/index.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0

Aplicaciones confinadas configuradas de forma no estándar

Los servicios pueden ejecutarse de diversas maneras. Para ello, es necesario especificar cómo se ejecutan. Esto se logra mediante variables booleanas de SELinux que permiten modificar partes de la política de SELinux en tiempo de ejecución. Esto posibilita cambios, como permitir que los servicios accedan a volúmenes NFS, sin necesidad de recargar ni recompilar la política de SELinux. Además, para ejecutar servicios en puertos distintos a los predeterminados, es necesario actualizar la configuración de la política mediante el comando semanage.

Por ejemplo, para permitir que el servidor HTTP Apache se comunique con MariaDB, habilite la variable booleana httpd_can_network_connect_db:

$ sudo setsebool -P httpd_can_network_connect_db on

Tenga en cuenta que la opción -P hace que la configuración se mantenga incluso después de reiniciar el sistema.

Si se deniega el acceso a un servicio en particular, utilice las utilidades getsebool y grep para comprobar si existen valores booleanos que permitan el acceso. Por ejemplo, utilice el comando getsebool -a | grep ftp para buscar valores booleanos relacionados con FTP:

$ getsebool -a | grep ftp
ftpd_anon_write --> off
ftpd_full_access --> off
ftpd_use_cifs --> off
ftpd_use_nfs --> off

ftpd_connect_db --> off
httpd_enable_ftp_server --> off
tftp_anon_write --> off

Para obtener una lista de valores booleanos y saber si están habilitados o deshabilitados, utilice el comando getsebool -a. Para obtener una lista de valores booleanos con su significado y saber si están habilitados o deshabilitados, instale el paquete selinux-policy-devel y utilice el comando semanage boolean -l como usuario root.

*Números de puerto

Según la configuración de la directiva, los servicios solo pueden ejecutarse en determinados números de puerto. Intentar cambiar el puerto en el que se ejecuta un servicio sin modificar la directiva puede provocar que el servicio no se inicie. Por ejemplo, ejecute el comando semanage port -l | grep http como usuario root para listar los puertos relacionados con http:

$ sudo semanage port -l | grep http
http_cache_port_t              tcp      3128, 8080, 8118
http_cache_port_t              udp      3130
http_port_t                    tcp      80, 443, 488, 8008, 8009, 8443
pegasus_http_port_t            tcp      5988
pegasus_https_port_t           tcp      5989

El tipo de puerto http_port_t define los puertos en los que Apache HTTP Server puede escuchar, que en este caso son los puertos TCP 80, 443, 488, 8.008, 8.009 y 8.443. Si un administrador configura httpd.conf de modo que httpd escuche en el puerto 9876 (Listen 9876), pero la política no se actualiza para reflejar esto, el siguiente comando falla:

$ sudo systemctl start httpd.service
Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.

$ sudo systemctl status httpd.service
httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
   Active: failed (Result: exit-code) since Thu 2013-08-15 09:57:05 CEST; 59s ago
  Process: 16874 ExecStop=/usr/sbin/httpd $OPTIONS -k graceful-stop (code=exited, status=0/SUCCESS)
  Process: 16870 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)

Un mensaje de denegación SELinux similar para el siguiente está guardado a /var/log/audit/audit.log:

type=AVC msg=audit(1225948455.061:294): avc:  denied  { name_bind } for  pid=4997 comm="httpd" src=9876 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket

Para conceder que httpd escuche en un puerto que no esté listado para el tipo de puerto http_port_t, utilice el comando semanage port para asignar una etiqueta diferente al puerto:

$ sudo semanage port -a -t http_port_t -p tcp 9876

La opción -a ` agrega un registro nuevo; la opción `-t define un tipo; y la opción -p define un protocolo. El último argumento es el número de puerto que se agregará.

Casos excepcionales, aplicaciones en evolución o defectuosas y sistemas comprometidos

Las aplicaciones pueden contener errores, lo que provoca que SELinux deniegue el acceso. Además, las reglas de SELinux están en constante evolución: es posible que SELinux no haya detectado que una aplicación se ejecuta de cierta manera, lo que podría provocar que deniegue el acceso, aunque la aplicación funcione correctamente. Por ejemplo, si se lanza una nueva versión de PostgreSQL, esta podría realizar acciones que la política actual no contempla, lo que provocaría que se deniegue el acceso, aunque debería estar permitido.

En estos casos, tras denegar el acceso, utilice la utilidad audit2allow para crear un módulo de política personalizado que permita el acceso. Puede informar sobre las reglas faltantes en la política de SELinux en Red Hat Bugzilla. Para Red Hat Enterprise Linux 8, cree informes de fallos para el producto Red Hat Enterprise Linux 8 y seleccione el componente selinux-policy. Incluya la salida de los comandos audit2allow -w -a y audit2allow -a en dichos informes de fallos.

Si una aplicación solicita privilegios de seguridad elevados, podría ser una señal de que está comprometida. Utilice herramientas de detección de intrusiones para inspeccionar este tipo de comportamiento sospechoso.

El Solution Engine del portal de clientes de Red Hat también ofrece orientación mediante un artículo que contiene una posible solución para el mismo problema o uno muy similar. Seleccione el producto y la versión correspondientes y utilice palabras clave relacionadas con SELinux, como selinux o avc, junto con el nombre del servicio o la aplicación bloqueada; por ejemplo: selinux samba.

Denegaciones de SELinux en la bitácora de auditoría

El sistema de auditoría de Linux almacena las entradas de registro en el archivo /var/log/audit/audit.log de forma predeterminada.

Para listar solo los registros relacionados con SELinux, utilice el comando ausearch con el parámetro de tipo de mensaje establecido en AVC y AVC_USER como mínimo, por ejemplo:

$ sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR

Una denegación entrada de SELinux en la bitácora de la Auditoría puede aparecer como sigue:

type=AVC msg=audit(1395177286.929:1638): avc:  denied  { read } for  pid=6591 comm="httpd" name="webpages" dev="0:37" ino=2112 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:nfs_t:s0 tclass=dir

Las partes más importantes de este apunte son:

  • avc: denied - la acción realizada por SELinux y registrada en la Caché del Vector de Acceso (AVC)

  • { read } - la acción denegada

  • pid=6591 - el identificador del proceso del sujeto que intentó realizar la acción denegada

  • comm="httpd" - el nombre del comando que se utilizó para invocar el proceso analizado

  • httpd_t - el tipo de proceso SELinux

  • nfs_t - el tipo SELinux del objeto afectado por la acción del proceso

  • tclass=dir - la clase de objeto de destino

La entrada de bitácora anterior se puede traducir como:

SELinux denegó al proceso httpd con PID 6591 y el tipo httpd_t para lectura desde un directorio con el tipo nfs_t.

El siguiente mensaje de denegación de SELinux sucede cuando el Servidor HTTP Apache intenta acceder a un directorio etiquetado con un tipo para la suite Samba:

type=AVC msg=audit(1226874073.147:96): avc:  denied  { getattr } for  pid=2465 comm="httpd" path="/var/www/html/file1" dev=dm-0 ino=284133 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file
  • { getattr }: la entrada getattr indica que el proceso de origen intentó leer la información de estado del archivo de destino. Esto ocurre antes de leer los archivos. SELinux deniega esta acción porque el proceso accede al archivo y este no tiene la etiqueta adecuada. Los permisos más comunes incluyen getattr, read y write.

  • path="/var/www/html/file1" - la ruta al objeto (destino) al que el proceso intentó acceder.

  • scontext="unconfined_u:system_r:httpd_t:s0" - el contexto SELinux del proceso (origen) que intenta la denegación de acción. En este caso, es el contexto SELinux del Servidor Apache HTTP, el cual está ejecutando con el tipo httpd_t.

  • tcontext="unconfined_u:object_r:samba_share_t:s0" - el contexto SELinux del objeto (objetivo) al que el proceso intentó acceder. En este caso, es el contexto SELinux de file1.

Esta denegación de SELinux se puede traducir como:

SELinux ha denegado el proceso httpd con PID 2465 para acceder al archivo /var/www/html/file1 con el tipo samba_share_t, el cual no es accesible a los procesos que se ejecutan en el ámbito httpd_t a no ser que lo configuró de otra manera.

Recursos adicionales

  • Páginas del man de auditd(8) y ausearch(8)