Fehlerbehebung bei Problemen im Zusammenhang mit SELinux
Wenn Sie SELinux auf Systemen aktivieren möchten, auf denen es zuvor deaktiviert war, oder wenn Sie einen Dienst in einer nicht standardmäßigen Konfiguration betreiben, müssen Sie möglicherweise Situationen beheben, die von SELinux blockiert werden. Beachten Sie, dass SELinux-Verweigerungen in den meisten Fällen auf eine Fehlkonfiguration hinweisen.
Identifizieren von SELinux-Verweigerungen
Befolgen Sie nur die notwendigen Schritte dieser Vorgehensweise; in den meisten Fällen müssen Sie nur Schritt 1 durchführen.
Vorgehensweise
-
Wenn Ihr Szenario durch SELinux blockiert wird, sollten Sie zunächst die Datei
/var/log/audit/audit.logüberprüfen, um weitere Informationen zur Zugriffsverweigerung zu erhalten. Verwenden Sie das Werkzeugausearch, um Audit-Protokolle abzufragen. Da SELinux-Entscheidungen, wie z. B. das Erlauben oder Verweigern des Zugriffs, zwischengespeichert werden (dieser Zwischenspeicher wird als Access Vector Cache (AVC) bezeichnet), verwenden Sie für den Parametermessage typedie WerteAVCundUSER_AVC, zum Beispiel:$ sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recentFalls keine Treffer gefunden werden, prüfen Sie, ob der Audit-Daemon läuft. Falls nicht, wiederholen Sie das Szenario mit der verweigerten Eingabe, nachdem Sie auditd gestartet haben, und prüfen Sie das Audit-Protokoll erneut.
-
Falls auditd ausgeführt wird, aber keine Treffer in der Ausgabe von ausearch gefunden werden, überprüfen Sie die Meldungen im systemd-Journal:
$ sudo journalctl -t setroubleshoot -
Wenn SELinux aktiv ist und der Audit-Daemon auf Ihrem System nicht läuft, suchen Sie in der Ausgabe des Befehls
dmesgnach bestimmten SELinux-Meldungen:$ sudo dmesg | grep -i -e type=1300 -e type=1400 -
Selbst nach den drei vorangegangenen Prüfungen ist es möglich, dass Sie nichts gefunden haben. In diesem Fall können AVC-Ablehnungen aufgrund von
dontaudit-Regeln unterdrückt werden.Um die
dontaudit-Regeln vorübergehend zu deaktivieren und so zu ermöglichen, dass alle Ablehnungen protokolliert werden,können Sie Folgendes tun:$ sudo semodule -DBNachdem Sie Ihr abgelehntes Szenario erneut ausgeführt und mithilfe der vorherigen Schritte Ablehnungsmeldungen gefunden haben, aktiviert der folgende Befehl die
dontaudit-Regeln in der Richtlinie wieder:$ sudo semodule -B -
Wenn Sie alle vier vorherigen Schritte angewendet haben und das Problem weiterhin unidentifiziert bleibt, sollten Sie prüfen, ob SELinux Ihr Szenario tatsächlich blockiert:
-
Wechseln Sie in den permissiven Modus:
$ sudo setenforce 0 $ getenforce Permissive -
Wiederholen Sie Ihr Szenario.
-
Wenn das Problem weiterhin besteht, blockiert etwas anderes als SELinux Ihr Szenario.
Analyse von SELinux-Verweigerungsmeldungen
Nachdem Sie festgestellt haben, dass SELinux Ihr Szenario blockiert, müssen Sie möglicherweise die Ursache analysieren, bevor Sie eine Lösung auswählen.
Voraussetzungen
-
Die Pakete
policycoreutils-python-utilsundsetroubleshoot-serversind auf Ihrem System installiert.
Vorgehensweise
-
Weitere Details zu einer protokollierten Ablehnung können Sie mit dem Befehl
sealertauflisten, zum Beispiel:$ sealert -l "*" SELinux is preventing /usr/bin/passwd from write access on the file /root/test. ***** Plugin leaks (86.2 confidence) suggests ***************************** Falls Sie ignorieren möchten, dass `passwd` versucht, schreibend auf die Testdatei zuzugreifen, weil Sie der Ansicht sind, dass es diesen Zugriff nicht benötigen sollte, dann sollten Sie dies als Fehler melden. Sie können ein lokales Richtlinienmodul erstellen, um diesen Zugriff mittels `dontaudit` zu unterdrücken. Führen Sie Folgendes aus: # ausearch -x /usr/bin/passwd --raw | audit2allow -D -M my-passwd # semodule -X 300 -i my-passwd.pp ***** Plugin catchall (14.7 confidence) suggests ************************** ... Raw Audit Messages type=AVC msg=audit(1553609555.619:127): avc: denied { write } for pid=4097 comm="passwd" path="/root/test" dev="dm-0" ino=17142697 scontext=unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0 .. Hash: passwd,passwd_t,admin_home_t,file,write -
Falls die im vorherigen Schritt erhaltenen Ergebnisse keine eindeutigen Vorschläge enthalten:
-
Aktivieren Sie die vollständige Pfadüberwachung, um die vollständigen Pfade zu den aufgerufenen Objekten anzuzeigen und zusätzliche Linux-Überwachungsereignisfelder sichtbar zu machen:
$ sudo auditctl -w /etc/shadow -p w -k shadow-write -
Leeren Sie den
setroubleshoot-Zwischenspeicher:$ sudo rm -f /var/lib/setroubleshoot/setroubleshoot.xml -
Reproduzieren Sie das Problem.
-
Wiederholen Sie Schritt 1.
Deaktivieren Sie nach Abschluss des Vorgangs die vollständige Pfadüberwachung:
$ sudo auditctl -W /etc/shadow -p w -k shadow-write
-
-
Falls
sealertlediglichcatchall-Vorschläge liefert oder das Hinzufügen einer neuen Regel mittels des Werkzeugsaudit2allowempfiehlt, gleichen Sie Ihr Problem mit den Beispielen ab, die in den SELinux-Verweigerungen im Audit-Protokoll aufgeführt und erläutert sind.
Weitere Ressourcen
-
Handbuchseite
sealert(8)
Behebung analysierter SELinux-Verweigerungen
In den meisten Fällen liefern die vom Werkzeug sealert bereitgestellten Vorschläge die richtige Anleitung zur Behebung von Problemen im Zusammenhang mit der SELinux-Richtlinie. Informationen zur Verwendung von sealert für die Analyse von SELinux-Verweigerungsmeldungen finden Sie unter „Analyse von SELinux-Verweigerungsmeldungen“.
Seien Sie vorsichtig, wenn das Werkzeug die Verwendung von audit2allow für Konfigurationsänderungen vorschlägt. Sie sollten audit2allow nicht als erste Option nutzen, um ein lokales Richtlinienmodul zu generieren, sobald Sie eine SELinux-Verweigerung (Denial) feststellen. Die Fehlersuche sollte stattdessen mit der Überprüfung beginnen, ob ein Problem mit der Kennzeichnung (Labeling) vorliegt. Der zweithäufigste Fall ist, dass Sie die Konfiguration eines Prozesses geändert haben, dabei jedoch vergessen haben, SELinux darüber zu informieren.
Probleme mit Kennzeichnungen
Eine häufige Ursache für Probleme bei der Kennzeichnung ist die Verwendung eines nicht standardmäßigen Verzeichnisses für einen Dienst. Ein Administrator könnte beispielsweise für eine Website anstelle von /var/www/html/ das Verzeichnis /srv/myweb/ verwenden wollen. Unter Red Hat Enterprise Linux ist das Verzeichnis /srv mit dem Typ var_t gekennzeichnet. In /srv erstellte Dateien und Verzeichnisse erben diesen Typ. Zudem können neu erstellte Objekte in Verzeichnissen der obersten Ebene – wie etwa /myserver – mit dem Typ default_t gekennzeichnet werden. SELinux hindert den Apache HTTP-Server (httpd) daran, auf Objekte dieser beiden Typen zuzugreifen. Um den Zugriff zu ermöglichen, muss SELinux bekannt sein, dass die Dateien in /srv/myweb/ für httpd zugänglich sein sollen:
$ sudo semanage fcontext -a -t httpd_sys_content_t "/srv/myweb(/.*)?"
Dieser semanage-Befehl fügt den Kontext für das Verzeichnis /srv/myweb/ sowie für alle darin enthaltenen Dateien und Unterverzeichnisse zur SELinux-Dateikontext-Konfiguration hinzu. Das Dienstprogramm semanage ändert den Kontext dabei nicht. Wenden Sie die Änderungen als Benutzer root mithilfe des Dienstprogramms restorecon an:
$ sudo restorecon -R -v /srv/myweb
Falscher Kontext
Das Dienstprogramm matchpathcon überprüft den Kontext eines Dateipfads und vergleicht ihn mit der Standardkennzeichnung für diesen Pfad. Das folgende Beispiel veranschaulicht die Verwendung von matchpathcon auf einem Verzeichnis, das falsch gekennzeichnete Dateien enthält:
$ matchpathcon -V /var/www/html/*
/var/www/html/index.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
/var/www/html/page1.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
In diesem Beispiel sind die Dateien index.html und page1.html mit dem Typ user_home_t gekennzeichnet. Dieser Typ wird für Dateien in Benutzer-Home-Verzeichnissen verwendet. Wenn Sie Dateien mithilfe des Befehls mv aus Ihrem Home-Verzeichnis verschieben, kann dies dazu führen, dass diese Dateien mit dem Typ user_home_t gekennzeichnet werden. Dieser Typ sollte außerhalb von Home-Verzeichnissen nicht vorkommen. Verwenden Sie das Dienstprogramm restorecon, um solchen Dateien wieder ihren korrekten Typ zuzuweisen:
$ sudo restorecon -v /var/www/html/index.html
restorecon reset /var/www/html/index.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_content_t:s0
Um den Kontext für alle Dateien in einem Verzeichnis wiederherzustellen, verwenden Sie die Option -R:
$ sudo restorecon -R -v /var/www/html/
restorecon reset /var/www/html/page1.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
restorecon reset /var/www/html/index.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
Eingeschränkte Anwendungen, die auf nicht standardmäßige Weise konfiguriert wurden
Dienste können auf verschiedene Arten ausgeführt werden. Um dies zu berücksichtigen, müssen Sie die Ausführungsmethode Ihrer Dienste festlegen. Dies erreichen Sie mithilfe von booleschen SELinux-Werten, die es ermöglichen, Teile der SELinux-Richtlinie zur Laufzeit zu ändern. So können Sie beispielsweise den Zugriff von Diensten auf NFS-Datenträgern erlauben, ohne die SELinux-Richtlinie neu laden oder kompilieren zu müssen. Die Ausführung von Diensten auf nicht standardmäßigen Portnummern erfordert zudem eine Aktualisierung der Richtlinienkonfiguration mit dem Befehl semanage.
Um beispielsweise dem Apache HTTP-Server die Kommunikation mit MariaDB zu ermöglichen, aktivieren Sie die boolesche Variable httpd_can_network_connect_db:
$ sudo setsebool -P httpd_can_network_connect_db on
Beachten Sie, dass die Option -P dafür sorgt, dass die Einstellung auch nach einem Neustart des Systems erhalten bleibt.
Falls der Zugriff auf einen bestimmten Dienst verweigert wird, verwenden Sie die Dienstprogramme getsebool und grep, um zu prüfen, ob boolesche Werte verfügbar sind, die den Zugriff ermöglichen. Verwenden Sie beispielsweise den Befehl getsebool -a | grep ftp, um nach FTP-bezogenen booleschen Werten zu suchen:
$ getsebool -a | grep ftp
ftpd_anon_write --> off
ftpd_full_access --> off
ftpd_use_cifs --> off
ftpd_use_nfs --> off
ftpd_connect_db --> off
httpd_enable_ftp_server --> off
tftp_anon_write --> off
Um eine Liste von booleschen Werten abzurufen und festzustellen, ob diese aktiviert oder deaktiviert sind, verwenden Sie den Befehl getsebool -a. Um eine Liste von booleschen Werten – einschließlich ihrer Bedeutung – abzurufen und festzustellen, ob diese aktiviert oder deaktiviert sind, installieren Sie das Paket selinux-policy-devel und verwenden Sie als Root den Befehl semanage boolean -l.
*Portnummern
Je nach Konfiguration der Richtlinien ist es Diensten möglicherweise nur gestattet, auf bestimmten Portnummern ausgeführt zu werden. Der Versuch, den Port zu ändern, auf dem ein Dienst läuft, ohne gleichzeitig die Richtlinien anzupassen, kann dazu führen, dass der Dienst nicht gestartet werden kann. Führen Sie beispielsweise den Befehl semanage port -l | grep http als Root aus, um die mit http verknüpften Ports aufzulisten:
$ sudo semanage port -l | grep http
http_cache_port_t tcp 3128, 8080, 8118
http_cache_port_t udp 3130
http_port_t tcp 80, 443, 488, 8008, 8009, 8443
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
Der Port-Typ http_port_t definiert die Ports, an denen der Apache HTTP-Server lauschen kann – in diesem Fall die TCP-Ports 80, 443, 488, 8008, 8009 und 8443. Konfiguriert ein Administrator die Datei httpd.conf so, dass httpd an Port 9876 lauscht (Listen 9876), die Richtlinie jedoch nicht entsprechend aktualisiert wird, schlägt der folgende Befehl fehl:
$ sudo systemctl start httpd.service
Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.
$ sudo systemctl status httpd.service
httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
Active: failed (Result: exit-code) since Thu 2013-08-15 09:57:05 CEST; 59s ago
Process: 16874 ExecStop=/usr/sbin/httpd $OPTIONS -k graceful-stop (code=exited, status=0/SUCCESS)
Process: 16870 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
Eine SELinux-Verweigerungsmeldung, ähnlich der folgenden, wird in /var/log/audit/audit.log protokolliert:
type=AVC msg=audit(1225948455.061:294): avc: denied { name_bind } for pid=4997 comm="httpd" src=9876 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket
Damit httpd an einem Port lauschen kann, der nicht für den Port-Typ http_port_t aufgeführt ist, verwenden Sie den Befehl semanage port, um dem Port eine andere Kennzeichnung zuzuweisen:
$ sudo semanage port -a -t http_port_t -p tcp 9876
Die Option -a ` fügt einen neuen Datensatz hinzu; die Option `-t definiert einen Typ; und die Option -p definiert ein Protokoll. Das letzte Argument ist die hinzuzufügende Portnummer.
Sonderfälle, sich entwickelnde oder fehlerhafte Anwendungen und kompromittierte Systeme
Anwendungen können Fehler enthalten, die dazu führen, dass SELinux den Zugriff verweigert. Zudem unterliegen die SELinux-Regeln einer ständigen Weiterentwicklung – es ist möglich, dass SELinux eine Anwendung noch nie in einer bestimmten Ausführungsweise beobachtet hat; dies kann eine Zugriffsverweigerung zur Folge haben, selbst wenn die Anwendung erwartungsgemäß funktioniert. Wird beispielsweise eine neue Version von PostgreSQL veröffentlicht, führt diese unter Umständen Aktionen aus, die in der aktuellen Richtlinie noch nicht berücksichtigt sind; dies kann dazu führen, dass der Zugriff verweigert wird, obwohl er eigentlich gestattet sein sollte.
Verwenden Sie in diesen Situationen – nachdem der Zugriff verweigert wurde – das Dienstprogramm audit2allow, um ein benutzerdefiniertes Richtlinienmodul zu erstellen, das den Zugriff gewährt. Fehlende Regeln in den SELinux-Richtlinien können Sie im Red Hat Bugzilla melden. Erstellen Sie für Red Hat Enterprise Linux 8 entsprechende Fehlerberichte für das Produkt „Red Hat Enterprise Linux 8“ und wählen Sie dabei die Komponente selinux-policy aus. Fügen Sie solchen Fehlerberichte die Ausgaben der Befehle audit2allow -w -a und audit2allow -a bei.
Fordert eine Anwendung weitreichende Sicherheitsberechtigungen an, könnte dies ein Hinweis darauf sein, dass die Anwendung kompromittiert ist. Setzen Sie Intrusion-Detection-Tools (Einbruchserkennungswerkzeuge) ein, um solch verdächtiges Verhalten zu überprüfen.
Die Solution Engine im Red Hat Customer Portal kann ebenfalls Hilfestellung bieten – in Form eines Artikels, der eine mögliche Lösung für genau das Problem (oder ein sehr ähnliches) enthält, mit dem Sie konfrontiert sind. Wählen Sie das entsprechende Produkt sowie die Version aus und verwenden Sie SELinux-bezogene Schlüsselwörter – wie etwa „selinux“ oder „avc“ – in Kombination mit dem Namen des blockierten Dienstes oder der blockierten Anwendung; zum Beispiel: selinux samba.
SELinux-Verweigerungen im Audit-Protokoll
Das Linux-Audit-System speichert Protokolleinträge standardmäßig in der Datei /var/log/audit/audit.log.
Um ausschließlich SELinux-bezogene Einträge aufzulisten, verwenden Sie den Befehl ausearch, wobei der Parameter für den Meldungstyp auf mindestens AVC und AVC_USER gesetzt ist – zum Beispiel:
$ sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR
Ein SELinux-Verweigerungseintrag in der Audit-Protokolldatei kann wie folgt aussehen:
type=AVC msg=audit(1395177286.929:1638): avc: denied { read } for pid=6591 comm="httpd" name="webpages" dev="0:37" ino=2112 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:nfs_t:s0 tclass=dir
Die wichtigsten Teile dieses Eintrags sind:
-
avc: denied– die von SELinux durchgeführte und im Access Vector Cache (AVC) protokollierte Aktion -
{ read }– die verweigerte Aktion -
pid=6591– die Prozesskennung des Subjekts, das versucht hat, die verweigerte Aktion auszuführen -
comm="httpd"– der Name des Befehls, der zum Aufrufen des analysierten Prozesses verwendet wurde -
httpd_t– der SELinux-Typ des Prozesses -
nfs_t– der SELinux-Typ des Objekts, das von der Prozessaktion betroffen ist -
tclass=dir– die Klasse des Zielobjekts
Der vorherige Protokolleintrag lässt sich wie folgt übersetzen:
SELinux hat dem Prozess httpd mit der PID 6591 und dem Typ httpd_t das Lesen aus einem Verzeichnis mit dem Typ nfs_t verweigert.
Die folgende SELinux-Fehlermeldung tritt auf, wenn der Apache HTTP-Server versucht, auf ein Verzeichnis zuzugreifen, das mit einem Typ für die Samba-Suite gekennzeichnet ist:
type=AVC msg=audit(1226874073.147:96): avc: denied { getattr } for pid=2465 comm="httpd" path="/var/www/html/file1" dev=dm-0 ino=284133 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file
-
{ getattr }– der Eintraggetattrzeigt an, dass der Quellprozess versucht hat, die Statusinformationen der Zieldatei zu lesen. Dies geschieht vor dem eigentlichen Lesen von Dateien. SELinux verweigert diese Aktion, da der Prozess auf die Datei zugreift, aber nicht über die entsprechende Berechtigung verfügt. Häufig vorkommende Berechtigungen sindgetattr,readundwrite. -
path="/var/www/html/file1"– der Pfad zu dem Objekt (Ziel), auf das der Prozess zugreifen wollte. -
scontext="unconfined_u:system_r:httpd_t:s0"– der SELinux-Kontext des Prozesses (Quelle), der die verweigerte Aktion versucht hat. In diesem Fall handelt es sich um den SELinux-Kontext des Apache HTTP-Servers, der mit dem Typhttpd_tausgeführt wird. -
tcontext="unconfined_u:object_r:samba_share_t:s0"– der SELinux-Kontext des Objekts (Ziels), auf das der Prozess zuzugreifen versuchte. In diesem Fall handelt es sich um den SELinux-Kontext vonfile1.
Diese SELinux-Verweigerung lässt sich wie folgt übersetzen:
SELinux hat dem Prozess httpd mit der PID 2465 den Zugriff auf die Datei /var/www/html/file1 vom Typ samba_share_t verweigert, da diese für Prozesse, die in der httpd_t-Domäne ausgeführt werden, nicht zugänglich ist, sofern nichts anderes konfiguriert ist.
Zusätzliche Ressourcen
-
Handbuchseiten
auditd(8)undausearch(8)
Want to help? Learn how to contribute to Fedora Docs ›