BLOG | NGINX

Uso de NGINX y NGINX Plus con SELinux

NGINX - Parte de F5 - horizontal, negro, tipo RGB
Miniatura de Owen Garrett
Owen Garrett
Publicado el 17 de agosto de 2018

Editor – La publicación del blog titulada “NGINX: “Cambios de SELinux al actualizar a RHEL 6.6 / CentOS 6.6” redirige aquí. Este artículo proporciona información actualizada y generalizada.

La configuración predeterminada para Security-Enhanced Linux (SELinux) en Red Hat Enterprise Linux (RHEL) moderno y distribuciones relacionadas puede ser muy estricta y estar más a favor de la seguridad que de la conveniencia. Aunque la configuración predeterminada no limita el funcionamiento de NGINX Open Source y NGINX Plus en sus configuraciones predeterminadas, otras funciones que pueda configurar pueden bloquearse a menos que las permita explícitamente en SELinux. Este artículo describe los posibles problemas y las formas recomendadas de resolverlos.

[Editor: Este artículo se aplica tanto a NGINX Open Source como a NGINX Plus. Para facilitar la lectura, se utiliza el término “NGINX” en todo el documento.

CentOS es una distribución relacionada originalmente derivada de RHEL y es compatible con NGINX y NGINX Plus. Además, NGINX Plus es compatible con las distribuciones Amazon Linux y Oracle Linux relacionadas. Su configuración SELinux predeterminada puede diferir de CentOS y RHEL; consulte la documentación del proveedor.]

Descripción general de SELinux

 

SELinux está habilitado de forma predeterminada en los servidores RHEL y CentOS modernos. Cada objeto del sistema operativo (proceso, descriptor de archivo, archivo, etc.) está etiquetado con un contexto SELinux que define los permisos y las operaciones que el objeto puede realizar. En RHEL 6.6/CentOS 6.6 y versiones posteriores, NGINX está etiquetado con el contexto httpd_t :

# ps auZ | grep nginx unconfined_u:system_r: httpd_t :s0 3234 ? Ss 0:00 nginx: proceso maestro /usr/sbin/nginx \ -c /etc/nginx/nginx.conf unconfined_u:system_r: httpd_t :s0 3236 ? Ss 0:00 nginx: proceso de trabajo

El contexto httpd_t permite a NGINX escuchar en puertos de servidor web comunes, acceder a archivos de configuración en /etc/nginx y acceder al contenido en la ubicación docroot estándar ( /usr/share/nginx ). No permite muchas otras operaciones, como la conexión a ubicaciones ascendentes o la comunicación con otros procesos a través de sockets.

Desactivación temporal de SELinux para NGINX

Para deshabilitar temporalmente las restricciones de SELinux para el contexto httpd_t , de modo que NGINX pueda realizar las mismas operaciones que en sistemas operativos que no sean SELinux, asigne el contexto httpd_t al dominio permisivo . Consulte la siguiente sección para obtener más detalles.

# semanage permisivo -a httpd_t

Cambiar los modos de SELinux

SELinux se puede ejecutar en modos de aplicación , permisivo o deshabilitado (también denominados dominios ). Antes de realizar un cambio de configuración de NGINX que pueda infringir los permisos predeterminados (estrictos), puede cambiar SELinux del modo obligatorio al modo permisivo , en su entorno de prueba (si está disponible) o en su entorno de producción. En el modo permisivo , SELinux permite todas las operaciones, pero registra las operaciones que habrían violado la política de seguridad en el modo de aplicación .

Para agregar httpd_t a la lista de dominios permisivos , ejecute este comando:

# semanage permisivo -a httpd_t

Para eliminar httpd_t de la lista de dominios permisivos , ejecute:

# semanage permisivo -d httpd_t

Para establecer el modo globalmente en permisivo , ejecute:

# setenforce 0

Para establecer el modo globalmente en enforcing , ejecute:

# setenforce 1

Resolución de excepciones de seguridad de SELinux

