Ich habe Nginx-Weiterleitungsanfragen an Gunicorn über einen Unix-Socket an /run/gunicorn/socket
. Standardmäßig ist dieses Verhalten von SELinux nicht zulässig:
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)
Überall, wo ich hinschaue (z. B. hier und hier ), müssen die Anweisungen, die dies ermöglichen, eine Anfrage an nginx stellen, die Anfrage von SELinux abgelehnt und dann ausgeführt werden audit2allow
, um zukünftige Anfragen zuzulassen. Ich kann nicht herausfinden , chcon
oder semanage
Befehl, der dieses Verhalten explizit erlaubt.
Ist das der einzige Weg? Es scheint lächerlich, dass Sie keine Richtlinie einrichten können, die es Nginx ermöglicht, in einen Socket zu schreiben, ohne zuerst einen Versuch abzulehnen und dann ein Tool auszuführen, das Dinge ermöglicht, die abgelehnt wurden. Woher wissen Sie genau, was aktiviert wird? Wie soll das funktionieren, wenn Sie Maschinen unter Automatisierung einrichten?
Ich benutze CentOS 7.
Antworten:
Nein, SELinux ist eine obligatorische Zugriffskontrolle, Dinge werden standardmäßig abgelehnt und Sie müssen explizit etwas zulassen. Wenn die Richtlinienautoren einen bestimmten (franken) Stapel nicht berücksichtigt haben oder die Autoren eines Dämons ihn nicht für SELinux sensibilisiert und Richtlinien dafür geschrieben haben, sind Sie auf sich allein gestellt. Sie müssen analysieren, was Ihre Dienste tun und wie sie mit SELinux interagieren, und Ihre eigenen Richtlinien erstellen, um dies zuzulassen. Es stehen Tools zur Verfügung, mit denen Sie audit2why , audit2allow usw. unterstützen können.
Nein, aber es hängt davon ab, was Sie versuchen und wie Sie es versuchen, was die Lösung ist. Beispielsweise möchten Sie möglicherweise nginx (httpd_t) an Port 8010 (unreserved_port_t) binden. Wenn Sie nginx starten, schlägt dies fehl
und Sie schauen (irgendwann) in das Überwachungsprotokoll und finden
Sie können dies über audit2alllow ausführen und die Ergebnisse naiv akzeptieren
Dadurch kann httpd_t eine Verbindung zu einem beliebigen TCP-Port herstellen. Dies ist möglicherweise nicht das, was Sie wollen.
Sie können sesearch verwenden , um die Richtlinie zu untersuchen und festzustellen, an welche Porttypen httpd_t name_bind kann
Unter anderem kann http_t an http_port_t binden. Jetzt können Sie Semanage verwenden , um etwas tiefer zu graben.
Port 8010 ist nicht aufgeführt. Da Nginx an Port 8010 gebunden werden soll, ist es nicht unangemessen, es der Liste http_port_t hinzuzufügen
Jetzt darf nginx name_bind an Port 8010 und nicht an jeden TCP-Port wie oben.
Änderungen an Richtlinien sind ziemlich einfach zu lesen, da Ihre oben genannten Nachrichten über audit2allow ausgeführt werden
die scheinen ziemlich selbsterklärend.
Die erste bezieht sich auf die Datei mit inum 76151. Sie können find verwenden, um den Namen abzurufen (find / -inum 76151), und dann
semanage fcontext -a -t ...
die Richtlinie und die Wiederherstellungskonfiguration ändern, um den Kontext zu korrigieren.Der zweite bezieht sich auf
/run/gunicorn/socket
den wiederum den falschen Kontext. Mit sesearch können wir sehen, dass http_t eine Verbindung zu unix_stream_sockets vom Typ (unter anderem) http_t herstellen kann. So können wir beispielsweise den Kontext entsprechend ändernDies legt den Kontext von / run / gunicorn und dem Baum | fest Dateien darunter zu httpd_t.
Sie müssen das System analysieren und im Test entsprechende Änderungen vornehmen. Anschließend verwenden Sie Ihre Automatisierungstools, um die Änderungen bereitzustellen. Puppet und Ansible unterstützen dies.
Natürlich können Sie alles in der Produktion tun, wenn SElinux auf freizügig eingestellt ist. Sammeln Sie alle Nachrichten, analysieren Sie sie, entscheiden Sie über Ihre Änderungen und stellen Sie sie bereit.
Es gibt viel mehr über SELinux zu wissen, aber das ist die Grenze meiner Fähigkeiten, Michael Hampton ist besser und Mathew Ife ist wieder viel besser, sie haben vielleicht mehr hinzuzufügen.
quelle
allow httpd_t httpd_sys_content_t:sock_file write;
ist für mich nicht so selbsterklärend, wie Sie gehofft haben. Was bedeutet das, dass die Richtlinie für diese Datei geändert werden muss (dh was folgt-t
imsemanage
Befehl?semanage
Befehle direkt verwende. Ich muss ein--add
Argument hinzufügen .httpd_var_run_t
wie Michael Hampton unten angegeben, dieaudit2allow
Nachricht lautet:allow httpd_t var_run_t:sock_file write;
var_run_t
nicht eingestellthttpd_var_run_t
.audit2allow
sagtallow httpd_t var_run_t:sock_file write;
Der Typ, den Sie verwenden möchten, ist nicht
httpd_sys_content_t
. Dies gilt für statische Dateien, die der Webserver für Benutzeragenten bereitstellen soll.Für einen Socket, der für die Interprozesskommunikation verwendet wird, suchen Sie den Typ
httpd_var_run_t
.Beachten Sie jedoch, dass es möglicherweise zusätzliche Probleme bei der Kommunikation gibt, da Sie Gunicorn unbeschränkt ausgeführt haben.
quelle
Ich habe die vorherigen Antworten ohne Erfolg ausprobiert. In meinem Fall verwende ich einen Nginx-Server als Frontend für eine Uwsgi-Anwendung, die Unix-Sockets verwendet, um sie zu kommunizieren. Mein Betriebssystem Es ist ein Fedora-Server 26.
Die Unix-Sockets werden im Verzeichnis erstellt
/var/local/myapp
:Um SELinux zu konfigurieren, musste ich den Kontexttyp hinzufügen:
httpd_sys_rw_content_t
quelle