Hardening Linux con SELinux: guía completa y práctica

Última actualización: 10 de marzo de 2026
  • SELinux aplica control de acceso obligatorio basado en políticas y contextos, añadiendo una capa crítica de hardening sobre los permisos Unix tradicionales.
  • Una configuración eficaz exige etiquetar bien el sistema de ficheros, elegir el modo adecuado (permissive/enforcing) y ajustar booleans y módulos sin debilitar la política base.
  • La integración de SELinux con RHEL, Fedora, SUSE y openSUSE permite mitigar el impacto de muchas CVEs y confinar servicios como servidores web, contenedores y demonios de red.
  • La automatización del hardening y el uso sistemático de logs y herramientas como audit2allow facilitan mantener SELinux operativo en producción sin sacrificar estabilidad.

Hardening Linux con SELinux

Cuando montas un servidor Linux para producción, su configuración por defecto suele ser bastante abierta. Está pensada para que todo funcione a la primera, no para que sea un búnker. Ahí es donde entra en juego SELinux como pieza clave del hardening: añade una capa de control que sigue trabajando incluso cuando las típicas defensas (permisos de archivos, firewall, actualizaciones) fallan.

SELinux puede parecer árido al principio, pero una vez entiendes sus conceptos básicos se convierte en una herramienta brutal para contener exploits, limitar daños y cumplir benchmarks de seguridad como CIS, PCI DSS o entornos de alta criticidad. En lugar de fiarse de que las aplicaciones se comporten bien, el sistema fuerza a cada proceso a moverse dentro de unos límites muy concretos.

Qué es SELinux y por qué importa en el hardening de Linux

Security-Enhanced Linux es una extensión de seguridad del kernel de Linux basada en Mandatory Access Control (MAC). A diferencia del control de acceso discrecional (DAC) clásico de Unix, donde el dueño de un archivo decide quién entra, en SELinux las reglas las dicta una política central que ni los propios usuarios root pueden saltarse sin cambiarla explícitamente.

Este modelo hace que las decisiones de acceso se tomen en función de etiquetas de seguridad (contextos) y reglas predefinidas, no sólo de permisos rwx. Aunque un servicio haya sido comprometido o lleve permisos de más, SELinux puede impedir que toque ficheros sensibles, dispare otros procesos o se mueva por la red fuera de lo que se ha autorizado.

SELinux no sustituye al DAC tradicional, lo complementa. Primero se comprueban los permisos Unix de toda la vida y, sólo si DAC permitiría la operación, entra SELinux a validar su política. Si DAC ya bloquea el acceso, SELinux ni interviene ni registra nada, lo que ayuda a reducir ruido en los logs y mantiene el rendimiento.

Este enfoque por capas se nota especialmente en entornos enterprise como Red Hat Enterprise Linux, Fedora, SUSE Linux Enterprise u openSUSE Leap, donde SELinux se integra con el resto de mecanismos de seguridad del sistema y con tecnologías modernas como contenedores y máquinas virtuales.

SELinux para endurecer sistemas Linux

Conceptos clave: políticas, contextos y dominios SELinux

La base de SELinux son las políticas de seguridad que describen quién puede hacer qué, contra qué y cómo. En ese lenguaje, los procesos se consideran sujetos (subjects) y los recursos del sistema (archivos, directorios, sockets, puertos, dispositivos, etc.) son objetos (objects).

En lugar de pensar en usuarios como “root” o “www-data”, SELinux trabaja con dominios y tipos. Un proceso del servidor web Apache, por ejemplo, se ejecuta en el dominio httpd_t, mientras que los ficheros que se sirven al cliente tienen un tipo como httpd_sys_content_t. La política define qué dominios pueden acceder a qué tipos, para qué clases de objetos (file, dir, socket, port…) y con qué permisos concretos (read, write, execute, getattr, append, etc.).

Cada objeto tiene asociado un contexto SELinux, una etiqueta de la forma:

usuario:rol:tipo:nivel

Por ejemplo, un fichero podría estar etiquetado como system_u:object_r:httpd_sys_content_t:s0, donde el campo más importante para la administración diaria suele ser el tipo (httpd_sys_content_t), que determina a qué dominios de proceso se le permitirá el acceso.

