Skip to content

SELinux (file context)

Objetivos

  • Comprender el contexto de seguridad httpd_sys_content_t y su uso en la administración de archivos para servidores web.
  • Crear un archivo en /root/test.html y moverlo a /var/www/html/, verificando el impacto en la seguridad SELinux.
  • Asignar el contexto correcto al archivo, asegurando que el servidor web pueda acceder y servir el contenido sin restricciones.
  • Validar que el acceso al archivo es permitido, probando su disponibilidad desde el servidor web.

Entorno Inicial

  • Usuario: student
  • Máquina: servera
  • Herramientas utilizadas: Shell Bash y utilidades básicas de Linux.

Pasos del Laboratorio

Prerequisitos

  1. Inicio de sesión

    • Inicia sesión en la máquina servera desde bastion como el usuario student utilizando la llave privada proporcionada:
    ssh student-#-servera
    

Paso 1: Validación de Configuración

  1. Validar estado actual:

    sestatus
    
    Salida similar a:
    SELinux status:                 enabled
    SELinuxfs mount:                /sys/fs/selinux
    SELinux root directory:         /etc/selinux
    Loaded policy name:             targeted
    Current mode:                   enforcing # <== Modo de operación
    Mode from config file:          enforcing # <== Modo configurado por defecto
    Policy MLS status:              enabled
    Policy deny_unknown status:     allowed
    Memory protection checking:     actual (secure)
    Max kernel policy version:      33
    
    Si la salida es diferente , configure el modo a Enforcing.
    setenforce 1
    

  2. Validar configuración permanente:

    Editar /etc/selinux/config, asegurese que SELINUX=enforcing esta configurado en el modo enforcing, puede validarlo posterior a su edición con el comando:

    grep -w ^SELINUX /etc/selinux/config
    
    Salida:
    SELINUX=enforcing
    

Apache 2 (httpd)

Para demostrar el funcionamiento de SELinux, se utilizará una instalación básica de Apache

Validar funcionamiento de Apache

  • Instalar apache
    dnf install httpd -y
    
  • Iniciar apache
    systemctl enable --now httpd
    
  • Crear contenido de ejemplo
echo "Hello from Apache" >  /var/www/html/index.html
  • Validar acceso a Servicio
    curl http://localhost
    curl -I http://localhost
    

Documentación y herramientas SELinux

  • Instalación

dnf install policycoreutils policycoreutils-python-utils selinux-policy-doc -y
* Actualización de manuales
mandb
* Obtener información de SELinux
man -k _selinux
man -k _selinux |grep http
man httpd_selinux

Buscar en contenido del manual FILE CONTEXTS

Trate de identificar el contexto asociado con el directorio /var/www/html.

Puede ser un poco complicado la primera vez encontrar la información requerida.

Salir del manual

Explorar contextos de archivos para Apache

Utilizaremos semanage, para listar los contextos y filtraremos por el directorio mencionado.

semanage fcontext -l |grep "var/www" |head
La salida debe ser similar a:
/var/www(/.*)?                                     all files          system_u:object_r:httpd_sys_content_t:s0
/var/www(/.*)?/logs(/.*)?                          all files          system_u:object_r:httpd_log_t:s0
/var/www/[^/]*/cgi-bin(/.*)?                       all files          system_u:object_r:httpd_sys_script_exec_t:s0
/var/www/apcupsd/multimon\.cgi                     regular file       system_u:object_r:apcupsd_cgi_script_exec_t:s0
/var/www/apcupsd/upsfstats\.cgi                    regular file       system_u:object_r:apcupsd_cgi_script_exec_t:s0
/var/www/apcupsd/upsimage\.cgi                     regular file       system_u:object_r:apcupsd_cgi_script_exec_t:s0
/var/www/apcupsd/upsstats\.cgi                     regular file       system_u:object_r:apcupsd_cgi_script_exec_t:s0
/var/www/calamaris(/.*)?                           all files          system_u:object_r:calamaris_www_t:s0
/var/www/cgi-bin(/.*)?                             all files          system_u:object_r:httpd_sys_script_exec_t:s0
/var/www/cgi-bin/apcgui(/.*)?                      all files          system_u:object_r:apcupsd_cgi_script_exec_t:s0

