SELinux

1. Introducción a SELinux

SELinux (Security-Enhanced Linux) es un módulo de seguridad del núcleo de Linux que implementa un mecanismo de control de acceso obligatorio (MAC). Esto significa que, además de los permisos tradicionales de usuario y grupo, SELinux aplica políticas de seguridad que determinan qué acciones puede realizar cada proceso en el sistema. Con SELinux, incluso si un servicio se ve comprometido, la política restringe las operaciones que puede llevar a cabo, lo que añade una capa extra de protección.


2. Instalación de SELinux en Debian 12

Debian no tiene SELinux activado por defecto, por lo que es necesario instalar algunos paquetes y activarlo manualmente. Abre una terminal y ejecuta los siguientes comandos:

apt update
sudo apt install selinux-basics selinux-policy-default auditd
  • selinux-basics: Conjunto de herramientas básicas para administrar SELinux.
  • selinux-policy-default: Política de SELinux predeterminada para aplicar controles.
  • auditd: Demonio de auditoría que ayuda a registrar eventos relacionados con SELinux y otros accesos.

Luego, activa SELinux en el sistema con:

sudo selinux-activate


Este comando modificará la configuración en 

/etc/selinux/config para establecer el modo en enforcing

(aplicación de políticas). Es recomendable reiniciar el sistema para que SELinux se cargue con la configuración nueva:

sudo reboot

Una vez reiniciado, puedes verificar el estado de SELinux con:

sestatus

Deberías ver que el modo está en enforcing y se están aplicando las políticas.


3. Activación de SELinux en Modo Log (Permissive)

Antes de aplicar las configuraciones definitivas para tus servicios, es recomendable probar SELinux en modo log, conocido también como permissive mode. En este modo, SELinux no bloquea acciones que contravengan la política, sino que únicamente las registra. Esto te permite identificar y ajustar posibles denegaciones sin interrumpir el funcionamiento de los servicios.

Opciones para activar el modo log (permissive):

  1. Cambiar el modo temporalmente: Ejecuta el siguiente comando para cambiar a modo permissive sin necesidad de reiniciar:
    sudo setenforce 0

    Para verificar el cambio:

    getenforce

    Este comando debería devolver Permissive.
  2. Configurar el modo de forma permanente:

    Edita el archivo de configuración de SELinux:

    sudo vi /etc/selinux/config

    Modifica la línea que indica el modo de SELinux:

    SELINUX=permissive

    Guarda el archivo y reinicia el sistema para que los cambios tengan efecto:

    sudo reboot

Con SELinux en modo permissive, podrás revisar los logs en:

/var/log/audit/audit.log

Para identificar qué acciones serían denegadas si estuviera en modo enforcing. Esto te ayudará a ajustar la política y asegurarte de que los servicios, como DNS y SSH, funcionen correctamente antes de cambiar a modo de aplicación completa.


4. Definiciones Clave

¿Qué es semanage?

semanage es una herramienta de línea de comandos utilizada para administrar la configuración de SELinux de manera persistente. Permite, entre otras cosas, asignar o modificar los contextos de seguridad de archivos, puertos, usuarios, procesos y dispositivos. Por ejemplo, con semanage port puedes asignar un contexto específico a un puerto, lo que resulta esencial para que SELinux reconozca y aplique las políticas correctas a los servicios que operan en dichos puertos.

¿Qué son los booleanos en SELinux?

Los booleanos de SELinux son interruptores de configuración que permiten habilitar o deshabilitar ciertos comportamientos de la política de seguridad sin necesidad de modificar o reescribir la política completa. Al cambiar el valor de un booleano, puedes ajustar dinámicamente cómo interactúan los servicios con SELinux. Por ejemplo, un booleano puede permitir que un servicio realice acciones que, por defecto, estarían restringidas por la política, facilitando la adaptación de SELinux a necesidades específicas del entorno.


5. Configuración de SELinux para el Servicio DNS

