J'ai des demandes de transfert de nginx vers gunicorn via une prise Unix à /run/gunicorn/socket
. Par défaut, ce comportement n'est pas autorisé par SELinux:
grep nginx /var/log/audit/audit.log
type=SERVICE_START msg=audit(1454358912.455:5390): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=nginx comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
type=AVC msg=audit(1454360194.623:7324): avc: denied { write } for pid=9128 comm="nginx" name="socket" dev="tmpfs" ino=76151 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=sock_file
type=SYSCALL msg=audit(1454360194.623:7324): arch=c000003e syscall=42 success=no exit=-13 a0=c a1=1f6fe58 a2=6e a3=7ffee1da5710 items=0 ppid=9127 pid=9128 auid=4294967295 uid=995 gid=993 euid=995 suid=995 fsuid=995 egid=993 sgid=993 fsgid=993 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1454361591.701:13343): avc: denied { connectto } for pid=9128 comm="nginx" path="/run/gunicorn/socket" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:initrc_t:s0 tclass=unix_stream_socket
type=SYSCALL msg=audit(1454361591.701:13343): arch=c000003e syscall=42 success=no exit=-13 a0=c a1=1f6fe58 a2=6e a3=7ffee1da5950 items=0 ppid=9127 pid=9128 auid=4294967295 uid=995 gid=993 euid=995 suid=995 fsuid=995 egid=993 sgid=993 fsgid=993 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)
Partout où je regarde (par exemple, ici et ici ), les instructions pour permettre à ce dis de faire une demande à nginx, faire refuser la demande par SELinux, puis exécuter audit2allow
pour autoriser les demandes futures. Je ne peux pas trouver de commande chcon
ou semanage
qui autorise ce comportement explicitement.
Est-ce le seul moyen? Il semble ridicule que vous ne puissiez pas mettre en place une stratégie qui permette à nginx d'écrire sur un socket sans avoir d'abord refusé une tentative, puis exécuté un outil qui permet les choses qui ont été refusées. Comment savez-vous exactement ce qui est activé? Comment est-ce censé fonctionner si vous configurez des machines sous automatisation?
J'utilise CentOS 7.
Réponses:
Eh bien non, SELinux est un contrôle d'accès obligatoire, les choses sont refusées par défaut et vous devez autoriser explicitement quelque chose. Si les auteurs de la politique n'ont pas pris en compte une pile particulière (franken) ou si les auteurs d'un démon ne l'ont pas prise en compte et écrite par SELinux, alors vous êtes seul. Vous devez analyser ce que font vos services et comment ils interagissent avec SELinux et élaborer votre propre politique pour l'autoriser. Il existe des outils pour vous aider à vérifier2 pourquoi , audit2allow, etc.
Non, mais cela dépend de ce que vous essayez de faire et de la façon dont vous essayez de le faire quant à la solution. Par exemple, vous pouvez lier nginx (httpd_t) au port 8010 (unreserved_port_t). Lorsque vous démarrez nginx, il échoue
et vous (éventuellement) regardez dans le journal d'audit et trouvez
Vous pouvez exécuter cela via audit2alllow et accepter naïvement ses conclusions
ce qui permet ensuite à httpd_t de se connecter à n'importe quel port tcp. Ce n'est peut-être pas ce que vous voulez.
Vous pouvez utiliser sesearch pour enquêter sur la stratégie et voir à quels types de port httpd_t peut nommer_bind
Entre autres types, http_t peut se lier à http_port_t. Vous pouvez maintenant utiliser le semanage pour creuser un peu plus profondément.
Le port 8010 n'est pas répertorié. Comme nous voulons que nginx se lie au port 8010, il n'est pas déraisonnable de l'ajouter à la liste http_port_t
Maintenant, nginx sera autorisé à nommer_bind vers le port 8010 et pas tous les ports TCP comme ci-dessus.
Les changements de politique sont assez faciles à lire, en exécutant vos messages ci-dessus via audit2allow nous obtenons
qui semblent assez explicites.
Le premier fait référence au fichier avec inum 76151. Vous pouvez utiliser find pour obtenir son nom (find / -inum 76151), puis utiliser
semanage fcontext -a -t ...
pour modifier la stratégie et restorecon pour corriger le contexte.La seconde concerne à
/run/gunicorn/socket
nouveau le mauvais contexte. En utilisant sesearch, nous pouvons voir que http_t peut se connecter à unix_stream_sockets de type (entre autres) http_t. On peut donc changer le contexte en conséquence par exempleCela définit le contexte de / run / gunicorn et l'arbre | fichiers en dessous à httpd_t.
Vous devez analyser le système et apporter les modifications appropriées au test. Vous utilisez ensuite vos outils d'automatisation pour déployer les modifications, marionnette et ansible prennent en charge cela.
Bien sûr, vous pouvez tout faire en production avec SElinux réglé sur permissif. Collectez tous les messages, analysez-les, décidez de vos modifications et déployez-les.
Il y a beaucoup plus à savoir sur SELinux mais c'est la limite de mes compétences, Michael Hampton est meilleur et Mathew Ife est encore mieux, ils ont peut-être plus à ajouter.
la source
allow httpd_t httpd_sys_content_t:sock_file write;
n'est pas aussi explicite pour moi que vous l'espériez. Qu'est - ce que ce à dire la politique sur que les besoins de fichiers à modifier à (c. -à- ce qui se passe après-t
lasemanage
commande?semanage
directement vos commandes. Je dois ajouter un--add
argument.httpd_var_run_t
comme Michael Hampton l'a noté ci-dessous, leaudit2allow
message est:allow httpd_t var_run_t:sock_file write;
var_run_t
pashttpd_var_run_t
.audit2allow
ditallow httpd_t var_run_t:sock_file write;
Le type que vous souhaitez utiliser ne l'est pas
httpd_sys_content_t
. Il s'agit des fichiers statiques que le serveur Web est censé servir aux agents utilisateurs.Pour un socket utilisé pour la communication interprocessus, le type que vous recherchez est
httpd_var_run_t
.Cependant, veuillez noter que, comme vous avez exécuté gunicorn sans restriction, il peut y avoir des problèmes supplémentaires de communication avec lui.
la source
J'ai essayé les réponses précédentes sans succès, dans mon cas j'utilise un serveur nginx comme frontend pour une application uwsgi utilisant des sockets unix pour les communiquer, mon OS C'est un serveur Fedora 26.
Les sockets unix sont créés dans le répertoire
/var/local/myapp
:Pour configurer SELinux, j'ai dû ajouter le type de contexte:
httpd_sys_rw_content_t
la source