Notar en la primera linea que todos los elementos definidos por la expresión regular /var/www(/.*)?, tienen el contexto definido como httpd_sys_content_t.

El directorio /var/www/html, entra dentro de esta expresión regular.

Validando el contexto del directorio en el sistema de archivos:

ls -ldZ /var/www/html/
Salida similar a:
drwxr-xr-x. 2 root root system_u:object_r:httpd_sys_content_t:s0 XX Jan XX 16:07 /var/www/html/
Note nuevamente que el contexto es el deseado por este directorio.

Procederemos a crer un contenido en un directorio en cual no tiene el contexto adecuado:

echo "Hola prueba SELINUX" > /root/test.html
chmod a+r /root/test.html
Moveremos el archivo el directorio de apache.

mv /root/test.html /var/www/html/
Realizaremos la prueba de consultar el archivo desde el webserver.

curl http://localhost/test.html
Salida similar a:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
</body></html>
Note que el error indica que no es posible acceder al recurso, esto regularmente esta asociado a permisos del sistema de archivos. Consulte los permisos.

ls -l /var/www/html/test.html
Salida similar a:
-rw-r--r--. 1 root root XX Jan XX 16:31 /var/www/html/test.html
Consultar el contexto de SELinux para ese archivo:
ls -lZ /var/www/html/test.html
Salida similar a:
-rw-r--r--. 1 root root unconfined_u:object_r:admin_home_t:s0 20 Apr 15 16:31 /var/www/html/test.html

Notar que el contexto de SElinux para ese archivo es admin_home_t. No el requerido por SElinux.

Identificar la posible solución en base al log

Consultar el log de audit.log para ver eventos relacionados a denegaciones.

grep denied /var/log/audit/audit.log
Salida similar a:
type=AVC msg=audit(1744756354.053:1128): avc:  denied  { getattr } for  pid=68580 comm="httpd" path="/var/www/html/test.html" dev="dm-0" ino=67272515 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0
Para ayudarnos a identificar la razón de la falla, podemos instalar el siguiente paquete:

dnf install setroubleshoot-server -y
systemctl restart setroubleshootd
Realizaremos la prueba de consultar el archivo desde el webserver.

curl http://localhost/test.html
Consultar los eventos desde hace 10 minutos para el servicio recién instalado.
journalctl -t setroubleshoot --since '10 min ago' --no-pager

Salida similar:

Jan XX 16:41:17 lab setroubleshoot[73055]: SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/test.html. For complete SELinux messages run: sealert -l c4746811-30de-4a93-ad0d-UNICO-PARA-SU-SISTEMA
Jan XX 16:41:17 lab setroubleshoot[73055]: SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/test.html.

*****  Plugin restorecon (99.5 confidence) suggests   ************************

If you want to fix the label.
/var/www/html/test.html default label should be httpd_sys_content_t.
Then you can run restorecon. The access attempt may have been stopped due to insufficient permissions to access a parent directory in which case try to change the following command accordingly.
Do
# /sbin/restorecon -v /var/www/html/test.html

*****  Plugin catchall (1.49 confidence) suggests   **************************

If you believe that httpd should be allowed getattr access on the test.html file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'httpd' --raw | audit2allow -M my-httpd
# semodule -X 300 -i my-httpd.pp
Identique el ID de la alerta: c4746811-30de-4a93-ad0d-UNICO-PARA-SU-SISTEMA Ejecuta el comando para ver el detalle:
sealert -l c4746811-30de-4a93-ad0d-UNICO-PARA-SU-SISTEMA
Salida similar:
SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/test.html.

*****  Plugin restorecon (99.5 confidence) suggests   ************************

