Herausgeber – Der Blogbeitrag mit dem Titel „NGINX: „SELinux-Änderungen beim Upgrade auf RHEL 6.6 /CentOS 6.6“ leitet hierher weiter. Dieser Artikel bietet aktuelle und allgemeine Informationen.
Die Standardeinstellungen für Security-Enhanced Linux (SELinux) auf modernem Red Hat Enterprise Linux (RHEL) und verwandten Distributionen können sehr streng sein und eher zu Sicherheit als zu Benutzerfreundlichkeit tendieren. Obwohl die Standardeinstellungen die Funktion von NGINX Open Source und NGINX Plus in ihren Standardkonfigurationen nicht einschränken, können andere von Ihnen konfigurierte Funktionen blockiert werden, sofern Sie sie in SELinux nicht ausdrücklich zulassen. In diesem Artikel werden die möglichen Probleme beschrieben und Lösungsvorschläge gemacht.
[Herausgeber – Dieser Artikel gilt sowohl für NGINX Open Source als auch für NGINX Plus. Der Lesbarkeit halber wird durchgehend der Begriff „NGINX“ verwendet.
CentOS ist eine verwandte Distribution, die ursprünglich von RHEL abgeleitet wurde und von NGINX und NGINX Plus unterstützt wird. Darüber hinaus unterstützt NGINX Plus die zugehörigen Amazon Linux- und Oracle Linux-Distributionen. Ihre standardmäßigen SELinux-Einstellungen können sich von denen von CentOS und RHEL unterscheiden; konsultieren Sie die Dokumentation des Anbieters.]
Übersicht über SELinux
SELinux ist auf modernen RHEL- und CentOS-Servern standardmäßig aktiviert. Jedes Betriebssystemobjekt (Prozess, Dateideskriptor, Datei usw.) ist mit einem SELinux-Kontext gekennzeichnet, der die Berechtigungen und Vorgänge definiert, die das Objekt ausführen kann. In RHEL 6.6/CentOS 6.6 und höher ist NGINX mit dem httpd_t
-Kontext gekennzeichnet:
# ps auZ | grep nginx unconfined_u:system_r: httpd_t :s0 3234 ? Ss 0:00 nginx: Masterprozess /usr/sbin/nginx \ -c /etc/nginx/nginx.conf unconfined_u:system_r: httpd_t :s0 3236 ? Ss 0:00 nginx: Arbeitsprozess
Der httpd_t-
Kontext ermöglicht es NGINX, auf gängigen Webserver-Ports zu lauschen, auf Konfigurationsdateien in /etc/nginx zuzugreifen und auf Inhalte im Standard-Docroot-Speicherort ( /usr/share/nginx ) zuzugreifen. Viele andere Vorgänge, wie etwa das Proxying zu Upstream-Standorten oder die Kommunikation mit anderen Prozessen über Sockets, sind nicht zulässig.
Um SELinux-Einschränkungen für den httpd_t
-Kontext vorübergehend zu deaktivieren, sodass NGINX dieselben Vorgänge wie in Nicht-SELinux-Betriebssystemen ausführen kann, weisen Sie den httpd_t-
Kontext der permissiven Domäne zu. Weitere Einzelheiten finden Sie im nächsten Abschnitt.
# semanage permissive -a httpd_t
SELinux kann im Modus „Enforcing“ , „Permissive“ oder „Disabled“ (auch als „Domänen “ bezeichnet) ausgeführt werden. Bevor Sie eine Änderung an der NGINX-Konfiguration vornehmen, die möglicherweise gegen die (strengen) Standardberechtigungen verstößt, können Sie SELinux in Ihrer Testumgebung (sofern verfügbar) oder Produktionsumgebung vom erzwingenden in den permissiven Modus ändern. Im permissiven Modus lässt SELinux alle Vorgänge zu, protokolliert jedoch Vorgänge, die im Enforcing -Modus gegen die Sicherheitsrichtlinie verstoßen hätten.
Um httpd_t
zur Liste der zulässigen Domänen hinzuzufügen, führen Sie diesen Befehl aus:
# semanage permissive -a httpd_t
Um httpd_t
aus der Liste der zulässigen Domänen zu löschen, führen Sie Folgendes aus:
# semanage permissive -d httpd_t
Um den Modus global auf permissive zu setzen, führen Sie Folgendes aus:
# setenforce 0
Um den Modus global auf „enforcing“ zu setzen, führen Sie Folgendes aus:
# setenforce 1
Beheben von SELinux-Sicherheitsausnahmen
Im permissiven Modus werden Sicherheitsausnahmen im Standard-Linux-Audit-Protokoll /var/log/audit/audit.log protokolliert. Wenn Sie auf ein Problem stoßen, das nur auftritt, wenn NGINX im Durchsetzungsmodus ausgeführt wird, überprüfen Sie die Ausnahmen, die im permissiven Modus protokolliert werden, und aktualisieren Sie die Sicherheitsrichtlinie, um sie zuzulassen.
Standardmäßig lässt die SELinux-Konfiguration keine Verbindung von NGINX zu Remote-HTTP-, FastCGI- oder anderen Servern zu. Dies wird durch eine Audit-Protokollmeldung wie die folgende angezeigt:
Typ=AVC msg=audit(1415714880.156:29): avc: { name_connect } für pid=1349 verweigert \
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
Typ=SYSCALL msg=audit(1415714880.156:29): arch=c000003e syscall=42 Erfolg=Nein \
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=(keine) ses=1 comm="nginx" exe="/usr/sbin/nginx" \
subj=unconfined_u:system_r:httpd_t:s0 key=(null)
Der Befehl audit2why
interpretiert den Nachrichtencode ( 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 Wurde verursacht durch:
Einer der folgenden Booleschen Werte wurde falsch gesetzt.
Beschreibung:
Erlauben Sie httpd, als Relay zu fungieren. Erlauben Sie den Zugriff durch Ausführen von: # setsebool -P httpd_can_network_relay 1. Beschreibung:
Erlauben Sie HTTPD-Skripten und -Modulen, über TCP eine Verbindung zum Netzwerk herzustellen.
Erlauben Sie den Zugriff durch Ausführen von: # setsebool -P httpd_can_network_connect 1
Die Ausgabe von audit2why
zeigt an, dass Sie NGINX das Herstellen von Proxy-Verbindungen erlauben können, indem Sie eine oder beide der booleschen Optionen „httpd_can_network_relay“
und „httpd_can_network_connect“
aktivieren. Sie können sie entweder vorübergehend oder dauerhaft aktivieren, letzteres durch Hinzufügen des Flags -P
, wie in der Ausgabe gezeigt.
Der Befehl „sesearch“
bietet weitere Informationen zu den Booleschen Optionen und ist verfügbar, wenn Sie das Paket „setools“ installieren ( yum
install
setools
). Hier zeigen wir die Ausgabe für die Optionen httpd_can_network_relay
und httpd_can_network_connect
.
„httpd_can_network_relay“
Hier ist die Ausgabe des Befehls „sesearch“
zur Option „ httpd_can_network_relay“
:
# sesearch -A -s httpd_t -b httpd_can_network_relay 10 semantische AV-Regeln gefunden: allow httpd_t gopher_port_t : tcp_socket name_connect ; allow httpd_t http_cache_client_packet_t : Paket { sende Empfang } ; allow httpd_t ftp_port_t : tcp_socket name_connect ; allow httpd_t ftp_client_packet_t : Paket { sende Empfang } ; allow httpd_t http_client_packet_t : Paket { sende Empfang } ; allow httpd_t squid_port_t : tcp_socket name_connect ; allow httpd_t http_cache_port_t : tcp_socket name_connect ; erlauben Sie httpd_t http_port_t: TCP_Socket Name_Connect; erlauben Sie httpd_t gopher_client_packet_t: Paket { send recv }; erlauben Sie httpd_t memcache_port_t: TCP_Socket Name_Connect;
Diese Ausgabe zeigt an, dass httpd_can_network_relay
Prozessen, die mit dem Kontext httpd_t
gekennzeichnet sind (wie etwa NGINX), erlaubt, eine Verbindung zu Ports verschiedener Typen herzustellen, einschließlich des Typs http_port_t
:
grep http_port_t http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
Um weitere Ports hinzuzufügen (hier,8082
) zu den für http_port_t
zulässigen Ports hinzu, führen Sie Folgendes aus:
# semanage port -a -t http_port_t -p tcp 8082
Wenn die Ausgabe dieses Befehls besagt, dass ein Port bereits
definiert
ist, wie im folgenden Beispiel, bedeutet dies, dass der Port in einem anderen Satz enthalten ist. Weisen Sie es nicht http_port_t
neu zu, da dies zu negativen Auswirkungen auf andere Dienste führen könnte.
# semanage port -a -t http_port_t -p tcp 8080 /usr/sbin/semanage: Port tcp/8080 bereits definiert # semanage port -l | grep 8080 http_cache_port_t tcp 3128, 8080, 8118, 8123, 10001-10010
„httpd_can_network_connect“
Hier ist die Ausgabe des Befehls „sesearch“
zur Option „ httpd_can_network_connect
“:
# sesearch -A -s httpd_t -b httpd_can_network_connect 1 semantische AV-Regel gefunden: allow httpd_t port_type : tcp_socket name_connect ;
Diese Ausgabe zeigt an, dass httpd_can_network_connect
Prozessen, die mit dem Kontext httpd_t
gekennzeichnet sind (wie etwa NGINX), erlaubt, eine Verbindung zu allen TCP-Socket-Typen herzustellen, die über das Attribut port_type
verfügen. Um sie aufzulisten, führen Sie Folgendes aus:
# seiinfo -aport_type -x
Standardmäßig gestattet die SELinux-Konfiguration NGINX nicht, auf Dateien außerhalb bekannter autorisierter Speicherorte zuzugreifen. Dies wird durch eine Prüfprotokollmeldung wie die folgende angezeigt:
Typ=AVC msg=audit(1415715270.766:31): avc: verweigert { getattr } für 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
Der Befehl audit2why
interpretiert den Nachrichtencode ( 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 Wurde verursacht durch:
Fehlende Zulassungsregel für die Typdurchsetzung (TE).
Sie können audit2allow verwenden, um ein ladbares Modul zu generieren, das diesen Zugriff ermöglicht.
Wenn der Dateizugriff verboten ist, haben Sie zwei Möglichkeiten.
Ändern Sie die Dateibezeichnung, sodass NGINX (als Prozess mit der Bezeichnung „httpd_t
“-Kontext) auf die Datei zugreifen kann:
# chcon -v --type=httpd_sys_content_t /www/t.txt
Standardmäßig wird diese Änderung gelöscht, wenn das Dateisystem neu benannt wird. Um die Änderung dauerhaft zu machen, führen Sie Folgendes aus:
# semanage fcontext -a -t httpd_sys_content_t /www/t.txt # restorecon -v /www/t.txt
Um Dateibezeichnungen für Dateigruppen zu ändern, führen Sie Folgendes aus:
# semanage fcontext -a -t httpd_sys_content_t '/www(/.*)? '
httpd_t-
DomänenberechtigungenErweitern Sie die Richtlinie für httpd_t,
um den Zugriff auf zusätzliche Dateispeicherorte zu ermöglichen:
# grep nginx /var/log/audit/audit.log | audit2allow -m nginx > nginx.te # cat nginx.te module nginx 1.0; erforderlich { Typ httpd_t; Typ default_t; Typ http_cache_port_t; Klasse tcp_socket name_connect; Klasse Datei { lesen getattr öffnen }; } #============== httpd_t =============== erlauben httpd_t default_t:Datei { lesen getattr öffnen }; #!!!! Dieser AVC kann mit einem dieser Booleschen Werte zugelassen werden: # httpd_can_network_relay, httpd_can_network_connect allow httpd_t http_cache_port_t:tcp_socket name_connect;
Um eine kompilierte Richtlinie zu generieren, schließen Sie die Option -M
ein:
# grep nginx /var/log/audit/audit.log | audit2allow -M nginx
Um die Richtlinie zu laden, führen Sie „semodule
-i“
aus und überprüfen Sie dann den Erfolg mit „semodule
-l“
:
# semodule -i nginx.pp # semodule -l | grep nginx nginx 1.0
Diese Änderung bleibt auch nach Neustarts bestehen.
Standardmäßig erlaubt die SELinux-Konfiguration es NGINX nicht, auf anderen TCP- oder UDP-Ports zu lauschen ( bind()
) als den Standardports, die im Typ http_port_t
auf der Whitelist stehen:
grep http_port_t http_port_t tcp 80, 443, 488, 8008, 8009, 8443
Wenn Sie versuchen, NGINX so zu konfigurieren, dass es auf einem nicht auf der Whitelist stehenden Port lauscht (mit der Direktive „listen
“ im Kontext „http“
, „stream“
oder „mail“
in der NGINX‑Konfiguration), erhalten Sie beim Überprüfen ( nginx
-t
) oder Neuladen der NGINX‑Konfiguration eine Fehlermeldung, wie dieser NGINX‑Protokolleintrag angibt:
JJJJ / MM / TT hh : mm : ss [emerg] 46123#0: bind() an 0.0.0.0:8001 fehlgeschlagen (13: Zugriff verweigert)
Mit semanage
können Sie dem Typ http_port_t
den gewünschten Port (hier 8001) hinzufügen:
# semanage port -a -t http_port_t -p tcp 8001
Laden Sie NGINX mit der neuen Konfiguration neu.
# nginx -s neu laden
Es sind zu viele Dateien geöffnet.
FehlerWenn das Limit für die Anzahl geöffneter Dateien ( RLIMIT_NOFILE
) überschritten wird, wird die folgende Meldung im Fehlerprotokoll angezeigt:
Es sind zu viele Dateien geöffnet
In den meisten Fällen meldet der NGINX-Arbeitsprozess diesen Fehler, Sie können die NGINX-Direktive worker_rlimit_nofile
jedoch nicht verwenden, um das Limit zu erhöhen, da SELinux den Systemaufruf setrlimit()
nicht zulässt, wie in den folgenden Nachrichten in Fehler- und Prüfprotokollen berichtet wird.
In /var/log/nginx/error.log für CentOS/RHEL 7.4+:
JJJJ / MM / TT hh : mm : ss [alert] 12066#0: setrlimit(RLIMIT_NOFILE, 2342) fehlgeschlagen (13: Zugriff verweigert)
In /var/log/nginx/error.log für CentOS/RHEL 8.0+:
JJJJ / MM / TT hh : mm : ss [alert] 3327#0: setrlimit(RLIMIT_NOFILE, 65535) fehlgeschlagen (1: Betrieb nicht zulässig)
In /var/log/audit/audit.log für CentOS/RHEL 7.4+ und /var/log/messages für CentOS/RHEL 8.0+:
Typ=AVC msg=audit(1437731200.211:366): avc: verweigert { setrlimit } für pid=12066 \ comm="nginx" scontext=system_u:system_r:httpd_t:s0 \
tcontext=system_u:system_r:httpd_t:s0 tclass=process
Um das Limit zu erhöhen, führen Sie stattdessen diesen Befehl als Root
-Benutzer aus:
$ setsebool -P httpd_setrlimit 1
Wenn der NGINX-Masterprozess den Fehler meldet, müssen Sie die systemd-
Unit
-Datei für NGINX aktualisieren. Dadurch wird das Dateideskriptorlimit für Master- und Workerprozesse festgelegt.
Erstellen Sie ein Verzeichnis für die nginx.service
-Konfiguration:
$ mkdir /etc/systemd/system/nginx.service.d
Fügen Sie die folgenden Zeilen zu /etc/systemd/system/nginx.service.d/nofile_limit.conf hinzu:
[Dienst]LimitNOFILE=65535
Laden Sie die Konfiguration des systemd-Daemons neu und starten Sie NGINX neu:
$ systemctl daemon-reload $ systemctl nginx.service neu starten
Weitere Ressourcen
SELinux ist eine komplexe und leistungsstarke Einrichtung zum Verwalten von Betriebssystemberechtigungen. Weitere Informationen finden Sie in den folgenden Dokumenten.
„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."