En la práctica, SELinux trabaja con miles de reglas. Para que esto no sea ingobernable, las políticas se dividen en módulos independientes que se pueden activar, desactivar o actualizar sin tener que recompilar un bloque monolítico gigante. Esto es fundamental tanto en RHEL como en SUSE u openSUSE, donde cada servicio relevante suele tener su propio módulo de política.

Modos de funcionamiento de SELinux: enforcing, permissive y disabled

SELinux puede operar en tres modos distintos, que marcan hasta qué punto sus reglas se aplican sobre el sistema en tiempo real:

En modo enforcing (cumplimiento), el kernel aplica estrictamente la política. Cualquier acción que viole las reglas se bloquea y se registra en los logs. Es el modo recomendado para producción cuando la política ya está bien afinada, porque es donde SELinux realmente protege.

En modo permissive (permisivo), SELinux sigue evaluando la política, pero no bloquea nada. Todas las violaciones se registran como avisos. Este modo es ideal para fases de pruebas, despliegue de nuevas aplicaciones o afinado de reglas, porque permite detectar qué rompería el enforcing sin interrumpir servicios.

En modo disabled, SELinux está completamente deshabilitado. No se aplican políticas ni se generan logs relacionados con SELinux. Cambiar entre disabled y un modo activo (permissive o enforcing) requiere reiniciar, porque el kernel debe arrancar con el soporte SELinux inicializado para poder etiquetar el sistema de ficheros.

  Copia de Seguridad en la Nube vs Local

Una práctica muy sensata en cualquier distro es arrancar inicialmente en permissive, revisar y corregir problemas de etiquetado y de política, y sólo cuando todo está estable pasar a enforcing. Dejarlo permanentemente en disabled elimina una de las capas de protección más potentes que tienes disponibles.

Integración de SELinux en RHEL, Fedora, SUSE y openSUSE

Distribuciones como Red Hat Enterprise Linux, Fedora y derivadas activan SELinux por defecto, normalmente usando una política dirigida (targeted) que confina principalmente a los servicios de sistema iniciados por systemd y a algunos usuarios.

En RHEL, además de la política preconfigurada, se ofrece una serie de herramientas pensadas para que el administrador no tenga que pelearse con reglas de bajo nivel todo el tiempo. Destaca SELinux Troubleshooter, que analiza los eventos de denegación y propone cambios concretos (como activar un booleano, corregir un contexto o generar un módulo adicional).

Además, SELinux se extiende a contenedores (por ejemplo con Podman) y a entornos virtualizados. Con etiquetas apropiadas, se consigue que cada contenedor o VM quede aislado de los demás a nivel de kernel, incluso si se produjera una fuga por vulnerabilidades internas del runtime o del hipervisor.

En el ecosistema SUSE, SUSE Linux Enterprise Server trae el framework SELinux soportado en el kernel y herramientas, pero no una política oficial completa. El enfoque recomendado es construir una política adaptada al entorno, o usar soluciones como slemicro cuando se quiere un host minimalista para contenedores o virtualización con SELinux plenamente soportado.

En openSUSE Leap sí es habitual apoyarse en políticas disponibles en repositorios como security:/SELinux_legacy para pruebas, sabiendo que para un entorno crítico lo ideal sigue siendo una política revisada y ajustada específicamente al despliegue.

Modelos de política SELinux: targeted, MLS y minimum

SELinux puede trabajar con diferentes modelos de política, que marcan la amplitud y profundidad del control. Los tres más habituales son:

La política targeted está pensada para entornos generales. Se centra en confinar servicios concretos (especialmente demonios de red) y deja otros procesos en dominios más permisivos o incluso sin confinar. Es la opción por defecto en la mayoría de distribuciones porque equilibra bastante bien seguridad y compatibilidad.

La política de Multi-Level Security (MLS) añade el campo de nivel de sensibilidad al contexto (s0, s1, s2, categorías, etc.) y permite clasificar la información y los procesos en niveles. Está pensada para organizaciones con requisitos muy estrictos (defensa, inteligencia, entornos clasificados) donde importa quién puede ver o modificar qué nivel de datos.

