Búsqueda de sitios web

Implementación de control de acceso obligatorio con SELinux o AppArmor en Linux


Para superar las limitaciones y aumentar los mecanismos de seguridad proporcionados por los permisos y listas de control de acceso estándar ugo/rwx, la Agencia de Seguridad Nacional de los Estados Unidos (NSA) ideó un < Método de control de acceso obligatorio (MAC) conocido como SELinux (abreviatura de Security Enhanced Linux) para restringir, entre otras cosas, la capacidad de los procesos para acceder o realizar otras operaciones en objetos del sistema (como archivos, directorios, puertos de red, etc.) con el menor permiso posible, al tiempo que permite modificaciones posteriores a este modelo.

Otro MAC popular y ampliamente utilizado es AppArmor, que además de las funciones proporcionadas por SELinux, incluye un modo de aprendizaje que permite al sistema “aprender”cómo se comporta una aplicación específica y establecer límites mediante la configuración de perfiles para el uso seguro de la aplicación.

En CentOS 7, SELinux está incorporado en el propio kernel y está habilitado en modo Enforcing de forma predeterminada (más sobre esto en la siguiente sección). a diferencia de openSUSE y Ubuntu que utilizan AppArmor.

En este artículo explicaremos los conceptos básicos de SELinux y AppArmor y cómo utilizar una de estas herramientas para su beneficio dependiendo de la distribución elegida.

Introducción a SELinux y cómo usarlo en CentOS 7

Security Enhanced Linux puede funcionar de dos maneras diferentes:

  1. Aplicación: SELinux deniega el acceso según las reglas de políticas de SELinux, un conjunto de pautas que controlan el motor de seguridad.
  2. Permisivo: SELinux no niega el acceso, pero las denegaciones se registran para acciones que se habrían denegado si se hubieran ejecutado en modo obligatorio.

SELinux también se puede desactivar. Aunque no es un modo de funcionamiento en sí, sigue siendo una opción. Sin embargo, aprender a utilizar esta herramienta es mejor que simplemente ignorarla. ¡Tenlo en mente!

Para mostrar el modo actual de SELinux, utilice getenforce. Si desea alternar el modo de operación, utilice setenforce 0 (para configurarlo en Permisivo) o setenforce 1 (Aplicar fuerte>).

Dado que este cambio no sobrevivirá a un reinicio, deberá editar el archivo /etc/selinux/config y configurar la variable SELINUX en cualquiera de los dos enforcing, permissive o disabled para lograr persistencia entre reinicios:

Como nota al margen, si getenforce devuelve Desactivado, tendrá que editar /etc/selinux/config con el modo de operación deseado y reiniciar. De lo contrario, no podrá configurar (o alternar) el modo de operación con setenforce.

Uno de los usos típicos de setenforce consiste en alternar entre los modos SELinux (de enforcing a permisivo o al revés) para solucionar problemas de una aplicación que se porta mal o no funciona como se esperaba. Si funciona después de configurar SELinux en modo Permisivo, puede estar seguro de que está ante un problema de permisos de SELinux.

Dos casos clásicos en los que muy probablemente tendremos que lidiar con SELinux son:

  1. Cambiar el puerto predeterminado donde escucha un demonio.
  2. Configurar la directiva DocumentRoot para un host virtual fuera de /var/www/html.

Echemos un vistazo a estos dos casos utilizando los siguientes ejemplos.

EJEMPLO 1: Cambiar el puerto predeterminado para el demonio sshd

Una de las primeras cosas que hacen la mayoría de los administradores de sistemas para proteger sus servidores es cambiar el puerto donde escucha el demonio SSH, principalmente para desalentar a los escáneres de puertos y a los atacantes externos. Para hacer esto, usamos la directiva Port en /etc/ssh/sshd_config seguida del nuevo número de puerto de la siguiente manera (usaremos el puerto 9999 en este caso):


Port 9999

Después de intentar reiniciar el servicio y comprobar su estado veremos que no pudo iniciarse:


systemctl restart sshd
systemctl status sshd

Si echamos un vistazo a /var/log/audit/audit.log, veremos que se impidió que sshd se iniciara en el puerto 9999. por SELinux porque es un puerto reservado para el servicio JBoss Management (los mensajes de registro de SELinux incluyen la palabra “AVC” para que puedan ser fácilmente identificado a partir de otros mensajes):


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

En este punto, la mayoría de la gente probablemente desactivaría SELinux, pero nosotros no. Veremos que hay una manera de que SELinux y la escucha sshd en un puerto diferente vivan juntos en armonía. Asegúrate de tener el paquete policycoreutils-python instalado y ejecuta:


yum install policycoreutils-python

Para ver una lista de los puertos donde SELinux permite que sshd escuche. En la siguiente imagen también podemos ver que el puerto 9999 estaba reservado para otro servicio y por lo tanto no podemos usarlo para ejecutar otro servicio por el momento:


semanage port -l | grep ssh

Por supuesto, podemos elegir otro puerto para SSH, pero si estamos seguros de que no necesitaremos usar esta máquina específica para ningún servicio relacionado con JBoss, podemos modificar la regla SELinux existente y asignar ese puerto a SSH en su lugar:


semanage port -m -t ssh_port_t -p tcp 9999

Después de eso, podemos usar el primer comando semanage para verificar si el puerto se asignó correctamente, o las opciones -lC (abreviatura de lista personalizada):


semanage port -lC
semanage port -l | grep ssh

Ahora podemos reiniciar SSH y conectarnos al servicio usando el puerto 9999. Tenga en cuenta que este cambio sobrevivirá a un reinicio.

EJEMPLO 2: Elegir un DocumentRoot fuera de /var/www/html para un host virtual

Si necesita configurar un host virtual Apache utilizando un directorio distinto de /var/www/html como DocumentRoot (digamos, por ejemplo, /websrv/sites /gabriel/public_html):


DocumentRoot “/websrv/sites/gabriel/public_html”

Apache se negará a publicar el contenido porque index.html ha sido etiquetado con el tipo default_t SELinux, al que Apache no puede acceder:


wget http://localhost/index.html
ls -lZ /websrv/sites/gabriel/public_html/index.html

Al igual que en el ejemplo anterior, puede utilizar el siguiente comando para verificar que se trata de un problema relacionado con SELinux:


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

Para cambiar la etiqueta de /websrv/sites/gabriel/public_html de forma recursiva a httpd_sys_content_t, haga lo siguiente:


semanage fcontext -a -t httpd_sys_content_t "/websrv/sites/gabriel/public_html(/.*)?"

El comando anterior otorgará a Apache acceso de solo lectura a ese directorio y su contenido.

Finalmente, para aplicar la política (y hacer que el cambio de etiqueta entre en vigor inmediatamente), haga lo siguiente:


restorecon -R -v /websrv/sites/gabriel/public_html

Ahora deberías poder acceder al directorio:


wget http://localhost/index.html

Para obtener más información sobre SELinux, consulte la guía del administrador y SELinux de Fedora 22.