Asumiremos que estás utilizando BIND9 como servicio DNS. SELinux debe estar configurado para que el puerto 53 (TCP/UDP) esté etiquetado con el contexto correcto. Para ello, utiliza la herramienta semanage.

a) Asignar el contexto adecuado al puerto DNS

En caso de que el puerto 53 no esté ya definido o desees asegurarte de que tenga el tipo adecuado (dns_port_t), ejecuta:

sudo semanage port -a -t dns_port_t -p tcp 53
sudo semanage port -a -t dns_port_t -p udp 53

Si en algún momento el puerto ya está registrado y necesitas modificarlo, puedes usar la opción -m en lugar de -a:

sudo semanage port -m -t dns_port_t -p tcp 53
sudo semanage port -m -t dns_port_t -p udp 53

b) Habilitar booleanos para el servicio DNS

Dependiendo de la política y de cómo esté configurado tu servicio, es posible que necesites ajustar algunos booleanos para permitir que BIND9 realice ciertas operaciones. Por ejemplo, si tu configuración DNS requiere que el servicio pueda escribir zonas maestras, podrías habilitar:

sudo setsebool -P named_write_master_zones 1

Nota:

La disponibilidad y el nombre exacto de los booleanos pueden variar según la distribución y la versión de la política de SELinux. Consultamos la lista de booleanos con:

sudo getsebool -a | grep named

6. Mantenimiento del Acceso SSH (Puerto 22)

Por defecto, SELinux ya tiene definido el puerto 22 para el servicio SSH (tipo ssh_port_t), pero siempre es bueno verificarlo:

sudo semanage port -l | grep ssh

Deberías ver una línea similar a:

ssh_port_t  tcp  22

Si por alguna razón el puerto 22 no aparece o se ha modificado, puedes restablecerlo usando:

sudo semanage port -m -t ssh_port_t -p tcp 22

Esto garantizará que el acceso SSH se mantenga operativo, permitiendo conexiones remotas en el puerto 22.


7.Comprobación Final

  1. Instalaste y activaste SELinux en Debian 12, con la opción de probar inicialmente en modo log (permissive) para verificar la configuración sin afectar los servicios.
  2. Se definió la función de semanage para asignar contextos de seguridad persistentes y se explicó qué son los booleanos y su utilidad para ajustar comportamientos de la política.
  3. Configuraste el servicio DNS (BIND9) asignando el contexto dns_port_t al puerto 53 para TCP y UDP.
  4. Ajustaste booleanos relevantes (por ejemplo, named_write_master_zones) para permitir las operaciones necesarias en BIND9.
  5. Verificaste que el puerto 22 para SSH sigue con el contexto correcto (ssh_port_t), asegurando el acceso remoto.

Con estos pasos, has integrado SELinux en tu servidor Debian 12 y configurado de manera específica el servicio DNS, sin afectar el acceso SSH. Te recomendamos iniciar en modo permissive para revisar los logs y realizar los ajustes necesarios antes de pasar a modo enforcing para una mayor seguridad. Revisa regularmente los logs de SELinux (por ejemplo, con ausearch o consultando /var/log/audit/audit.log) para asegurarte de que no existan denegaciones inesperadas que puedan afectar el funcionamiento de tus servicios.


8. Comando ls -Z

El comando ls -Z se utiliza para listar archivos y directorios junto con su contexto de seguridad SELinux. Cada archivo o directorio muestra información adicional que consta de varios componentes:

  • Usuario SELinux (por ejemplo, system_u): Indica el usuario del sistema SELinux asignado al objeto.
  • Rol (por ejemplo, object_r): Define el rol del objeto.
  • Tipo (por ejemplo, etc_t, dns_conf_t, ssh_config_t): Especifica la categoría del objeto, determinando qué operaciones puede realizar.
  • Nivel de seguridad (por ejemplo, s0): Representa el nivel o rango de seguridad.

