
📘 Este artículo forma parte de nuestra Guía Completa de Linux, nuestra Guía Completa de Servidores y Virtualización y nuestra Guía Completa de Ciberseguridad. Si administras servidores Linux y quieres maximizar su seguridad, esas guías son tu punto de partida.
Introducción
SELinux (Security-Enhanced Linux) es uno de los sistemas de seguridad más potentes —y temidos— del mundo Linux. Desarrollado originalmente por la NSA y liberado como open source en 2000, proporciona un Control de Acceso Obligatorio (MAC) que va mucho más allá de los permisos tradicionales de Linux.
En 2026, SELinux es el estándar de seguridad en:
- Red Hat Enterprise Linux (RHEL)
- Fedora
- Rocky Linux
- AlmaLinux
- CentOS Stream
- Android (usa una variante)
Y aunque es famoso por «romper cosas» cuando no se entiende, bien configurado es una capa de seguridad imprescindible para cualquier servidor serio.
En esta guía completa vas a aprender:
- Qué es SELinux y por qué es diferente de los permisos tradicionales.
- Cómo funciona: contextos, políticas, modos.
- Cómo configurarlo paso a paso.
- Cómo diagnosticar problemas de accesos bloqueados.
- Comparativa con AppArmor (alternativa en Ubuntu/Debian).
- Casos de uso reales.
- Troubleshooting de errores comunes.
- FAQ con las preguntas más frecuentes.
Si nunca has administrado Linux, consulta nuestra Guía Completa de Linux. Si gestionas servidores, nuestra Guía Completa de Servidores.
Índice de contenidos
- ¿Qué es SELinux?
- ¿Por qué es importante?
- Cómo funciona: contextos, políticas, modos
- SELinux vs AppArmor
- Modos de operación
- Contextos de seguridad
- Políticas de SELinux
- Cómo configurar SELinux
- Herramientas esenciales
- Casos de uso reales
- Troubleshooting
- FAQ
- Conclusión
1. ¿Qué es SELinux?
SELinux es un módulo de seguridad del kernel Linux que implementa un modelo de Control de Acceso Obligatorio (MAC, Mandatory Access Control).
1.1 Diferencia con los permisos tradicionales (DAC)
DAC (Discretionary Access Control): el modelo tradicional de Linux.
- Cada archivo tiene un propietario.
- El propietario decide quién puede acceder.
- root puede hacer cualquier cosa.
MAC (Mandatory Access Control): el modelo de SELinux.
- Políticas predefinidas por el administrador.
- Incluso root está limitado por las políticas.
- Cada proceso, archivo y recurso tiene un contexto de seguridad.
- Aislamiento estricto.
Ejemplo práctico:
Sin SELinux, si un proceso de Apache es comprometido, el atacante tiene los permisos de www-data y puede leer/escribir lo que ese usuario pueda.
Con SELinux, incluso si el atacante compromete Apache, el proceso está limitado a su contexto específico (httpd_t) y no puede acceder a archivos fuera de su política.
1.2 Historia
- 1998: NSA empieza a desarrollar SELinux.
- 2000: se libera como open source.
- 2003: se integra en el kernel Linux 2.6.
- 2005: Fedora lo adopta por defecto.
- 2007: RHEL 5 lo incluye.
- 2026: estándar en toda la familia Red Hat.
2. ¿Por qué es importante?
2.1 Beneficios clave
1. Prevención de accesos no autorizados
- Restringe acciones basadas en políticas detalladas.
- Ni siquiera root puede saltárselas.
2. Protección contra exploits
- Limita los privilegios de procesos comprometidos.
- Contención de daños si hay una brecha.
3. Defensa en profundidad
- Capa adicional sobre DAC, firewalls, contraseñas.
- Si una capa falla, SELinux actúa.
4. Auditorías detalladas
- Registra todos los intentos de acceso no permitido.
- Útil para forense y análisis post-incidente.
5. Cumplimiento normativo
- Requerido por estándares como PCI-DSS, DISA STIG, CIS Benchmarks.
- Ayuda a cumplir con NIS2, DORA, ISO 27001.
2.2 ¿Cuándo usar SELinux?
Recomendado en:
- Servidores en producción.
- Sectores regulados (banca, salud, gobierno).
- Sistemas expuestos a internet.
- Entornos con datos sensibles.
No crítico en:
- Escritorios personales.
- Laboratorios de pruebas.
- Dispositivos embebidos con pocos recursos.
2.3 Casos reales donde SELinux previene ataques
- Apache comprometido: el atacante no puede acceder a
/etc/passwd. - Nginx con RCE: el proceso está limitado a su contexto.
- Contenedores Docker:
container_tlimita el daño entre contenedores. - Servicio comprometido: incluso con root, no puede modificar archivos del sistema.
Consulta Zero-day exploits: qué son y cómo protegerte para entender el contexto.
3. Cómo funciona: contextos, políticas, modos
SELinux tiene 3 conceptos fundamentales:
3.1 Contextos de seguridad
Cada archivo, proceso, puerto y recurso tiene un contexto con 4 componentes:
usuario:rol:tipo:nivelEjemplo:
system_u:object_r:httpd_sys_content_t:s0Componentes:
- Usuario: identifica al usuario SELinux (no el del sistema).
- Rol: define el acceso permitido.
- Tipo: el más importante. Controla qué procesos pueden interactuar con qué recursos.
- Nivel (MLS/MCS): para seguridad multinivel (raro en uso general).
Ejemplo práctico:
/var/www/html/index.html→httpd_sys_content_t- Proceso de Apache →
httpd_t - Política permite:
httpd_tpuede leerhttpd_sys_content_t.
Si un archivo NO tiene el tipo correcto, Apache no puede leerlo, aunque tenga permisos 777.
3.2 Políticas de SELinux
Políticas: reglas que definen qué puede hacer cada tipo.
Tipos de políticas:
Targeted (por defecto):
- Protege servicios específicos (Apache, SSH, Nginx…).
- Los procesos no listados corren sin restricciones.
- Recomendado para la mayoría de casos.
MLS (Multi-Level Security):
- Seguridad multinivel (tipo militar).
- Cada proceso tiene un nivel de clasificación.
- Muy restrictivo, poco usado en PYMEs.
Minimum:
- Solo protege un conjunto mínimo de servicios.
- Usado en entornos embebidos.
3.3 Modos de operación
SELinux tiene 3 modos:
| Modo | Descripción | Uso |
|---|---|---|
| Enforcing | Aplica las políticas. Bloquea accesos no permitidos. | Producción |
| Permissive | No bloquea, solo registra. | Diagnóstico, aprendizaje |
| Disabled | SELinux inactivo. | NO recomendado |
4. SELinux vs AppArmor
AppArmor es la alternativa más común a SELinux, usada por defecto en Ubuntu y SUSE.
| Aspecto | SELinux | AppArmor |
|---|---|---|
| Modelo | MAC con etiquetas | MAC con rutas |
| Complejidad | Alta | Media |
| Curva de aprendizaje | Pronunciada | Suave |
| Distros | RHEL, Fedora, Rocky | Ubuntu, SUSE |
| Granularidad | Muy fina | Menos fina |
| Configuración | Contextos + políticas | Perfiles por app |
| Ideal para | Empresas, alta seguridad | Uso general, facilidad |
Conclusión:
- SELinux: más potente, más complejo.
- AppArmor: más fácil, suficiente para la mayoría.
En Ubuntu/Debian normalmente usarás AppArmor. Si quieres SELinux, tendrás que instalarlo manualmente.
Consulta Hardening de servidores web Apache vs Nginx para más capas de seguridad.
5. Modos de operación
5.1 Ver el modo actual
getenforceResultados posibles:
Enforcing
Permissive
Disabled5.2 Cambiar el modo temporalmente
# A Permissive (para diagnóstico)
sudo setenforce 0
# A Enforcing
sudo setenforce 1⚠️ El cambio se pierde al reiniciar. Para hacerlo permanente, hay que editar el archivo de configuración.
5.3 Cambiar el modo permanentemente
Edita /etc/selinux/config:
sudo nano /etc/selinux/configModifica:
SELINUX=enforcingOpciones:
enforcingpermissivedisabled
Reinicia para aplicar:
sudo reboot5.4 Ver el estado completo
sestatusEjemplo de salida:
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 336. Contextos de seguridad
6.1 Ver contextos de archivos
ls -Z /var/www/html/Resultado:
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 style.css6.2 Ver contextos de procesos
ps -eZ | grep httpdResultado:
system_u:system_r:httpd_t:s0 1234 ? 00:00:00 httpd6.3 Ver contextos de puertos
sudo semanage port -l | grep httpResultado:
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 90006.4 Cambiar el contexto de un archivo
# Temporal (se pierde al reiniciar)
sudo chcon -t httpd_sys_content_t /var/www/html/index.html
# Permanente (recomendado)
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
sudo restorecon -Rv /var/www/html6.5 Restaurar contextos por defecto
sudo restorecon -Rv /ruta/7. Políticas de SELinux
7.1 Booleanos
Los booleanos son interruptores que activan/desactivan partes de la política sin necesidad de escribir código.
Ver booleanos:
getsebool -aVer booleanos relacionados con Apache:
getsebool -a | grep httpdEjemplo:
httpd_can_network_connect --> off
httpd_can_sendmail --> off
httpd_enable_homedirs --> offActivar un booleano temporalmente:
sudo setsebool httpd_can_network_connect onPermanentemente:
sudo setsebool -P httpd_can_network_connect on⚠️ Ejemplo típico: si tu aplicación web hace peticiones a APIs externas, necesitas:
sudo setsebool -P httpd_can_network_connect onSin ese booleano, Apache no puede hacer peticiones de red.
7.2 Políticas personalizadas
Si SELinux bloquea algo legítimo:1. Ver el bloqueo:
sudo ausearch -m avc -ts recent2. Generar una política permisiva:
sudo ausearch -m avc -ts recent | audit2allow -M mi_politica3. Instalar la política:
sudo semodule -i mi_politica.pp⚠️ Cuidado: crear políticas sin entender el impacto puede abrir agujeros de seguridad. Úsalo como último recurso.
7.3 Módulos de política
# Listar módulos activos
sudo semodule -l
# Instalar
sudo semodule -i modulo.pp
# Eliminar
sudo semodule -r modulo8. Cómo configurar SELinux
8.1 Verificar instalación
rpm -qa | grep selinuxEn RHEL/Fedora/Rocky/AlmaLinux ya viene instalado.
En Ubuntu/Debian:
SELinux no viene instalado por defecto. Usa AppArmor en su lugar.
Si quieres SELinux en Ubuntu:
sudo apt install selinux-basics selinux-policy-default auditd
sudo selinux-activate⚠️ No recomendado en Ubuntu: puede romper cosas.
8.2 Instalar herramientas de administración
# RHEL/Rocky/AlmaLinux
sudo dnf install policycoreutils policycoreutils-python-utils selinux-policy-devel
# Fedora
sudo dnf install policycoreutils policycoreutils-python-utils8.3 Configurar el modo
Edita /etc/selinux/config:
sudo nano /etc/selinux/configAjustes recomendados:
SELINUX=enforcing
SELINUXTYPE=targeted8.4 Aplicar cambios sin reiniciar
sudo setenforce 18.5 Verificar el estado
sestatus
getenforce9. Herramientas esenciales
9.1 getenforce / setenforce
getenforce # Ver modo
setenforce 0 # Permissive
setenforce 1 # Enforcing9.2 sestatus
sestatus
sestatus -v # Verbose9.3 ls -Z / ps -Z / id -Z
ls -Z # Contexto de archivos
ps -eZ # Contexto de procesos
id -Z # Contexto del usuario actual9.4 chcon
Cambia el contexto de un archivo (temporal):
sudo chcon -t httpd_sys_content_t archivo.html9.5 restorecon
Restaura contextos por defecto:
sudo restorecon -Rv /var/www/html9.6 semanage
Gestiona políticas de forma permanente:
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
sudo semanage port -a -t http_port_t -p tcp 8080
sudo semanage user -l
sudo semanage login -l9.7 getsebool / setsebool
getsebool -a
sudo setsebool -P httpd_can_network_connect on9.8 ausearch / audit2why / audit2allow
# Ver eventos recientes
sudo ausearch -m avc -ts today
# Explicar por qué se bloqueó
sudo ausearch -m avc -ts today | audit2why
# Generar política permisiva
sudo ausearch -m avc -ts today | audit2allow -M mi_politica9.9 sealert
Explica alertas de forma legible:
sudo sealert -a /var/log/audit/audit.log9.10 Troubleshooting
sudo ausearch -m avc -ts recent10. Casos de uso reales
10.1 Apache con contenido en /var/www/html
Problema: Apache no puede leer archivos nuevos.
Causa: el contexto del archivo es incorrecto.
Solución:
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
sudo restorecon -Rv /var/www/html10.2 WordPress con escritura en wp-content
Problema: WordPress no puede subir archivos.
Solución:
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/wp-content(/.*)?"
sudo restorecon -Rv /var/www/html/wp-content
sudo setsebool -P httpd_unified on10.3 Nginx en puerto no estándar
Problema: Nginx no arranca en puerto 8080.
Causa: SELinux solo permite a Nginx usar puertos específicos.
Solución:
sudo semanage port -a -t http_port_t -p tcp 8080
sudo systemctl restart nginx10.4 SSH en puerto no estándar
Problema: SSH no arranca en puerto 2222.
Solución:
sudo semanage port -a -t ssh_port_t -p tcp 2222
sudo systemctl restart sshd10.5 Docker con volúmenes
Problema: Docker no puede montar volúmenes.
Solución:
# Opción 1: Añadir :z al volumen
docker run -v /host/data:/container/data:z ...
# Opción 2: Activar booleano
sudo setsebool -P container_manage_cgroup on10.6 Base de datos con directorio personalizado
Problema: MariaDB/PostgreSQL no arranca con directorio de datos en otra ruta.
Solución:
sudo semanage fcontext -a -t mysqld_db_t "/var/lib/mysql-custom(/.*)?"
sudo restorecon -Rv /var/lib/mysql-custom10.7 Nginx proxy a backend
Problema: Nginx no puede conectarse a un backend local.
Solución:
sudo setsebool -P httpd_can_network_connect onConsulta Hardening de servidores web Apache vs Nginx.
11. Troubleshooting
11.1 Un servicio no arranca
Diagnóstico:
sudo journalctl -u servicio -n 50
sudo ausearch -m avc -ts recentBusca líneas como:
type=AVC msg=audit(...): avc: denied { read } for pid=1234 comm="nginx"
name="index.html" dev="sda1" ino=12345 scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:user_home_t:s0 tclass=fileSolución típica:
sudo restorecon -Rv /var/www/html
sudo setsebool -P httpd_can_network_connect on11.2 Un archivo no se puede leer/escribir
Diagnóstico:
ls -Z /ruta/archivoSolución: restaurar contexto.
sudo restorecon -Rv /ruta/11.3 Permiso denegado en puerto
Diagnóstico:
sudo semanage port -l | grep mi_puertoSolución:
sudo semanage port -a -t mi_tipo_port -p tcp MI_PUERTO11.4 Ver todos los bloqueos de hoy
sudo ausearch -m avc -ts today11.5 Generar política permisiva (último recurso)
sudo ausearch -m avc -ts today | audit2allow -M politica_custom
sudo semodule -i politica_custom.pp⚠️ Cuidado: solo si estás seguro de que el bloqueo es un falso positivo.
11.6 Deshabilitar temporalmente SELinux (no recomendado)
sudo setenforce 0Usar solo para diagnóstico. Vuelve a enforcing después:
sudo setenforce 111.7 Verificar el modo
getenforce
sestatus11.8 Logs de SELinux
/var/log/audit/audit.log— auditoría principal./var/log/messages— mensajes generales.journalctl -t setroubleshoot— alertas procesadas.
11.9 Documentación oficial
- Wiki de SELinux (Fedora): https://fedoraproject.org/wiki/SELinux
- Red Hat docs: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/
12. FAQ
¿Qué es SELinux y para qué sirve?
SELinux (Security-Enhanced Linux) es un módulo de seguridad del kernel Linux que implementa Control de Acceso Obligatorio (MAC).
Sirve para:
- Restringir acciones incluso de root.
- Contener daños de exploits.
- Auditar accesos no permitidos.
Uso típico: servidores en producción, sectores regulados.
¿SELinux y AppArmor son lo mismo?
No. Son dos implementaciones de MAC:
- SELinux: etiquetas, políticas complejas, RHEL/Fedora/Rocky.
- AppArmor: rutas, perfiles, Ubuntu/SUSE.
Ambos son válidos. Ubuntu usa AppArmor por defecto.
Consulta Hardening de servidores web Apache vs Nginx.
¿Qué significa «Enforcing» y «Permissive»?
- Enforcing: SELinux aplica las políticas y bloquea accesos no permitidos.
- Permissive: SELinux no bloquea, solo registra los accesos no permitidos.
- Disabled: SELinux inactivo (no recomendado).
Recomendación: usa enforcing en producción; permissive solo para diagnóstico.
¿Cómo sé si SELinux está bloqueando algo?
Herramientas:
sudo ausearch -m avc -ts today
sudo sealert -a /var/log/audit/audit.log
sudo journalctl -t setroubleshootLos bloqueos aparecen como avc: denied.
¿Cómo deshabilito SELinux?
Temporalmente:
sudo setenforce 0Permanentemente: edita /etc/selinux/config:
SELINUX=disabledReinicia el sistema.
⚠️ NO recomendado. SELinux es una capa esencial de seguridad.
¿Puedo instalar SELinux en Ubuntu?
Sí, pero no es recomendado. Ubuntu usa AppArmor por defecto.
Si insistes:
sudo apt install selinux-basics selinux-policy-default auditd
sudo selinux-activatePuede romper cosas. Mejor quédate con AppArmor.
¿SELinux afecta al rendimiento?
Impacto mínimo en sistemas modernos (~1-3%).
Consejo: no es excusa para desactivarlo. Los beneficios superan el coste.
¿SELinux puede impedir que root haga algo?
Sí. Esa es su principal ventaja. Aunque un proceso sea root, está limitado por su contexto y políticas.
Ejemplo: un proceso de Apache comprometido no puede leer /etc/shadow aunque tenga permisos root, porque SELinux lo bloquea.
¿Cómo hago que un servicio use un puerto personalizado?
sudo semanage port -a -t http_port_t -p tcp 8080
sudo systemctl restart nginxConsulta Cómo configurar y usar Fail2ban para más seguridad.
¿Cómo soluciono «avc: denied»?
Pasos:
- Identifica el bloqueo:
sudo ausearch -m avc -ts today- Analiza:
sudo ausearch -m avc -ts today | audit2why- Soluciona según el caso:
- Contexto de archivo →
restorecon. - Puerto →
semanage port. - Booleano →
setsebool. - Política personalizada →
audit2allow.
- Contexto de archivo →
¿Cuándo NO usar SELinux?
- Escritorios personales: AppArmor es más simple.
- Laboratorios de pruebas: puede interferir.
- Dispositivos embebidos: pocos recursos.
- Cuando no tienes tiempo de aprenderlo: mejor dejarlo en
permissive.
Consulta Guía Completa de Linux para alternativas.
13. Conclusión
SELinux es una de las herramientas de seguridad más potentes del mundo Linux. Aunque su curva de aprendizaje es pronunciada, bien configurado proporciona una capa de protección inigualable contra exploits y accesos no autorizados.
Puntos clave:
- SELinux implementa MAC (Control de Acceso Obligatorio).
- Incluso root está limitado por las políticas.
- 3 modos: Enforcing, Permissive, Disabled.
- Contextos de seguridad: usuario:rol:tipo:nivel.
- Políticas Targeted para servicios específicos.
- Herramientas esenciales:
semanage,restorecon,setsebool,ausearch. - Troubleshooting:
audit2why,sealert. - Alternativa: AppArmor (Ubuntu/SUSE).
- Cumple con estándares como PCI-DSS, CIS.
- No desactivar en producción.
Si quieres profundizar:






