Durante esta serie hemos explorado en detalle al menos dos métodos de control de acceso: los permisos estándar ugo/rwx (Gestionar Usuarios y Grupos – Parte 3) y las listas de control de acceso (Configurar ACL en Sistemas de Archivos – Parte 7).

Aunque son necesarios como mecanismos de control de acceso de primer nivel, tienen algunas limitaciones que son abordadas por Security Enhanced Linux (también conocido como SELinux).
Una de esas limitaciones es que un usuario puede exponer un archivo o directorio a una vulnerabilidad de seguridad mediante un comando chmod mal elaborado y así causar una propagación inesperada de los derechos de acceso. Como resultado, cualquier proceso iniciado por ese usuario puede hacer lo que quiera con los archivos propiedad del usuario, donde finalmente un software malicioso o comprometido de otra manera puede lograr acceso de nivel de raíz al sistema completo.
Con esas limitaciones en mente, la Agencia de Seguridad Nacional de los Estados Unidos (NSA) ideó por primera vez SELinux, un método flexible de control de acceso obligatorio, para restringir la capacidad de los procesos de acceder o realizar otras operaciones en objetos del sistema (como archivos, directorios, puertos de red, etc.) al modelo de permisos mínimo, que puede ser modificado más tarde según sea necesario. En pocas palabras, a cada elemento del sistema se le otorga solo el acceso necesario 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 de SELinux
SELinux puede operar de tres formas diferentes:
- Enforcing: SELinux niega el acceso según las reglas de política de SELinux, un conjunto de pautas que controlan el motor de seguridad.
- Permissive: SELinux no niega el acceso, pero los rechazos se registran para acciones que hubieran sido denegadas si se ejecutaran en modo enforcing.
- Disabled (autoexplicativo).
El comando getenforce
muestra el modo actual de SELinux, mientras que setenforce
(seguido de un 1 o un 0) se utiliza para cambiar el modo a Enforcing o Permissive, respectivamente, solo durante la sesión actual.
Para lograr persistencia entre cierres de sesión y reinicios, deberás editar el archivo /etc/selinux/config
y establecer la variable SELINUX en enforcing, permissive, o disabled:
# getenforce # setenforce 0 # getenforce # setenforce 1 # getenforce # cat /etc/selinux/config

Normalmente, utilizarás setenforce para alternar entre los modos de SELinux (de enforcing a permissive y viceversa) como primer paso de solución de problemas. Si SELinux está actualmente configurado en enforcing mientras experimentas un cierto problema, y el mismo desaparece cuando lo configuras en permissive, puedes estar seguro de que estás enfrentando un problema de permisos de SELinux.
Contextos SELinux
A SELinux context consists of an access control environment where decisions are made based on SELinux user, role, and type (and optionally a level):
- 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.
- El concepto de rol actúa como intermediario entre dominios y usuarios de SELinux en el sentido de que define a qué dominios de procesos y tipos de archivos se puede acceder. Esto protegerá su sistema contra vulnerabilidades a ataques de escalada de privilegios.
- 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.
Vamos a ver cómo funciona todo eso a través de los siguientes ejemplos.
EJEMPLO 1: Cambiar el puerto predeterminado para el demonio sshd
En Asegurando SSH – Parte 8 explicamos que cambiar el puerto predeterminado en el que sshd escucha es una de las primeras medidas de seguridad para proteger su servidor contra ataques externos. Editemos el archivo /etc/ssh/sshd_config
y establezcamos el puerto en 9999:
Port 9999
Guarde los cambios y reinicie sshd:
# systemctl restart sshd # systemctl status sshd

Como puede ver, sshd no ha podido iniciarse. ¿Pero qué sucedió?
A quick inspection of /var/log/audit/audit.log
indicates that sshd has been denied permissions to start on port 9999 (SELinux log messages include the word “AVC” so that they might be easily identified from other messages) because that is a reserved port for the JBoss Management service:
# cat /var/log/audit/audit.log | grep AVC | tail -1

En este punto, podría desactivar SELinux (¡pero no lo haga!) como se explicó anteriormente e intentar iniciar sshd de nuevo, y debería funcionar. Sin embargo, la utilidad semanage puede decirnos qué necesitamos cambiar para poder iniciar sshd en el puerto que elijamos sin problemas.
Ejecute,
# semanage port -l | grep ssh
para obtener una lista de los puertos en los que SELinux permite que sshd escuche.

Entonces cambiemos el puerto en /etc/ssh/sshd_config
a 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 puedes ver, el servicio se inició con éxito esta vez. Este ejemplo ilustra el hecho de que SELinux controla el número de puerto TCP según sus propias definiciones internas de tipo de puerto.
EJEMPLO 2: Permitir que httpd envíe acceso a sendmail
Este es un ejemplo de SELinux gestionando un proceso que accede a otro proceso. Si fueras a implementar mod_security y mod_evasive junto con Apache en tu servidor RHEL 7, necesitas permitir que httpd acceda a sendmail para enviar una notificación de correo tras un ataque (D)DoS. En el siguiente comando, omite la bandera -P si no deseas que el cambio sea persistente tras reinicios.
# semanage boolean -1 | grep httpd_can_sendmail # setsebool -P httpd_can_sendmail 1 # semanage boolean -1 | grep httpd_can_sendmail

Como puedes ver en el ejemplo anterior, las configuraciones de booleanos SELinux (o simplemente booleanos) son reglas verdaderas/falsas integradas en las políticas de SELinux. Puedes listar todos los booleanos con semanage boolean -l
, y alternativamente filtrar la salida con grep.
EJEMPLO 3: Servir un sitio estático desde un directorio distinto al predeterminado
Supongamos que estás sirviendo un sitio web estático usando un directorio distinto al predeterminado (/var/www/html
), digamos /websites (esto podría ser el caso si estás almacenando tus archivos web en una unidad de red compartida, por ejemplo, y necesitas montarla en /websites).
a). Create an index.html file inside /websites with the following contents:
<html> <h2>SELinux test</h2> </html>
Si lo haces,
# ls -lZ /websites/index.html
Verás que el archivo index.html ha sido etiquetado con el tipo default_t SELinux, al cual Apache no puede acceder:

b). Change the DocumentRoot directive in /etc/httpd/conf/httpd.conf
to /websites and don’t forget to update the corresponding Directory block. Then, restart Apache.
c). Browse to http://<web server IP address>
, and you should get a 503 Forbidden HTTP response.
d). Next, change the label of /websites, recursively, to the httpd_sys_content_t type in order to grant Apache read-only access to that directory and its contents:
# semanage fcontext -a -t httpd_sys_content_t "/websites(/.*)?"
e). Finally, apply the SELinux policy created in d):
# restorecon -R -v /websites
Ahora reinicia Apache y navega a http://<dirección IP del servidor web>
de nuevo y verás que el archivo html se muestra correctamente:

Resumen
En este artículo hemos repasado los conceptos básicos de SELinux. Ten en cuenta que debido a la amplitud del tema, no es posible ofrecer una explicación detallada completa en un solo artículo, pero creemos que los principios descritos en esta guía te ayudarán a avanzar hacia temas más avanzados si así lo deseas.
Si me permites, permíteme recomendarte dos recursos esenciales para comenzar: la página de SELinux de la NSA y la guía de Usuario y Administrador de SELinux de RHEL 7.
No dudes en hacernos saber si tienes alguna pregunta o comentario.
Source:
https://www.tecmint.com/selinux-essentials-and-control-filesystem-access/