Ejemplo de salida

Supongamos que ejecutamos el comando en el directorio /etc:

ls -Z /etc

La salida podría ser similar a:

-rw-r--r--. root root system_u:object_r:etc_t:s0          hosts
-rw-r--r--. root root system_u:object_r:etc_t:s0 resolv.conf
drwxr-xr-x. root root system_u:object_r:etc_t:s0 cron.d

Interpretación de la salida

  • system_u: Es el usuario del sistema SELinux asignado al archivo o directorio.
  • object_r: Es el rol que se asigna a objetos (archivos o directorios).
  • etc_t: Es el tipo o dominio. En este caso, indica que el archivo o directorio forma parte de la configuración del sistema, típicamente asociados a la ubicación /etc.
  • s0: Es el nivel de seguridad, el cual en la mayoría de los casos es s0 (sin etiquetas adicionales de nivel).

Mediante ls -Z se puede verificar que los archivos y directorios tienen asignados los contextos correctos, lo cual es fundamental para que SELinux aplique las políticas adecuadas. Si algún objeto muestra un contexto inesperado, podrías necesitar ajustarlo usando herramientas como chcon (para cambios temporales) o semanage fcontext (para cambios persistentes).


9. Configuración de auditd en Modo Permissive para SSH y Named

Cuando SELinux está en modo permissive, no bloquea las acciones que incumplen la política, pero registra eventos (mensajes AVC) que luego se almacenan en los logs de auditd. Esto es muy útil para identificar qué variables o configuraciones necesitan ser ajustadas para que, en modo enforcing, los servicios funcionen correctamente sin generar denegaciones inesperadas.

a) Configuración temporal con auditctl

Para monitorear los eventos relacionados con SSH y Named (BIND9), puedes utilizar el comando auditctl para agregar reglas que capturen ejecuciones o actividades específicas. Por ejemplo:

  • Para el servicio SSH (sshd):

    sudo auditctl -a always,exit -F arch=b64 -S execve -F exe=/usr/sbin/sshd -k sshd_monitor
  • Para el servicio Named (BIND9):

    sudo auditctl -a always,exit -F arch=b64 -S execve -F exe=/usr/sbin/named -k named_monitor

Estas reglas indican a auditd que registre siempre las llamadas al sistema execve para los ejecutables /usr/sbin/sshd y /usr/sbin/named, utilizando las claves sshd_monitor y named_monitor, respectivamente. Esto te permitirá identificar cuándo y cómo se están ejecutando estos servicios, lo que es útil para detectar posibles denegaciones o comportamientos inusuales mientras SELinux está en modo permissive.

b) Verificación de los logs

Después de haber configurado las reglas, puedes revisar los eventos relacionados utilizando ausearch. Por ejemplo:

  • Para eventos de SSH:

    sudo ausearch -k sshd_monitor
  • Para eventos de Named:

    sudo ausearch -k named_monitor

Estos comandos filtrarán los logs de auditd por las claves configuradas, mostrando los eventos que se han registrado para cada servicio.

c) Variables y ajustes a tener en cuenta

Al revisar los logs, presta atención a las siguientes variables que pueden necesitar configuración o ajuste en SELinux:

  • Contexto del proceso: Verifica que el proceso se ejecute con el contexto adecuado y que no se muestren denegaciones inesperadas.
  • Acciones denegadas: Observa los mensajes AVC en los logs para identificar qué permisos o accesos están siendo denegados.
  • Booleanos de SELinux: Si se detectan denegaciones relacionadas con permisos específicos, puede que necesites ajustar booleanos (por ejemplo, para SSH o Named) para permitir temporalmente la acción mientras corriges la política.

Esta configuración de auditd en modo permissive es muy útil , ya que les permite ver de forma práctica cuáles son las variables y configuraciones que deben monitorear y ajustar antes de pasar SELinux a modo enforcing en un entorno de producción.