En el modo permisivo , las excepciones de seguridad se registran en el registro de auditoría predeterminado de Linux, /var/log/audit/audit.log . Si encuentra un problema que ocurre solo cuando NGINX se ejecuta en modo de aplicación , revise las excepciones registradas en modo permisivo y actualice la política de seguridad para permitirlas.

Número 1: La conexión proxy está prohibida

De forma predeterminada, la configuración de SELinux no permite que NGINX se conecte a servidores HTTP, FastCGI u otros servidores remotos, como lo indica un mensaje de registro de auditoría como el siguiente:

Tipo=AVC msg=audit(1415714880.156:29): avc: conexión denegada {nombre_conexión} para pid=1349 \
comm="nginx" dest=8080 scontext=unconfined_u:system_r:httpd_t:s0 \
tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket
Tipo=SYSCALL msg=audit(1415714880.156:29): arch=c000003e syscall=42 éxito=no \
salida=-115 a0=b \a1=16125f8 a2=10 a3=7fffc2bab440 items=0 ppid=1347 pid=1349 \
auid=1000 uid=497 gid=496 euid=497 suid=497 fsuid=497 egid=496 sgid=496 fsgid=496 \
tty=(ninguno) ses=1 comm="nginx" exe="/usr/sbin/nginx" \
subj=unconfined_u:system_r:httpd_t:s0 clave=(nulo)

El comando audit2why interpreta el código del mensaje ( 1415714880.156:29 ):

# grep 1415714880.156:29 /var/log/audit/audit.log | audit2why tipo=AVC msg=audit(1415714880.156:29): avc: se denegó { name_connect } para pid=1349 \ comm="nginx" dest=8080 scontext=unconfined_u:system_r:httpd_t:s0 \ tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket Fue causado por:
        Uno de los siguientes valores booleanos se configuró incorrectamente.
        Descripción:
        Permitir que httpd actúe como relé Permitir el acceso ejecutando: # setsebool -P httpd_can_network_relay 1 Descripción:
        Permitir que los scripts y módulos HTTPD se conecten a la red mediante TCP.
 
        Permitir el acceso ejecutando: # setsebool -P httpd_can_network_connect 1

La salida de audit2why indica que puede permitir que NGINX realice conexiones proxy habilitando una o ambas de las opciones booleanas httpd_can_network_relay y httpd_can_network_connect . Puede habilitarlos de forma temporal o permanente, esto último agregando el indicador -P como se muestra en la salida.

Comprensión de las opciones booleanas

El comando sesearch proporciona más información sobre las opciones booleanas y está disponible si instala el paquete setools ( yum install setools ). Aquí mostramos la salida de las opciones httpd_can_network_relay y httpd_can_network_connect .

La opción booleana httpd_can_network_relay

Aquí está el resultado del comando sesearch sobre la opción httpd_can_network_relay :

# sesearch -A -s httpd_t -b httpd_can_network_relay Se encontraron 10 reglas anti-virus semánticas: permitir httpd_t gopher_port_t : tcp_socket nombre_conexión ; permitir httpd_t http_cache_client_packet_t : paquete { enviar recepción } ; permitir httpd_t ftp_port_t : tcp_socket nombre_conexión ; permitir httpd_t ftp_client_packet_t : paquete { enviar recepción } ; permitir httpd_t http_client_packet_t : paquete { enviar recepción } ; permitir httpd_t squid_port_t : tcp_socket nombre_conexión ; permitir httpd_t http_cache_port_t : tcp_socket nombre_conexión ; permitir httpd_t http_port_t : tcp_socket nombre_conexión ; permitir httpd_t gopher_client_packet_t : paquete { enviar recepción } ; permitir httpd_t memcache_port_t : tcp_socket nombre_conexión ;

Esta salida indica que httpd_can_network_relay permite que los procesos etiquetados con el contexto httpd_t (como NGINX) se conecten a puertos de varios tipos, incluido el tipo http_port_t :

# semanage puerto -l | grep http_port_t http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000

Para agregar más puertos (aquí,8082 ) al conjunto de puertos permitidos para http_port_t , ejecute:

# semanage puerto -a -t http_port_t -p tcp 8082

Si la salida de este comando indica que un puerto ya está definido , como en el siguiente ejemplo, significa que el puerto está incluido en otro conjunto. No lo reasigne a http_port_t , porque otros servicios podrían verse afectados negativamente.

# semanage puerto -a -t http_port_t -p tcp 8080 /usr/sbin/semanage: Puerto tcp/8080 ya definido # semanage port -l | grep 8080 http_cache_port_t tcp 3128, 8080, 8118, 8123, 10001-10010

La opción booleana httpd_can_network_connect

Aquí está el resultado del comando sesearch sobre la opción httpd_can_network_connect :

# sesearch -A -s httpd_t -b httpd_can_network_connect Se encontraron 1 reglas anti-v semánticas: permitir httpd_t port_type : tcp_socket name_connect ;

Esta salida indica que httpd_can_network_connect permite que los procesos etiquetados con el contexto httpd_t (como NGINX) se conecten a todos los tipos de sockets TCP que tengan el atributo port_type . Para enumerarlos, ejecute:

# seinfo -aport_type -x

Número 2: El acceso a los archivos está prohibido

De forma predeterminada, la configuración de SELinux no permite que NGINX acceda a archivos fuera de ubicaciones autorizadas conocidas, como lo indica un mensaje de registro de auditoría como el siguiente:

tipo=AVC msg=audit(1415715270.766:31): avc: denegado { getattr } para pid=1380 \
comm="nginx" path="/www/t.txt" dev=vda1 ino=1084 \
scontext=unconfined_u:system_r:httpd_t:s0 \
tcontext=unconfined_u:object_r:default_t:s0 tclass=file

El comando audit2why interpreta el código del mensaje ( 1415715270.766:31 ):

# grep 1415715270.766:31 /var/log/audit/audit.log | audit2why tipo=AVC msg=audit(1415715270.766:31): avc: denegado { getattr } para pid=1380 \ comm="nginx" path="/www/t.txt" dev=vda1 ino=1084 \ scontext=unconfined_u:system_r:httpd_t:s0 \ tcontext=unconfined_u:object_r:default_t:s0 tclass=file Fue causado por:
        Falta la regla de permiso de aplicación de tipo (TE).
 
        Puede utilizar audit2allow para generar un módulo cargable para permitir este acceso.

Cuando el acceso a los archivos está prohibido, tienes dos opciones.

Opción 1: Modificar la etiqueta del archivo

Modifique la etiqueta del archivo para que NGINX (como un proceso etiquetado con el contexto httpd_t ) pueda acceder al archivo:

# chcon -v --type=httpd_sys_content_t /www/t.txt

De forma predeterminada, esta modificación se elimina cuando se vuelve a etiquetar el sistema de archivos. Para que el cambio sea permanente, ejecute:

# semanage fcontext -a -t httpd_sys_content_t /www/t.txt # restorecon -v /www/t.txt

Para modificar las etiquetas de archivos de grupos de archivos, ejecute:

# semanage fcontext -a -t httpd_sys_content_t '/www(/.*)?' # restorecon -Rv /www

Opción 2: Ampliar los permisos del dominio httpd_t

Amplíe la política de httpd_t para permitir el acceso a ubicaciones de archivos adicionales:

# grep nginx /var/log/audit/audit.log | audit2allow -m nginx > nginx.te # cat nginx.te módulo nginx 1.0; requerir { tipo httpd_t; tipo predeterminado_t; tipo http_cache_port_t; clase tcp_socket nombre_conexión; clase archivo { leer getattr abrir }; } #============= httpd_t ============== permitir httpd_t predeterminado_t:archivo { leer getattr abrir }; #!!!! Este avc se puede permitir usando uno de estos booleanos: # httpd_can_network_relay, httpd_can_network_connect allow httpd_t http_cache_port_t:tcp_socket name_connect;

Para generar una política compilada, incluya la opción -M :

# grep nginx /var/log/audit/audit.log | audit2allow -M nginx

Para cargar la política, ejecute semodule -i y luego verifique el éxito con semodule -l :

