SELinux por trabaja en dos modos, Enforcing, en el cual por default todo se deniega, y se permite acceso únicamente a lo que se explicitamente permitido, y Permissive, en lo cual por default todo se deniega, pero en vez de bloquear el acceso, simplemente notifica esto en los logs (/var/log/messages y /var/log/audit/audit.log) y debe ser utilizado solamente para testing.
Para verificar el estado de SELinux utilizamos el comando sestatus:
# sestatusO mediante el comando getenforce:
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: enforcing
Mode from config file: enforcing
Policy version: 26
Policy from config file: targeted
# getenforcePara cambiar de Enforcing a Permisive en tiempo real podemos utilizar setenforce:
Enforcing
# setenforce 0Si queremos saber como esta configurado en el sistema SELinux podemos revisar el archivo /etc/sysconfig/selinux que es un link simbólico hacia /etc/selinux/config:
# getenforce
Permissive
# setenforce 1
# getenforce
Enforcing
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - SELinux is fully disabled.
SELINUX=enforcing
# SELINUXTYPE= type of policy in use. Possible values are:
# targeted - Only targeted network daemons are protected.
# strict - Full SELinux protection.
SELINUXTYPE=targeted
Cualquier modificación que hagamos en este archivo, requiere que reiniciemos el sistema para poder aplicar los cambios.
Un administrador, puede hacer uso de los directorios homes para contener los DocumentRoot de los usuarios, en un path que no es el originalmente permitido por SELinux (/var/www/), por lo cual debemos cambiar los permisos del mismo para poder acceder, veamos como hacer esto.Una vez que httpd se encuentre instalado en el servidor, es importante definir los virtualhost en el archivo de configuración de Apache (Al final de /etc/httpd/conf/httpd.conf o añadirlos al directorio /etc/httpd/conf.d).
En este caso vamos a definir dos virutalhost, virtualhost-1 y virtualhost-2:
<VirtualHost ip.address.of.virtualhost-1>
ServerAdmin webmaster@virtualhost-1.com
DocumentRoot /home/user/www/virtualhost-1
ServerName virtualhost-1
ErrorLog logs/virtualhost-1-error_log
CustomLog logs/host.virtualhost-1-access_log common
</VirtuailHost>
<VirtualHost ip.address.of.virtualhost-2>Como vemos los DocumentRoot de ambos virtualhost no son los permitidos por SELinux (que intenta servir el contenido de /var/www o /srv), por lo cual al intentar acceder a los mismos vamos a obtener un error del tipo Forbidden, así que debemos permitirlos de manera explicita dentro de la policy de SELinux. Podemos verificar esto con semanage fcontext -l:
ServerAdmin webmaster@virtualhost-2.com
DocumentRoot /home/user/www/virtualhost-2
ServerName virtualhost-2
ErrorLog logs/virtualhost-2-error_log
CustomLog logs/host.virtualhost-2-access_log common
</VirtualHost>
# semanage fcontext -l | grep httpd_Por lo cual, lo que tenemos que hacer es cambiar el contexto de dichos directorios, y vamos a realizar esto de manera recursiva para que afecte a todos los archivos que se encuentran en su interior. Para esto vamos a utilizar el comando chcon.
/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
...
# chcon -R -v -u system_u -r object_r -t httpd_sys_content_t /home/user/www/virtualhost-{1,2}El parámetro -R hace esto recursivo, -v es verbose, con -u se especifica el usuario (system_u), con -r se especifica el rol, y con -t el tipo, que para que caso de httpd es httpd_sys_content_t.
Otra forma de lograr el mismo resultado es por referencia, esto es, pasandole como tal un directorio que tenga el contexto previamente configurado. Para esto utilizamos el parámetro --reference:
# chcon -R -v --reference=/var/www/html /home/user/www/virtualhost-{1,2}Ahora, nuestra configuración persistirá a través de reboots, pero no soportaría un releabel (restorecon), por lo cual debemos commitear dichos cambios a la policy. Por lo cual, para esto, vamos a utilizar semange, dicho comando no se encuentra instalado por default en RHEL 6/CentOS 6, por lo cual debemos instalar el paquete policycoreutils-python mediante yum o rpm.
# semanage fcontext -a -t httpd_sys_content_t "/home/user/www/virtualhost-1(/.*)?"
# semanage fcontext -a -t httpd_sys_content_t "/home/user/www/virtualhost-2(/.*)?"
Ahora si hacemos un restorecon sobre los DocumentRoot de nuestros virtualhost vemos que soportan el relabel:
# restorecon -R -v /home/user/www/
# ls -Z /home/user/virtualhost-{1,2}
drwx------. root root system_u:object_r:httpd_sys_content_t:s0 virtualhost-1
drwx------. root root system_u:object_r:httpd_sys_content_t:s0 virtualhost-2
Pero esto todavía tiene una vuelta de tuerca más, para permitir el acceso de SELinux a la home, tenemos que modificar el valor de un booleano.
Para listar los booleanos, se pueden utilizar dos comandos, uno es getsebool y el otro, semanage, vamos a utilizar el segundo, ya que este nos provee además una breve descripción de lo que hace cada booleano:
# semanage boolean -l | grep httpd
httpd_can_network_relay -> off Allow httpd to act as a relay
httpd_can_network_connect_db -> off Allow HTTPD scripts and modules to connect to databases.
httpd_enable_homedirs -> off Allow httpd to read home directories
...
El booleano que nos interesa es httpd_enable_homedirs, como cualquier booleano, tiene dos posibles valores, true o false, en este caso vemos que esta seteado en off; Por lo cual, vamos a cambiarle su valor a on utilizando setsebool y el parámetro -P para que persista atravéz de los reboots del sistema:
# setsebool -P httpd_enable_homedirs 1
En caso de querer saber más acerca de la configuración de SELinux para cualquier deamon, es interesante ver las páginas de manual asociadas al mismo, para ello con man -k http | grep _selinux podemos listar estas:
# man -k httpd | grep _selinux
httpd_selinux (8) - Security Enhanced Linux Policy for the httpd daemon
Buen artículo, gracias por compartirlo.
ResponderEliminarExcelente artículo, me ha servido como no tienes idea.
ResponderEliminarGran aporte
Gorgeous!
ResponderEliminar