Serie RHCSA: Esenciales de control de acceso obligatorio con SELinux en RHEL 7 - Parte 13


Durante esta serie, hemos explorado en detalle al menos dos métodos de control de acceso: permisos ugo/rwx estándar (Administrar usuarios y grupos - Parte 3) y listas de control de acceso (Configurar ACL en sistemas de archivos - Parte 7).

Aunque son necesarios como permisos de primer nivel y mecanismos de control de acceso, tienen algunas limitaciones que son abordadas por Security Enhanced Linux (también conocido como SELinux para abreviar).

Una de esas limitaciones es que un usuario puede exponer un archivo o directorio a una brecha de seguridad a través de un comando chmod mal elaborado y, por lo tanto, causar una propagación inesperada de los derechos de acceso. Como resultado, cualquier proceso iniciado por ese usuario puede hacer lo que le plazca con los archivos propiedad del usuario, donde finalmente un software malicioso o comprometido puede lograr acceso de nivel raíz a todo el sistema.

Con esas limitaciones en mente, la Agencia de Seguridad Nacional de los Estados Unidos (NSA) diseñó primero SELinux, un método flexible de control de acceso obligatorio, para restringir la capacidad de los procesos para acceder o realizar otras operaciones en los objetos del sistema (como archivos, directorios, puertos de red). , etc.) al modelo de menor permiso, que se puede modificar más adelante según sea necesario. En pocas palabras, a cada elemento del sistema se le da solo el acceso requerido para funcionar.

En RHEL 7, SELinux está incorporado en el propio kernel y está habilitado en modo Enforcing de forma predeterminada. En este artículo explicaremos brevemente los conceptos básicos asociados con SELinux y su funcionamiento.

Modos SELinux

SELinux puede operar de tres formas diferentes:

  1. Enforcing: SELinux denies access based on SELinux policy rules, a set of guidelines that control the security engine.
  2. Permissive: SELinux does not deny access, but denials are logged for actions that would have been denied if running in enforcing mode.
  3. Disabled (self-explanatory).

El comando getenforce muestra el modo actual de SELinux, mientras que setenforce (seguido de un 1 o un 0) se usa para cambiar el modo a Enforcing o Permissive, respectivamente, durante el sesión actual solamente.

Para lograr la persistencia entre cierres de sesión y reinicios, deberá editar el archivo /etc/selinux/config y establecer la variable SELINUX en forzado, permisivo o deshabilitado:

# getenforce
# setenforce 0
# getenforce
# setenforce 1
# getenforce
# cat /etc/selinux/config

Normalmente, utilizará setenforce para alternar entre los modos SELinux (forzar a permisivo y viceversa) como primer paso de resolución de problemas. Si SELinux está configurado actualmente para hacer cumplir mientras experimenta un cierto problema, y u200bu200blo mismo desaparece cuando lo configura como permisivo, puede estar seguro de que está viendo un problema de permisos de SELinux.

Contextos SELinux

Un contexto de SELinux consiste en un entorno de control de acceso donde las decisiones se toman según el usuario, rol y tipo de SELinux (y opcionalmente un nivel):

  1. A SELinux user complements a regular Linux user account by mapping it to a SELinux user account, which in turn is used in the SELinux context for processes in that session, in order to explicitly define their allowed roles and levels.
  2. The concept of role acts as an intermediary between domains and SELinux users in that it defines which process domains and file types can be accessed. This will shield your system against vulnerability to privilege escalation attacks.
  3. A type defines an SELinux file type or an SELinux process domain. Under normal circumstances, processes are prevented from accessing files that other processes use, and and from accessing other processes, thus access is only allowed if a specific SELinux policy rule exists that allows it.

Veamos cómo funciona todo eso a través de los siguientes ejemplos.

En Asegurar SSH - Parte 8 explicamos que cambiar el puerto predeterminado donde escucha sshd es una de las primeras medidas de seguridad para proteger su servidor contra ataques externos. Editemos el archivo /etc/ssh/sshd_config y configuremos el puerto en 9999:

Port 9999

Guarde los cambios y reinicie sshd:

# systemctl restart sshd
# systemctl status sshd

Como puede ver, sshd no pudo iniciarse. ¿Pero qué pasó?

Una inspección rápida de /var/log/audit/audit.log indica que a sshd se le han negado los permisos para iniciarse en el puerto 9999 (los mensajes de registro de SELinux incluyen la palabra "AVC" para que puedan identificarse fácilmente de otros mensajes) porque ese es un puerto reservado para el servicio de administración de JBoss:

# cat /var/log/audit/audit.log | grep AVC | tail -1

En este punto, puede deshabilitar SELinux (¡pero no lo haga!) Como se explicó anteriormente e intentar iniciar sshd nuevamente, y debería funcionar. Sin embargo, la utilidad semanage puede decirnos qué necesitamos cambiar para poder iniciar sshd en cualquier puerto que elijamos sin problemas.

Correr,

# semanage port -l | grep ssh

para obtener una lista de los puertos donde SELinux permite que sshd escuche.

Así que cambiemos el puerto en /etc/ssh/sshd_config al puerto 9998, agreguemos el puerto al contexto ssh_port_t y luego reiniciemos el servicio:

# semanage port -a -t ssh_port_t -p tcp 9998
# systemctl restart sshd
# systemctl is-active sshd

Como puede ver, el servicio se inició con éxito esta vez. Este ejemplo ilustra el hecho de que SELinux controla el número de puerto TCP a sus propias definiciones internas de tipo de puerto.

Este es un ejemplo de SELinux gestionando un proceso accediendo a otro proceso. Si tuviera que implementar mod_security y mod_evasive junto con Apache en su servidor RHEL 7, debe permitir que httpd acceda a sendmail para enviar una notificación por correo después de un ataque (D) DoS. En el siguiente comando, omita la marca -P si no desea que el cambio sea persistente entre reinicios.

# semanage boolean -1 | grep httpd_can_sendmail
# setsebool -P httpd_can_sendmail 1
# semanage boolean -1 | grep httpd_can_sendmail

Como puede ver en el ejemplo anterior, las configuraciones booleanas de SELinux (o simplemente booleanas) son reglas de verdadero/falso incrustadas en las políticas de SELinux. Puede enumerar todos los valores booleanos con semanage boolean -l y, alternativamente, canalizarlos a grep para filtrar la salida.

Suponga que está sirviendo un sitio web estático usando un directorio diferente al predeterminado (/var/www/html ), digamos/websites (este podría ser el caso si está almacenando sus archivos web en un unidad de red compartida, por ejemplo, y necesita montarla en/websites).

una). Cree un archivo index.html dentro de/websites con el siguiente contenido:

<html>
<h2>SELinux test</h2>
</html>

Si lo haces,

# ls -lZ /websites/index.html

verá que el archivo index.html ha sido etiquetado con el tipo default_t SELinux, al que Apache no puede acceder:

si). Cambie la directiva DocumentRoot en /etc/httpd/conf/httpd.conf a/websites y no olvide actualizar el bloque de directorio correspondiente. Luego, reinicie Apache.

C). Vaya a http:/ y debería obtener una respuesta HTTP prohibida 503.

re). A continuación, cambie la etiqueta de/websites, de forma recursiva, al tipo httpd_sys_content_t para otorgar acceso de solo lectura a Apache a ese directorio y su contenido:

# semanage fcontext -a -t httpd_sys_content_t "/websites(/.*)?"

mi). Finalmente, aplique la política de SELinux creada en d):

# restorecon -R -v /websites

Ahora reinicie Apache y busque http:/ nuevamente y verá que el archivo html se muestra correctamente:

Resumen

En este artículo hemos analizado los conceptos básicos de SELinux. Tenga en cuenta que debido a la amplitud del tema, no es posible una explicación detallada completa en un solo artículo, pero creemos que los principios descritos en esta guía lo ayudarán a pasar a temas más avanzados si así lo desea.

Si puedo, permítame recomendarle dos recursos esenciales para comenzar: la página NSA SELinux y la guía del usuario y administrador de RHEL 7 SELinux.

No dude en informarnos si tiene alguna pregunta o comentario.