Anmerkung der Redaktion – Der Blogbeitrag mit dem Titel „NGINX: SELinux-Änderungen beim Upgrade auf RHEL 6.6 / CentOS 6.6“ verweist auf diese Seite. Dieser Artikel enthält aktualisierte und allgemeiner gefasste Informationen.
Die Standardeinstellungen für Security-Enhanced Linux (SELinux) unter modernen Versionen von Red Hat Enterprise Linux (RHEL) und verwandten Distributionen können sehr streng sein und räumen der Sicherheit Vorrang vor der Benutzerfreundlichkeit ein. Obwohl die Standardeinstellungen die Funktionsweise von NGINX Open Source und NGINX Plus in ihren Standardkonfigurationen nicht einschränken, können andere von Ihnen konfigurierte Funktionen blockiert werden, sofern Sie diese nicht ausdrücklich in SELinux zulassen. Dieser Artikel beschreibt mögliche Probleme und empfohlene Lösungswege.
[Redaktion – Dieser Artikel gilt sowohl für NGINX Open Source als auch für NGINX Plus. Zur besseren Lesbarkeit 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 verwandten Distributionen Amazon Linux und Oracle Linux. Deren standardmäßige SELinux-Einstellungen können von denen unter CentOS und RHEL abweichen. Weitere Informationen finden Sie in der Dokumentation des jeweiligen Anbieters.]
Überblick ü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 festlegt, die das Objekt ausführen kann. Ab RHEL 6.6/CentOS 6.6 ist NGINX mit dem Kontext „httpd_t“ gekennzeichnet:
# ps auZ | grep nginxunconfined_u:system_r:httpd_t:s0 3234 ? Ss 0:00 nginx: master process /usr/sbin/nginx \
-c /etc/nginx/nginx.conf
unconfined_u:system_r:httpd_t:s0 3236 ? Ss 0:00 nginx: worker processDer Kontext httpd_t erlaubt NGINX, an gängigen Webserver-Ports zu lauschen, auf Konfigurationsdateien in /etc/nginx und auf Inhalte im standardmäßigen Dokumentenstammverzeichnis (/usr/share/nginx) zuzugreifen. Viele andere Vorgänge sind jedoch nicht zulässig, beispielsweise die Weiterleitung an Upstream-Ziele oder die Kommunikation mit anderen Prozessen über Sockets.
SELinux für NGINX vorübergehend deaktivieren
Um die SELinux-Einschränkungen für den Kontext httpd_t vorübergehend zu deaktivieren, damit NGINX dieselben Vorgänge wie auf Betriebssystemen ohne SELinux ausführen kann, weisen Sie den Kontext httpd_t der Domäne permissive zu. Weitere Informationen finden Sie im nächsten Abschnitt.
# semanage permissive -a httpd_tSELinux-Modi ändern
SELinux kann in den Modi Enforcing, Permissive oder Disabled ausgeführt werden (auch als Domänen bezeichnet). Bevor Sie eine Änderung an der NGINX-Konfiguration vornehmen, die möglicherweise gegen die standardmäßigen (strikten) Berechtigungen verstößt, können Sie SELinux in Ihrer Testumgebung (sofern vorhanden) oder Produktionsumgebung vom Modus Enforcing in den Modus Permissive versetzen. Im Modus Permissive lässt SELinux alle Vorgänge zu, protokolliert jedoch Vorgänge, die im Modus Enforcing gegen die Sicherheitsrichtlinie verstoßen hätten.
Um httpd_t zur Liste der permissiven Domänen hinzuzufügen, führen Sie diesen Befehl aus:
# semanage permissive -a httpd_tUm httpd_t aus der Liste der permissiven Domänen zu entfernen, führen Sie folgenden Befehl aus:
# semanage permissive -d httpd_tUm den Modus global auf „permissive“ festzulegen, führen Sie Folgendes aus:
# setenforce 0Um den Modus global auf „enforcing“ festzulegen, führen Sie Folgendes aus:
# setenforce 1Beheben von SELinux-Sicherheitsausnahmen
Im permissiven Modus werden Sicherheitsausnahmen im standardmäßigen Linux-Audit-Protokoll /var/log/audit/audit.log protokolliert. Wenn ein Problem nur auftritt, wenn NGINX im erzwingenden Modus ausgeführt wird, überprüfen Sie die im permissiven Modus protokollierten Ausnahmen und aktualisieren Sie die Sicherheitsrichtlinie, um sie zuzulassen.
Problem 1: Proxy-Verbindung ist nicht zulässig
Standardmäßig erlaubt die SELinux-Konfiguration NGINX keine Verbindungen zu entfernten HTTP-, FastCGI- oder anderen Servern. Darauf weist eine Audit-Protokollmeldung wie die folgende hin:
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
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=(none) ses=1 comm="nginx" exe="/usr/sbin/nginx" \
subj=unconfined_u:system_r:httpd_t:s0 key=(null)Der Befehl „audit2why“ interpretiert den Meldungscode (1415714880.156:29):
# grep 1415714880.156:29 /var/log/audit/audit.log | audit2whytype=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
Was caused by:
One of the following booleans was set incorrectly.
Description:
Allow httpd to act as a relay
Allow access by executing:
# setsebool -P httpd_can_network_relay 1
Description:
Allow HTTPD scripts and modules to connect to the network using TCP.
Allow access by executing:
# setsebool -P httpd_can_network_connect 1Die Ausgabe von audit2why zeigt, dass Sie NGINX 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 diese entweder vorübergehend oder dauerhaft aktivieren. Für Letzteres fügen Sie wie in der Ausgabe gezeigt das Flag ‑P hinzu.
Boolesche Optionen verstehen
Der Befehl „sesearch“ liefert 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“.
Die boolesche Option „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_relayFound 10 semantic av rules:
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 ;
allow httpd_t gopher_client_packet_t : packet { send recv } ;
allow httpd_t memcache_port_t : tcp_socket name_connect ;Diese Ausgabe zeigt, dass httpd_can_network_relay Prozessen mit dem Kontext httpd_t (wie etwa NGINX) erlaubt, Verbindungen zu Ports verschiedener Typen herzustellen, darunter auch zum Typ http_port_t:
# semanage port -l | grep http_port_thttp_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000Um weitere Ports (hier 8082) zur Liste der für http_port_t zulässigen Ports hinzuzufügen, führen Sie folgenden Befehl aus:
# semanage port -a -t http_port_t -p tcp 8082Wenn die Ausgabe dieses Befehls besagt, dass ein Port bereits definiert ist, wie im folgenden Beispiel, bedeutet dies, dass der Port in einer anderen Gruppe enthalten ist. Weisen Sie ihn nicht erneut http_port_t zu, da dies andere Dienste beeinträchtigen könnte.
# semanage port -a -t http_port_t -p tcp 8080
/usr/sbin/semanage: Port tcp/8080 already defined
# semanage port -l | grep 8080
http_cache_port_t tcp 3128, 8080, 8118, 8123, 10001-10010Die boolesche Option „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_connectFound 1 semantic av rules:
allow httpd_t port_type : tcp_socket name_connect ;Diese Ausgabe zeigt, dass „httpd_can_network_connect“ Prozessen mit dem Kontext „httpd_t“ (wie etwa NGINX) erlaubt, eine Verbindung zu allen TCP-Socket-Typen herzustellen, die das Attribut „port_type“ aufweisen. Führen Sie folgenden Befehl aus, um sie aufzulisten:
# seinfo -aport_type -xProblem 2: Der Dateizugriff ist nicht zulässig
Standardmäßig erlaubt die SELinux-Konfiguration NGINX nicht, auf Dateien außerhalb bekannter autorisierter Speicherorte zuzugreifen, worauf eine Audit-Protokollmeldung wie die folgende hinweist:
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=fileDer Befehl „audit2why“ interpretiert den Meldungscode (1415715270.766:31):
# grep 1415715270.766:31 /var/log/audit/audit.log | audit2whytype=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
Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.Wenn der Dateizugriff verweigert wird, haben Sie zwei Möglichkeiten.
Option 1: Dateikennzeichnung ändern
Ändern Sie den Dateikontext so, dass NGINX (als Prozess mit dem Kontext httpd_t gekennzeichnet) auf die Datei zugreifen kann:
# chcon -v --type=httpd_sys_content_t /www/t.txtStandardmäßig wird diese Änderung gelöscht, wenn das Dateisystem neu gekennzeichnet wird. Um die Änderung dauerhaft zu übernehmen, führen Sie Folgendes aus:
# semanage fcontext -a -t httpd_sys_content_t /www/t.txt
# restorecon -v /www/t.txtUm Datei-Labels für Gruppen von Dateien zu ändern, führen Sie Folgendes aus:
# semanage fcontext -a -t httpd_sys_content_t '/www(/.*)?'# restorecon -Rv /wwwOption 2: Erweitern der Berechtigungen der Domain httpd_t Domain Permissions
Erweitern 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;
require {
type httpd_t;
type default_t;
type http_cache_port_t;
class tcp_socket name_connect;
class file { read getattr open };
}
#============= httpd_t ==============
allow httpd_t default_t:file { read getattr open };
#!!!! This avc can be allowed using one of these booleans:
# 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, verwenden Sie die Option „-M“:
# grep nginx /var/log/audit/audit.log | audit2allow -M nginxUm die Richtlinie zu laden, führen Sie semodule -i aus und überprüfen Sie anschließend mit semodule -l, ob der Vorgang erfolgreich war:
# semodule -i nginx.pp
# semodule -l | grep nginx
nginx 1.0Diese Änderung bleibt auch nach einem Neustart bestehen.
Problem 3: NGINX kann keine Bindung an zusätzliche Ports herstellen
Standardmäßig erlaubt die SELinux-Konfiguration NGINX nicht, andere als die standardmäßig zugelassenen TCP- oder UDP-Ports zu verwenden (bind()). Diese Standardports sind im Typ http_port_t aufgeführt:
# semanage port -l | grep http_port_thttp_port_t tcp 80, 443, 488, 8008, 8009, 8443Wenn Sie versuchen, NGINX so zu konfigurieren, dass es einen Port überwacht, der nicht auf der Zulassungsliste steht (mit der listen-Direktive im http-, stream- oder mail-Kontext der NGINX-Konfiguration), erhalten Sie beim Überprüfen (nginx -t) oder erneuten Laden der NGINX-Konfiguration einen Fehler, wie dieser NGINX-Protokolleintrag zeigt:
YYYY/MM/DD hh:mm:ss [emerg] 46123#0: bind() to 0.0.0.0:8001 failed (13: Permission denied)Mit semanage können Sie den gewünschten Port (hier 8001) dem Typ http_port_t hinzufügen:
# semanage port -a -t http_port_t -p tcp 8001Laden Sie NGINX mit der neuen Konfiguration neu.
# nginx -s reloadProblem 4: „Zu viele Dateien sind geöffnet“-Fehler
Wenn die Höchstzahl der geöffneten Dateien (RLIMIT_NOFILE) überschritten wird, erscheint die folgende Meldung im Fehlerprotokoll:
Too many files are openWenn der NGINX-Worker-Prozess den Fehler erzeugt
In den meisten Fällen meldet der NGINX-Worker-Prozess diesen Fehler. Sie können jedoch die NGINX-Direktive „worker_rlimit_nofile“ nicht verwenden, um den Grenzwert zu erhöhen, da SELinux den Systemaufruf „setrlimit()“ nicht zulässt, wie die folgenden Meldungen in den Fehler- und Audit-Protokollen zeigen.
- In /var/log/nginx/error.log für CentOS/RHEL 7.4+:
YYYY/MM/DD hh:mm:ss [alert] 12066#0: setrlimit(RLIMIT_NOFILE, 2342) failed (13: Permission denied)- In /var/log/nginx/error.log für CentOS/RHEL 8.0+:
YYYY/MM/DD hh:mm:ss [alert] 3327#0: setrlimit(RLIMIT_NOFILE, 65535) failed (1: Operation not permitted)- In /var/log/audit/audit.log für CentOS/RHEL 7.4+ und /var/log/messages für CentOS/RHEL 8.0+:
type=AVC msg=audit(1437731200.211:366): avc: denied { setrlimit } for pid=12066 \ comm="nginx" scontext=system_u:system_r:httpd_t:s0 \
tcontext=system_u:system_r:httpd_t:s0 tclass=processUm das Limit zu erhöhen, führen Sie stattdessen diesen Befehl als root-Benutzer aus:
$ setsebool -P httpd_setrlimit 1Wenn der NGINX-Masterprozess den Fehler verursacht
Wenn der NGINX-Masterprozess den Fehler meldet, müssen Sie die systemd-unit-Datei für NGINX aktualisieren. Dadurch wird die maximale Anzahl der Dateideskriptoren sowohl für den Master- als auch für die Worker-Prozesse festgelegt.
- Erstellen Sie ein Verzeichnis für die
nginx.service-Konfiguration:
$ mkdir /etc/systemd/system/nginx.service.d- Fügen Sie die folgenden Zeilen in „/etc/systemd/system/nginx.service.d/nofile_limit.conf“ ein:
[Service]LimitNOFILE=65535- Laden Sie die systemd-Daemon-Konfiguration neu und starten Sie NGINX neu:
$ systemctl daemon-reload$ systemctl restart nginx.serviceWeitere Ressourcen
SELinux ist eine komplexe und leistungsfähige Funktion zur Verwaltung von Berechtigungen im Betriebssystem. Weitere Informationen finden Sie in den folgenden Dokumenten.
- Security‑Enhanced Linux, RHEL 6 oder RHEL 7
- SELinux (CentOS-Anleitung)
- Benutzerhandbuch zu Security-Enhanced Linux (Fedora-Projekt)
- Startseite des SELinux-Projekts
- Security‑Enhanced Linux (Nationale Sicherheitsbehörde der Vereinigten Staaten)
Über den Autor