La política minimum es una variante reducida, con menos reglas y controles. Se emplea en sistemas con requisitos de seguridad limitados o donde se busca un impacto mínimo en compatibilidad, sacrificando parte de la capacidad de confinamiento de SELinux.

En despliegues reales, suele ser preferible trabajar con políticas modulares targeted, ajustando módulo a módulo qué se protege y cómo, en lugar de intentar gestionar un único fichero monolítico enorme, mucho más duro de mantener.

Gestión de contextos: ver, cambiar y restaurar etiquetas SELinux

Una de las tareas clave en la administración de SELinux consiste en asegurarse de que los ficheros, directorios, procesos y puertos tienen el contexto correcto según la política. Un contexto mal asignado puede hacer que un servicio deje de funcionar o que un recurso quede demasiado expuesto.

Para inspeccionar el contexto SELinux de ficheros y directorios, muchas órdenes estándar aceptan la opción -Z. Por ejemplo, con ls -Z /ruta puedes ver usuario, rol, tipo y nivel de cada entrada, y con ps Zaux obtienes el contexto de los procesos activos.

Cuando se instala una política y se etiqueta el sistema de ficheros (por ejemplo usando setfiles o fixfiles con los archivos file_contexts), cada ruta recibe un tipo por defecto según la política. Si creas un fichero nuevo en un directorio ya etiquetado, heredará el tipo del directorio, pero si lo mueves desde otro sitio conservará su etiqueta original, lo que puede provocar incoherencias.

Si un archivo o árbol de directorios tiene las etiquetas equivocadas, puedes corregirlas con restorecon, que restaura los contextos a los valores definidos en la política. Con opciones como -R (recursivo) y -v (verbose) es fácil ver qué se está cambiando. Es un paso casi obligatorio antes de pasar de modo permissive a enforcing en sistemas que han estado un tiempo en pruebas.

Para declarar nuevos patrones de etiquetado, se utiliza semanage fcontext. Con esta herramienta escribes en la política qué tipo SELinux debe asignarse a determinados caminos o expresiones regulares, y posteriormente aplicas esos cambios al sistema de ficheros con restorecon. Así, por ejemplo, puedes etiquetar un nuevo DocumentRoot de Apache con httpd_sys_content_t para que el servidor web pueda leerlo bajo su dominio confinado.

Configuración básica: activar SELinux y elegir modo

El comportamiento de SELinux a nivel global se controla desde /etc/selinux/config, donde se define el modo (enforcing, permissive o disabled) y la política a utilizar (targeted, mls, minimum…).

  Podman, KVM y contenedores: guía práctica de virtualización segura

En sistemas como RHEL o Fedora, la política targeted suele venir habilitada por defecto y en modo enforcing, mientras que en SUSE u openSUSE hay que ajustar parámetros del kernel en GRUB2 para que se cargue SELinux en lugar de AppArmor. Esto implica añadir opciones como security=selinux y selinux=1 a la línea de arranque y regenerar la configuración de GRUB.

Tras activar SELinux en el arranque y seleccionar la política, es importante realizar un primer etiquetado completo del sistema de ficheros usando setfiles o herramientas equivalentes. Este paso puede llevar tiempo y conviene hacerlo en un momento de baja carga, pero es la base para que el sistema arranque sin sorpresas en modo enforcing.

En entornos donde se está migrando desde AppArmor, es crítico revisar muy bien los ficheros file_contexts y sus variantes locales, porque cualquier incoherencia grave puede dejar el sistema sin arrancar. Hacer una copia de seguridad previa y trabajar con semanage fcontext para alinear la política con la realidad del sistema es casi obligatorio.

SELinux y CVEs: cómo ayuda a mitigar vulnerabilidades

Proveedores como Red Hat incluyen SELinux como factor en su evaluación de impacto de CVEs. Su modelo de severidad (Crítica, Importante, Moderada, Baja) tiene en cuenta si un fallo puede ser mitigado o al menos contenido por restricciones de SELinux bien configuradas.

