BLOG | NGINX

Utilisation de NGINX et NGINX Plus avec SELinux

NGINX-Partie-de-F5-horiz-black-type-RGB
Vignette d'Owen Garrett
Owen Garrett
Publié le 17 août 2018

Rédacteur en chef – L’article de blog intitulé « NGINX : « Modifications de SELinux lors de la mise à niveau vers RHEL 6.6 / CentOS 6.6 » redirige ici. Cet article fournit des informations mises à jour et généralisées.

Les paramètres par défaut de Security-Enhanced Linux (SELinux) sur les distributions modernes Red Hat Enterprise Linux (RHEL) et associées peuvent être très stricts, privilégiant la sécurité plutôt que la commodité. Bien que les paramètres par défaut ne limitent pas le fonctionnement de NGINX Open Source et NGINX Plus dans leurs configurations par défaut, d'autres fonctionnalités que vous pourriez configurer peuvent être bloquées à moins que vous ne les autorisiez explicitement dans SELinux. Cet article décrit les problèmes possibles et les méthodes recommandées pour les résoudre.

[Éditeur – Cet article s’applique à la fois à NGINX Open Source et à NGINX Plus. Pour faciliter la lecture, le terme « NGINX » est utilisé tout au long du document.

CentOS est une distribution apparentée dérivée à l'origine de RHEL et prise en charge par NGINX et NGINX Plus. De plus, NGINX Plus prend en charge les distributions Amazon Linux et Oracle Linux associées. Leurs paramètres SELinux par défaut peuvent différer de ceux de CentOS et RHEL ; consultez la documentation du fournisseur.]

Présentation de SELinux

 

SELinux est activé par défaut sur les serveurs RHEL et CentOS modernes. Chaque objet du système d'exploitation (processus, descripteur de fichier, fichier, etc.) est étiqueté avec un contexte SELinux qui définit les autorisations et les opérations que l'objet peut effectuer. Dans RHEL 6.6/CentOS 6.6 et versions ultérieures, NGINX est étiqueté avec le contexte httpd_t :

# ps auZ | grep nginx unconfined_u:system_r: httpd_t :s0 3234 ? Ss 0:00 nginx : processus maître /usr/sbin/nginx \ -c /etc/nginx/nginx.conf unconfined_u :system_r : httpd_t :s0 3236 ? Ss 0:00 nginx : processus de travail

Le contexte httpd_t permet à NGINX d'écouter sur les ports de serveur Web courants, d'accéder aux fichiers de configuration dans /etc/nginx et d'accéder au contenu dans l'emplacement docroot standard ( /usr/share/nginx ). Il ne permet pas de nombreuses autres opérations, telles que la proxy vers des emplacements en amont ou la communication avec d'autres processus via des sockets.

Désactivation temporaire de SELinux pour NGINX

Pour désactiver temporairement les restrictions SELinux pour le contexte httpd_t , afin que NGINX puisse effectuer toutes les mêmes opérations que dans les systèmes d’exploitation non SELinux, attribuez le contexte httpd_t au domaine permissif . Voir la section suivante pour plus de détails.

# semanage permissif -a httpd_t

Modification des modes SELinux

SELinux peut être exécuté en modes contraignant , permissif ou désactivé (également appelés domaines ). Avant d'effectuer une modification de configuration NGINX susceptible de violer les autorisations par défaut (strictes), vous pouvez modifier SELinux du mode contraignant au mode permissif , dans votre environnement de test (si disponible) ou dans votre environnement de production. En mode permissif , SELinux autorise toutes les opérations, mais enregistre les opérations qui auraient violé la politique de sécurité en mode d'application .

Pour ajouter httpd_t à la liste des domaines permissifs , exécutez cette commande :

# semanage permissif -a httpd_t

Pour supprimer httpd_t de la liste des domaines permissifs , exécutez :

# semanage permissif -d httpd_t

Pour définir le mode globalement sur permissif , exécutez :

# définirforce 0

Pour définir le mode globalement sur enforcing , exécutez :

# définirforce 1

Résolution des exceptions de sécurité SELinux

En mode permissif , les exceptions de sécurité sont enregistrées dans le journal d'audit Linux par défaut, /var/log/audit/audit.log . Si vous rencontrez un problème qui se produit uniquement lorsque NGINX s'exécute en mode d'application , examinez les exceptions enregistrées en mode permissif et mettez à jour la politique de sécurité pour les autoriser.

Numéro 1 : La connexion proxy est interdite

Par défaut, la configuration SELinux ne permet pas à NGINX de se connecter à des serveurs HTTP, FastCGI ou autres distants, comme indiqué par un message de journal d'audit comme le suivant :

type=AVC msg=audit(1415714880.156:29): avc: refusé { nom_connect } pour 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
type=SYSCALL msg=audit(1415714880.156:29): arch=c000003e syscall=42 success=no \
exit=-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=(aucun) ses=1 comm="nginx" exe="/usr/sbin/nginx" \
subj=unconfined_u:system_r:httpd_t:s0 key=(null)

La commande audit2why interprète le code du message ( 1415714880.156:29 ) :

# grep 1415714880.156:29 /var/log/audit/audit.log | audit2why type=AVC msg=audit(1415714880.156:29): avc: denied { name_connect } for 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 Provoqué par :
        L’un des booléens suivants a été défini de manière incorrecte.
        Description:
        Autoriser httpd à agir comme un relais Autoriser l'accès en exécutant : # setsebool -P httpd_can_network_relay 1 Description :
        Autoriser les scripts et modules HTTPD à se connecter au réseau via TCP.
 
        Autoriser l'accès en exécutant : # setsebool -P httpd_can_network_connect 1

La sortie de audit2why indique que vous pouvez autoriser NGINX à établir des connexions proxy en activant l'une ou les deux options booléennes httpd_can_network_relay et httpd_can_network_connect . Vous pouvez les activer temporairement ou définitivement, dans ce dernier cas en ajoutant l'indicateur -P comme indiqué dans la sortie.

Comprendre les options booléennes

La commande sesearch fournit plus d'informations sur les options booléennes et est disponible si vous installez le package setools ( yum install setools ). Nous montrons ici la sortie pour les options httpd_can_network_relay et httpd_can_network_connect .

L'option booléenne httpd_can_network_relay

Voici le résultat de la commande sesearch concernant l'option httpd_can_network_relay :

# sesearch -A -s httpd_t -b httpd_can_network_relay 10 règles d'analyse sémantique trouvées : allow httpd_t gopher_port_t : tcp_socket name_connect ; allow httpd_t http_cache_client_packet_t : packet { send recv } ; allow httpd_t ftp_port_t : tcp_socket name_connect ; allow httpd_t ftp_client_packet_t : packet { send recv } ; allow httpd_t http_client_packet_t : packet { send recv } ; allow httpd_t squid_port_t : tcp_socket name_connect ; allow httpd_t http_cache_port_t : tcp_socket name_connect ; allow httpd_t http_port_t : tcp_socket name_connect ; autoriser httpd_t gopher_client_packet_t : paquet { envoyer réception } ; autoriser httpd_t memcache_port_t : tcp_socket name_connect ;

Cette sortie indique que httpd_can_network_relay permet aux processus étiquetés avec le contexte httpd_t (tel que NGINX) de se connecter à des ports de différents types, y compris le type http_port_t :

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

Pour ajouter plus de ports (ici,8082 ) à l'ensemble des ports autorisés pour http_port_t , exécutez :

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

Si la sortie de cette commande indique qu'un port est déjà défini , comme dans l'exemple suivant, cela signifie que le port est inclus dans un autre ensemble. Ne le réaffectez pas à http_port_t , car d'autres services pourraient être affectés négativement.

# semanage port -a -t http_port_t -p tcp 8080 /usr/sbin/semanage: Port tcp/8080 déjà défini # semanage port -l | grep 8080 http_cache_port_t tcp 3128, 8080, 8118, 8123, 10001-10010

L'option booléenne httpd_can_network_connect

Voici le résultat de la commande sesearch concernant l'option httpd_can_network_connect :

# sesearch -A -s httpd_t -b httpd_can_network_connect 1 règles av sémantiques trouvées : allow httpd_t port_type : tcp_socket name_connect ;

Cette sortie indique que httpd_can_network_connect permet aux processus étiquetés avec le contexte httpd_t (tel que NGINX) de se connecter à tous les types de sockets TCP qui ont l'attribut port_type . Pour les lister, exécutez :

# seinfo -aport_type -x

Numéro 2 : L'accès au fichier est interdit

Par défaut, la configuration SELinux n’autorise pas NGINX à accéder aux fichiers en dehors des emplacements autorisés connus, comme indiqué par un message de journal d’audit tel que le suivant :

type=AVC msg=audit(1415715270.766:31): avc: refusé { getattr } pour 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=fichier

La commande audit2why interprète le code du message ( 1415715270.766:31 ) :

# grep 1415715270.766:31 /var/log/audit/audit.log | audit2why type=AVC msg=audit(1415715270.766:31): avc: denied { getattr } for 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 Provoqué par :
        Règle d'autorisation d'application de type manquante (TE).
 
        Vous pouvez utiliser audit2allow pour générer un module chargeable afin d'autoriser cet accès.

Lorsque l'accès aux fichiers est interdit, vous avez deux options.

Option 1 : Modifier l'étiquette du fichier

Modifiez l'étiquette du fichier afin que NGINX (en tant que processus étiqueté avec le contexte httpd_t ) puisse accéder au fichier :

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

Par défaut, cette modification est supprimée lorsque le système de fichiers est réétiqueté. Pour rendre le changement permanent, exécutez :

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

Pour modifier les étiquettes de fichiers pour des groupes de fichiers, exécutez :

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

Option 2 : Étendre les autorisations du domaine httpd_t

Étendez la politique pour httpd_t pour autoriser l'accès à des emplacements de fichiers supplémentaires :

# grep nginx /var/log/audit/audit.log | audit2allow -m nginx > nginx.te # cat nginx.te module nginx 1.0; require { type httpd_t; type default_t; type http_cache_port_t; class tcp_socket name_connect; class fichier { lecture getattr ouvert }; } #============= httpd_t ============== allow httpd_t default_t:file { lecture getattr ouvert }; #!!!! Cet avc peut être autorisé en utilisant l'un de ces booléens : # httpd_can_network_relay, httpd_can_network_connect allow httpd_t http_cache_port_t:tcp_socket name_connect;

Pour générer une politique compilée, incluez l'option -M :

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

Pour charger la politique, exécutez semodule -i , puis vérifiez le succès avec semodule -l :

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

Ce changement persiste après les redémarrages.

Numéro 3 : NGINX ne peut pas se lier à des ports supplémentaires

Par défaut, la configuration SELinux n'autorise pas NGINX à écouter ( bind() ) les ports TCP ou UDP autres que ceux par défaut qui sont sur liste blanche dans le type http_port_t :

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

Si vous essayez de configurer NGINX pour écouter sur un port non autorisé (avec la directive listen dans le contexte http , stream ou mail dans la configuration NGINX), vous obtenez une erreur lorsque vous vérifiez ( nginx -t ) ou rechargez la configuration NGINX, comme indiqué par cette entrée de journal NGINX :

AAAA / MM / JJ hh : mm : ss [emerg] 46123#0 : échec de bind() à 0.0.0.0:8001 (13 : (Autorisation refusée)

Vous pouvez utiliser semanage pour ajouter le port souhaité (ici, 8001) au type http_port_t :

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

Rechargez NGINX avec la nouvelle configuration.

# nginx -s recharger

Numéro 4 : Trop de fichiers sont ouverts Erreur

Lorsque la limite du nombre de fichiers ouverts ( RLIMIT_NOFILE ) est dépassée, le message suivant apparaît dans le journal des erreurs :

Trop de fichiers sont ouverts

Lorsque le processus de travail NGINX génère l'erreur

Dans la plupart des cas, le processus de travail NGINX signale cette erreur, mais vous ne pouvez pas utiliser la directive NGINX worker_rlimit_nofile pour augmenter la limite car SELinux n'autorise pas l'appel système setrlimit() , comme indiqué dans les messages suivants dans les journaux d'erreur et d'audit.

  • Dans /var/log/nginx/error.log pour CentOS/RHEL 7.4+ :

    AAAA / MM / JJ hh : mm : ss [alerte] 12066#0 : setrlimit(RLIMIT_NOFILE, 2342) a échoué (13 : (Autorisation refusée)
    
  • Dans /var/log/nginx/error.log pour CentOS/RHEL 8.0+ :

    AAAA / MM / JJ hh : mm : ss [alerte] 3327#0 : setrlimit(RLIMIT_NOFILE, 65535) a échoué (1 : (Opération non autorisée)
    
  • Dans /var/log/audit/audit.log pour CentOS/RHEL 7.4+ et /var/log/messages pour CentOS/RHEL 8.0+ :

    type=AVC msg=audit(1437731200.211:366): avc: refusé { setrlimit } pour pid=12066 \ comm="nginx" scontext=system_u:system_r:httpd_t:s0 \
    tcontext=system_u:system_r:httpd_t:s0 tclass=process
    

Pour augmenter la limite, exécutez plutôt cette commande en tant qu'utilisateur root :

$ setsebool -P httpd_setrlimit 1

Lorsque le processus maître NGINX génère l'erreur

Si le processus maître NGINX signale l'erreur, vous devez mettre à jour le fichier d'unité systemd pour NGINX. Cela définit la limite du descripteur de fichier pour les processus maître et de travail.

  1. Créez un répertoire pour la configuration de nginx.service :

    $ mkdir /etc/systemd/system/nginx.service.d
    
  2. Ajoutez les lignes suivantes à /etc/systemd/system/nginx.service.d/nofile_limit.conf :

    [Service]LimitNOFILE=65535
    
  3. Rechargez la configuration du démon systemd et redémarrez NGINX :

    $ systemctl daemon-reload $ systemctl restart nginx.service
    

Ressources supplémentaires

SELinux est un outil complexe et puissant permettant de gérer les autorisations du système d'exploitation. Des informations complémentaires sont disponibles dans les documents suivants.


« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."