Ähnliche Blogbeiträge
Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln
Beim NGINX Sprint 2022 besinnen wir uns auf unsere Open-Source-Wurzeln. Erfahren Sie mehr über die Initiativen, die wir im kommenden Jahr verfolgen, und teilen Sie uns mit, was Sie sich wünschen.

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen
Ein Ingress-Controller kann eines der leistungsstärksten Tools in Ihrem Kubernetes-Stack sein. Erfahren Sie, wie Sie Ihre Ingress-Anforderungen ermitteln, um die beste Option auszuwählen.
Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet
Wir haben kürzlich den Lösungsleitfaden zum NGINX Ingress Controller um Empfehlungen zur Dimensionierung für Amazon Elastic Kubernetes Service (EKS) ergänzt. In diesem Blogbeitrag erläutern wir, wie wir diese Empfehlungen erarbeitet haben, und stellen Ihnen alle Informationen zur Verfügung, die Sie benötigen, um selbst ähnliche Tests durchzuführen.

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77
Bei der Fehlersuche bei Datenverkehrsproblemen zwischen NGINX und Upstream-Servern konnte CDN77 die benötigten Daten nur aus dem Fehlerprotokoll mit aktivierter Debug-Ausgabe beziehen, was die Leistung beeinträchtigt und riesige Dateien erzeugt. Daher entwickelte das Team ein neues benutzerdefiniertes Modul, das ausschließlich die benötigten Daten protokolliert.
Ankündigung von NGINX Plus R16
NGINX Plus R16 ist eine einheitliche, elastische Ingress- und Egress-Schicht für Anwendungen, die die Funktionen eines Load Balancers, API-Gateways und einer WAF vereint und neue Features wie clusterfähige Ratenbegrenzung, Schlüssel-Wert-Speicher, „Random with Two Choices“, verbessertes UDP-Load-Balancing und vieles mehr bietet.
5 Gründe für den Umstieg auf softwarebasiertes Load Balancing
Entdecken Sie fünf Gründe für den Wechsel zu einem softwarebasierten Load Balancer wie NGINX Plus, darunter Kosteneinsparungen, die Einführung von DevOps und eine einheitliche Lösung für alle Umgebungen.