If you want to fix the label.
/var/www/html/test.html default label should be httpd_sys_content_t.
Then you can run restorecon. The access attempt may have been stopped due to insufficient permissions to access a parent directory in which case try to change the following command accordingly.
Do
# /sbin/restorecon -v /var/www/html/test.html

*****  Plugin catchall (1.49 confidence) suggests   **************************

If you believe that httpd should be allowed getattr access on the test.html file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'httpd' --raw | audit2allow -M my-httpd
# semodule -X 300 -i my-httpd.pp


Additional Information:
Source Context                system_u:system_r:httpd_t:s0
Target Context                unconfined_u:object_r:admin_home_t:s0
Target Objects                /var/www/html/test.html [ file ]
Source                        httpd
Source Path                   /usr/sbin/httpd
Port                          <Unknown>
Host                          lab
Source RPM Packages           httpd-core-2.4.62-1.el9_5.2.x86_64
Target RPM Packages
SELinux Policy RPM            selinux-policy-targeted-38.1.45-3.el9_5.noarch
Local Policy RPM              selinux-policy-targeted-38.1.45-3.el9_5.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     lab
Platform                      Linux psi-2025-3 5.14.0-427.28.1.el9_4.x86_64 #1
                              SMP PREEMPT_DYNAMIC Wed Jul 31 15:28:35 UTC 2024
                              x86_64 x86_64
Alert Count                   2
First Seen                    2025-04-15 16:41:15 CST
Last Seen                     2025-04-15 16:41:15 CST
Local ID                      c4746811-30de-4a93-ad0d-65c8833a2171

Raw Audit Messages
type=AVC msg=audit(1744756875.929:1178): avc:  denied  { getattr } for  pid=68580 comm="httpd" path="/var/www/html/test.html" dev="dm-0" ino=67272515 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0


type=SYSCALL msg=audit(1744756875.929:1178): arch=x86_64 syscall=newfstatat success=no exit=EACCES a0=ffffff9c a1=7f23c8002bb0 a2=7f23daffc8b0 a3=100 items=0 ppid=68577 pid=68580 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm=httpd exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s0 key=(null)

Hash: httpd,httpd_t,admin_home_t,file,getattr

El comando nos sugiere una solución:

*****  Plugin restorecon (99.5 confidence) suggests   ************************

If you want to fix the label.
/var/www/html/test.html default label should be httpd_sys_content_t.
Then you can run restorecon. The access attempt may have been stopped due to insufficient permissions to access a parent directory in which case try to change the following command accordingly.
Do
# /sbin/restorecon -v /var/www/html/test.html

Procedemos a ejecutar la solución propuesta:

/sbin/restorecon -v /var/www/html/test.html

Salida similar:

Relabeled /var/www/html/test.html from unconfined_u:object_r:admin_home_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0

Realizaremos la prueba de consultar el archivo desde el webserver.

curl -v http://localhost/test.html
Salida similar:
*   Trying ::1:80...
* Connected to localhost (::1) port 80 (#0)
> GET /test.html HTTP/1.1
> Host: localhost
> User-Agent: curl/7.76.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Tue, 15 Apr 2025 22:52:09 GMT
< Server: Apache/2.4.62 (Rocky Linux)
< Last-Modified: Tue, 15 Apr 2025 22:31:02 GMT
< ETag: "14-632d8b93d41cd"
< Accept-Ranges: bytes
< Content-Length: 20
< Content-Type: text/html; charset=UTF-8
<
Hola prueba SELINUX
* Connection #0 to host localhost left intact

Con este hemos valida el funcionamiento de SELinux en un sistema para los contextos de archivos para la política de apache.

Resultados Esperados

  • El archivo test.html es correctamente movido a /var/www/html/.
  • Confirmación de que SELinux aplica el contexto httpd_sys_content_t al archivo, permitiendo su uso en el servidor web.
  • Verificación de acceso desde el servidor web, asegurando que el archivo se puede servir sin problemas.
  • Diagnóstico y solución de posibles restricciones impuestas por SELinux en archivos con contexto incorrecto.