En una vulnerabilidad crítica de ejecución remota de código, tipo Log4Shell (CVE-2021-44228), un atacante podría inyectar código en un servicio accesible desde Internet. Si ese servicio corre bajo un dominio SELinux muy confinado, el potencial de daño se reduce, porque no tendrá permisos para leer /etc/shadow, manipular bases de datos sensibles o pivotar por el sistema fuera de lo estrictamente necesario para su función.

En fallos de elevación de privilegios como CVE-2023-4911 (Looney Tunables), incluso si el exploit llega a dar acceso a un usuario con más privilegios a nivel DAC, la política puede seguir impidiendo acciones clave como cargar módulos del kernel, escribir en directorios de sistema o abrir determinados sockets de red. El resultado es que se limita qué se puede hacer con ese acceso ganado.

En vulnerabilidades moderadas (por ejemplo, ciertos problemas en Grafana) que requieren configuraciones poco habituales o son complicadas de explotar, SELinux actúa como barrera adicional que impide que un fallo poco grave escale a incidente serio. Muchas veces, la política directamente bloquea los accesos que el exploit necesitaría para impactar al sistema.

En vulnerabilidades de impacto bajo, como bugs que provocan cuelgues en aplicaciones de usuario (por ejemplo en editores como vim), SELinux no suele ser determinante para evitar el problema en sí, pero aun así mantiene su labor de contención, asegurando que un proceso defectuoso no se sale de su sandbox conceptual.

SELinux en acción: ejemplo real de confinamiento de un servidor web

Imagina un servidor web sobre RHEL o Fedora que expone varias aplicaciones y que, a pesar de estar vacunado con parches, acaba siendo vulnerable a un exploit de ejecución remota en uno de sus componentes. Sin SELinux, un atacante que ejecute código con el usuario del servidor web podría instalar puertas traseras, leer credenciales o pivotar hacia otros sistemas.

Con SELinux en modo enforcing y una política targeted bien ajustada, los procesos de Apache, Nginx o similares se ejecutan bajo el dominio httpd_t, que tiene permisos limitados a ficheros etiquetados con tipos como httpd_sys_content_t o httpd_sys_rw_content_t, y acceso controlado a puertos definidos también con contexto apropiado.

Esto implica que, aunque el exploit permita ejecutar comandos, el proceso comprometido no puede leer ficheros como /etc/shadow ni tocar directorios de bases de datos etiquetados con tipos específicos (por ejemplo mysqld_db_t), ni abrir conexiones arbitrarias a otros servicios internos si la política de red lo restringe.

En lugar de hablar de compromiso total del sistema, la intrusión queda encerrada dentro de los límites del dominio web. Sí, seguirá siendo un incidente a investigar, pero el techo del impacto es mucho más bajo y el atacante lo tiene, literalmente, mucho más difícil para moverse.

Booleans, módulos y herramientas para ajustar políticas

Además de etiquetar bien, el día a día con SELinux suele girar en torno a tocar pequeños ajustes sobre la política base sin tener que reescribirla entera. Aquí entran en juego los booleans y los módulos personalizados.

Los booleans SELinux son conmutadores on/off que alteran partes del comportamiento de la política ya compilada. Por ejemplo, un booleano puede permitir o prohibir que el servidor FTP escriba en determinados directorios (caso de allow_ftpd_anon_write), o que el servidor web inicie conexiones salientes hacia la red.

Con getsebool -a o semanage boolean -l puedes listar estos interruptores y ver su descripción. Para cambiarlos de forma persistente, se usa setsebool -P nombre_booleano on|off, donde la opción -P asegura que el cambio se guarda en disco y sobrevive a reinicios. Es una manera muy cómoda de adaptar la política “oficial” a las necesidades concretas de tu servidor.

  Sistemas operativos ligeros para revivir PC antiguos

Por otro lado, el uso de módulos de política permite extender o modificar reglas sin tocar la política base. Puedes ver los módulos activos con semodule -l, desactivar alguno con semodule -d nombre o volver a activarlo con semodule -e nombre. En SUSE/openSUSE esto es especialmente útil para ir ajustando qué partes del sistema quieres que estén bajo el foco de SELinux mientras estabilizas tu despliegue.