# semodule -i nginx.pp # semodule -l | grep nginx nginx 1.0

Este cambio persiste después de los reinicios.

Número 3: NGINX no puede vincularse a puertos adicionales

De forma predeterminada, la configuración de SELinux no permite que NGINX escuche ( bind() ) puertos TCP o UDP distintos de los predeterminados que están en la lista de permitidos en el tipo http_port_t :

# semanage puerto -l | grep http_port_t http_port_t tcp 80, 443, 488, 8008, 8009, 8443

Si intenta configurar NGINX para escuchar en un puerto no permitido (con la directiva listen en el contexto http , stream o mail en la configuración de NGINX), obtendrá un error cuando verifique ( nginx -t ) o vuelva a cargar la configuración de NGINX, como lo indica esta entrada de registro de NGINX:

AAAA / MM / DD hh : mm : ss [emerg] 46123#0: error al enlazar() a 0.0.0.0:8001 (13: Permiso denegado)

Puede utilizar semanage para agregar el puerto deseado (aquí, 8001) al tipo http_port_t :

# semanage puerto -a -t http_port_t -p tcp 8001

Recargue NGINX con la nueva configuración.

# nginx -s recargar

Número 4: Hay demasiados archivos abiertos Error

Cuando se excede el límite en la cantidad de archivos abiertos ( RLIMIT_NOFILE ), aparece el siguiente mensaje en el registro de errores:

Hay demasiados archivos abiertos

Cuando el proceso de trabajo NGINX genera el error

En la mayoría de los casos, el proceso de trabajo de NGINX informa este error, pero no puede usar la directiva NGINXworker_rlimit_nofile para aumentar el límite porque SELinux no permite la llamada del sistema setrlimit() , como se informa en los siguientes mensajes en los registros de error y auditoría.

  • En /var/log/nginx/error.log para CentOS/RHEL 7.4+:

    AAAA / MM / DD hh : mm : ss [alerta] 12066#0: setrlimit(RLIMIT_NOFILE, 2342) falló (13: Permiso denegado)
    
  • En /var/log/nginx/error.log para CentOS/RHEL 8.0+:

    AAAA / MM / DD hh : mm : ss [alerta] 3327#0: setrlimit(RLIMIT_NOFILE, 65535) falló (1: Operación no permitida)
    
  • En /var/log/audit/audit.log para CentOS/RHEL 7.4+ y /var/log/messages para CentOS/RHEL 8.0+:

    tipo=AVC msg=audit(1437731200.211:366): avc: denegado { setrlimit } para pid=12066 \ comm="nginx" scontext=system_u:system_r:httpd_t:s0 \
    tcontext=system_u:system_r:httpd_t:s0 tclass=process
    

Para aumentar el límite, ejecute este comando como usuario root :

$ setsebool -P httpd_setrlimit 1

Cuando el proceso maestro NGINX genera el error

Si el proceso maestro de NGINX informa el error, debe actualizar el archivo de unidad systemd para NGINX. Esto establece el límite de descriptores de archivo para los procesos maestro y de trabajo.

  1. Cree un directorio para la configuración de nginx.service :

    $ mkdir /etc/systemd/system/nginx.service.d
    
  2. Agregue las siguientes líneas a /etc/systemd/system/nginx.service.d/nofile_limit.conf :

    [Servicio]LimitNOFILE=65535
    
  3. Recargue la configuración del demonio systemd y reinicie NGINX:

    $ systemctl daemon-reload $ systemctl restart nginx.service
    

Recursos adicionales

SELinux es una herramienta compleja y potente para administrar los permisos del sistema operativo. Información adicional está disponible en los siguientes documentos.


"Esta publicación de blog puede hacer referencia a productos que ya no están disponibles o que ya no reciben soporte. Para obtener la información más actualizada sobre los productos y soluciones F5 NGINX disponibles, explore nuestra familia de productos NGINX . NGINX ahora es parte de F5. Todos los enlaces anteriores de NGINX.com redirigirán a contenido similar de NGINX en F5.com.