Cuando necesitas conceder permisos adicionales muy específicos, la combinación de audit2allow y semodule facilita mucho la vida. A partir de los registros de /var/log/audit/audit.log, audit2allow te muestra qué regla bloquearon y te genera un módulo que, si lo instalas, permite justo aquello que antes se denegaba.

Logs, auditoría y resolución de problemas con SELinux

Cada vez que SELinux impide una acción que la política no autoriza, se genera un AVC denial (Access Vector Cache denial) que queda registrado, normalmente, en /var/log/audit/audit.log, siempre que el servicio auditd esté funcionando.

Estas entradas incluyen mucha información: qué se ha intentado hacer (avc: denied { append }, write, getattr, etc.), qué proceso lo ha pedido (pid, comm=), sobre qué fichero o recurso (name=, dev=, ino=), qué contexto tenía el proceso de origen (scontext) y qué contexto el destino (tcontext). Al principio parecen líneas crípticas, pero con algo de práctica son oro puro para entender qué está pasando.

Para no volverse loco leyendo el log a mano, herramientas como ausearch permiten filtrar por tipo de mensaje (por ejemplo, -m AVC) o por ventana temporal (-ts recent). Y, sobre todo, audit2allow y utilidades como sealert ayudan a traducir estos eventos a lenguaje casi humano y mostrar sugerencias.

Un flujo típico de troubleshooting sería usar audit2allow -w -a para ver explicaciones de los últimos avisos, luego audit2allow -a o -i fichero para inspeccionar reglas concretas, y finalmente decidir si compensa generar un módulo que abra ese permiso o si, por el contrario, el bloqueo está del lado seguro y no conviene tocarlo.

Siempre que se generen módulos con audit2allow -M nombre y se instalen con semodule -i, conviene revisarlos, porque la herramienta tiende a ser generosa y podría conceder más accesos de los estrictamente necesarios. SELinux da mucho juego para endurecer, pero un uso descuidado puede terminar abriéndole huecos a la propia política.

SELinux dentro de una estrategia de hardening Linux

SELinux no vive en el vacío: se integra en una estrategia más amplia de hardening que incluye usuarios con privilegios limitados, firewalls, endurecimiento de SSH, mecanismos anti fuerza bruta y automatización de configuraciones.

Un patrón muy habitual tras instalar un servidor es crear un usuario con privilegios sudo acotados para no trabajar nunca como root directo, activar un firewall de red (como ufw o iptables/nftables), instalar herramientas como Fail2ban para bloquear intentos repetitivos de acceso y configurar SSH con buenas prácticas (puerto no estándar, desactivar acceso de root, autenticación por clave, límites de intentos, cifrados robustos, etc.).

Sobre esa base, SELinux añade la capa de MAC: aunque un atacante consiga un usuario con sudo mal configurado o una contraseña SSH, la política puede seguir acotando qué procesos y qué ficheros toca ese usuario cuando hace sus acciones. No es infalible, pero cierra muchas de las puertas que suelen explotar los ataques automatizados descritos en matrices como MITRE ATT&CK.

A medida que crece el número de servidores, aplicar manualmente todas estas medidas de hardening se vuelve inviable. Aquí entran en juego herramientas de automatización y orquestación (Ansible, Puppet, Chef, soluciones comerciales de hardening automatizado, etc.) que permiten desplegar políticas SELinux coherentes, ajustar booleanos, etiquetar rutas y mantener los estados deseados sin dedicar horas por máquina.

En organizaciones con cientos de nodos, esta automatización puede ser la diferencia entre tener un entorno razonablemente homogéneo y seguro, o una selva de configuraciones inconsistentes donde SELinux está desactivado en la mitad de los servidores “para que no moleste”.

Al final, cuando SELinux está bien planteado —modo enforcing, contextos coherentes, políticas revisadas, módulos afinados y logs vigilados— se convierte en una especie de red de seguridad que mantiene a raya comportamientos extraños, contiene intrusiones y ayuda a demostrar que se están aplicando controles de acceso robustos de cara a auditorías, regulaciones y buenas prácticas de seguridad.

contenedores linux cgroups namespaces
Artículo relacionado:
Namespaces y cgroups en Linux: la base real de los contenedores