Eine Einführung in SELinux unter CentOS 7 - Teil 2: Dateien und Prozesse

Einführung

Im https://www.digitalocean.com/community/tutorials/an-einführung-in-selinux-on-centos-7-teil-1-grundkonzepte, dem ersten Teil unserer SELinux-Serie, haben wir gesehen, wie das geht Aktivieren und Deaktivieren von SELinux und Ändern einiger Richtlinieneinstellungen mithilfe von Booleschen Werten. In diesem zweiten Teil werden wir über Datei- und Prozesssicherheitskontexte sprechen.

Um Ihren Speicher aus dem vorherigen Lernprogramm zu aktualisieren, ist ein Dateisicherheitskontext ein type und ein Prozesssicherheitskontext eine domain.

_ * Hinweis * + Die in diesem Tutorial gezeigten Befehle, Pakete und Dateien wurden unter CentOS 7 getestet. Die Konzepte bleiben für andere Distributionen gleich. _

In diesem Lernprogramm führen wir die Befehle als Root-Benutzer aus, sofern nicht anders angegeben. Wenn Sie keinen Zugriff auf das Root-Konto haben und ein anderes Konto mit Sudo-Berechtigungen verwenden, müssen Sie den Befehlen das Schlüsselwort "+ sudo +" voranstellen.

Erstellen von Testbenutzerkonten

Erstellen wir zunächst vier Benutzerkonten, um die SELinux-Funktionen zu demonstrieren.

  • Stammkunde

  • Switcheduser

  • Gastbenutzer

  • eingeschränkte Benutzer

Sie sollten derzeit der Benutzer * root * sein. Führen Sie den folgenden Befehl aus, um das Konto * regularuser * hinzuzufügen:

useradd -c "Regular User" regularuser

Dann führen wir den Befehl + passwd + aus, um das Passwort zu ändern:

passwd regularuser

Die Ausgabe wird uns nach einem neuen Passwort fragen. Nach der Auslieferung ist das Konto für die Anmeldung bereit:

Changing password for user regularuser.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

Erstellen wir auch die anderen Konten:

useradd -c "Switched User" switcheduser
passwd switcheduser
useradd -c "Guest User" guestuser
passwd guestuser
useradd -c "Restricted Role User" restricteduser
passwd restricteduser

SELinux für Prozesse und Dateien

Der Zweck von SELinux besteht darin, sicherzustellen, wie Prozesse auf Dateien in einer Linux-Umgebung zugreifen. Ohne SELinux wird ein Prozess oder eine Anwendung wie der Apache-Daemon im Kontext des Benutzers ausgeführt, der ihn gestartet hat. Wenn Ihr System also von einer betrügerischen Anwendung kompromittiert wird, die unter dem Root-Benutzer ausgeführt wird, kann die App alles tun, was sie will, da Root über umfassende Rechte für jede Datei verfügt.

SELinux versucht, noch einen Schritt weiter zu gehen und dieses Risiko auszuschalten. Mit SELinux hat ein Prozess oder eine Anwendung nur die Rechte, die sie benötigen, um zu funktionieren, und NICHTS mehr. Die SELinux-Richtlinie für die Anwendung legt fest, auf welche Dateitypen zugegriffen werden muss und zu welchen Prozessen Übergänge möglich sind. SELinux-Richtlinien werden von App-Entwicklern geschrieben und mit der Linux-Distribution ausgeliefert, die sie unterstützt. Eine Richtlinie besteht im Wesentlichen aus einer Reihe von Regeln, mit denen Prozesse und Benutzer ihren Rechten zugeordnet werden.

Wir beginnen die Diskussion dieses Teils des Tutorials damit, zu verstehen, was SELinux-Kontexte und -Domänen bedeuten.

Der erste Teil der Sicherheit versieht jede Entität im Linux-System mit einem Label. Ein Label ist wie jedes andere Datei- oder Prozessattribut (Eigentümer, Gruppe, Erstellungsdatum usw.). Es zeigt den Kontext der Ressource. Was ist also ein Kontext? Einfach ausgedrückt, ist ein Kontext eine Sammlung sicherheitsrelevanter Informationen, die SELinux bei Entscheidungen zur Zugriffssteuerung unterstützen. Jedes Linux-System kann einen Sicherheitskontext haben: Ein Benutzerkonto, eine Datei, ein Verzeichnis, ein Daemon oder ein Port können alle ihre Sicherheitskontexte haben. Sicherheitskontext bedeutet jedoch für verschiedene Objekttypen unterschiedliche Dinge. + ​

SELinux-Dateikontexte

Beginnen wir mit dem Verständnis der SELinux-Dateikontexte. Sehen wir uns die Ausgabe eines regulären Befehls ls -l im Verzeichnis / etc an.

ls -l /etc/*.conf

Dies wird uns eine vertraute Ausgabe zeigen:

...
-rw-r--r--. 1 root root    19 Aug 19 21:42 /etc/locale.conf
-rw-r--r--. 1 root root   662 Jul 31  2013 /etc/logrotate.conf
-rw-r--r--. 1 root root  5171 Jun 10 07:35 /etc/man_db.conf
-rw-r--r--. 1 root root   936 Jun 10 05:59 /etc/mke2fs.conf
...

Einfach, richtig? Fügen wir nun das -Z-Flag hinzu:

ls -Z /etc/*.conf

Wir haben jetzt eine zusätzliche Spalte mit Informationen nach dem Benutzer- und Gruppeneigentum:

...
-rw-r--r--. root root system_u:object_r:locale_t:s0    /etc/locale.conf
-rw-r--r--. root root system_u:object_r:etc_t:s0       /etc/logrotate.conf
-rw-r--r--. root root system_u:object_r:etc_t:s0       /etc/man_db.conf
-rw-r--r--. root root system_u:object_r:etc_t:s0       /etc/mke2fs.conf
...

Diese Spalte zeigt die Sicherheitskontexte der Dateien. Eine Datei soll mit ihrem Sicherheitskontext beschriftet worden sein, wenn Ihnen diese Informationen zur Verfügung stehen. Sehen wir uns einen der Sicherheitskontexte genauer an.

-rw-r--r--. root    root  system_u:object_r:etc_t:s0       /etc/logrotate.conf

Der Sicherheitskontext ist dieser Teil:

system_u:object_r:etc_t:s0

Es gibt vier Teile und jeder Teil des Sicherheitskontexts ist durch einen Doppelpunkt (:) getrennt. Der erste Teil ist der SELinux-Benutzerkontext für die Datei. Wir werden uns später mit SELinux-Benutzern befassen, aber jetzt können wir sehen, dass es * system_u * ist. Jedes Linux-Benutzerkonto wird einem SELinux-Benutzer zugeordnet. In diesem Fall wird der Benutzer * root *, dem die Datei gehört, dem Benutzer * system_u * SELinux zugeordnet. Diese Zuordnung wird von der SELinux-Richtlinie vorgenommen.

Der zweite Teil gibt die SELinux-Rolle * object_r * an. Schauen Sie sich zum Auffrischen der SELinux-Rollen den ersten SELinux-Artikel an.

Was hier am wichtigsten ist, ist der dritte Teil, der Typ der Datei, die hier als * etc_t * aufgeführt ist. Dies ist der Teil, der definiert, zu welchem ​​Typ die Datei oder das Verzeichnis gehört. Wir können sehen, dass die meisten Dateien zum Typ * etc_t * im Verzeichnis + / etc + gehören. Hypothetisch können Sie sich den Typ als eine Art „Gruppe“ oder attribut für die Datei vorstellen: Dies ist eine Methode zum Klassifizieren der Datei.

Wir können auch sehen, dass einige Dateien möglicherweise zu anderen Typen gehören, wie z. B. "+ locale.conf +" mit dem Typ "* locale_t *". Auch wenn alle hier aufgelisteten Dateien den gleichen Benutzer- und Gruppenbesitzer haben, können ihre Typen unterschiedlich sein.

Als weiteres Beispiel überprüfen wir die Typkontexte für Benutzer-Ausgangsverzeichnisse:

ls -Z /home

Basisverzeichnisse haben einen anderen Kontexttyp: * user_home_dir_t *

drwx------. guestuser      guestuser      unconfined_u:object_r:user_home_dir_t:s0      guestuser
drwx------. root           root           system_u:object_r:lost_found_t:s0 lost+found
drwx------. regularuser    regularuser    unconfined_u:object_r:user_home_dir_t:s0      regularuser
drwx------. restricteduser restricteduser unconfined_u:object_r:user_home_dir_t:s0      restricteduser
drwx------. switcheduser   switcheduser   unconfined_u:object_r:user_home_dir_t:s0      switcheduser
drwx------. sysadmin       sysadmin       unconfined_u:object_r:user_home_dir_t:s0      sysadmin

Der vierte Teil des Sicherheitskontexts, * s0 , hat mit multilevel security oder MLS zu tun. Grundsätzlich ist dies eine andere Möglichkeit, die SELinux-Sicherheitsrichtlinie durchzusetzen, und dieser Teil zeigt die Empfindlichkeit der Ressource ( s0 *). Wir werden später kurz auf Sensibilität und Kategorien eingehen. Für die meisten Vanilla-Setups von SELinux sind die ersten drei Sicherheitskontexte wichtiger.

SELinux-Prozesskontexte

Lassen Sie uns nun über Kontexte der Prozesssicherheit sprechen.

Starten Sie die Apache- und SFTP-Dienste. Wir haben diese Dienste im ersten SELinux-Tutorial installiert.

service httpd start
service vsftpd start

Wir können den Befehl + ps + mit einigen Flags ausführen, um die auf unserem Server ausgeführten Apache- und SFTP-Prozesse anzuzeigen:

ps -efZ | grep 'httpd\|vsftpd'

Wieder wird das Flag -Z zum Anzeigen von SELinux-Kontexten verwendet. Die Ausgabe zeigt den Benutzer, der den Prozess ausführt, die Prozess-ID und die übergeordnete Prozess-ID:

system_u:system_r:httpd_t:s0            root        7126    1       0 16:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0            apache      7127    7126    0 16:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0            apache      7128    7126    0 16:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0            apache      7129    7126    0 16:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0            apache      7130    7126    0 16:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0            apache      7131    7126    0 16:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:ftpd_t:s0-s0:c0.c1023 root        7209    1       0 16:54 ?        00:00:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 root 7252 2636  0 16:57 pts/0 00:00:00 grep --color=auto httpd\|vsftpd

Der Sicherheitskontext ist dieser Teil:

system_u:system_r:httpd_t:s0

Der Sicherheitskontext besteht aus vier Teilen: Benutzer, Rolle, Domäne und Vertraulichkeit. Der Benutzer, die Rolle und die Vertraulichkeit funktionieren genauso wie die im vorherigen Abschnitt erläuterten Kontexte für Dateien. Die Domain ist nur für Prozesse gültig.

Im obigen Beispiel sehen wir, dass einige Prozesse in der Domäne * httpd_t * ausgeführt werden, während einer in der Domäne * ftpd_t * ausgeführt wird.

Was macht die Domain für Prozesse? Es gibt dem Prozess einen Kontext, in dem er ausgeführt werden kann. Es ist wie eine Blase um den Prozess, die ihn beschränkt. Es teilt dem Prozess mit, was er kann und was nicht. Durch diese Einschränkung wird sichergestellt, dass jede Prozessdomäne nur auf bestimmte Dateitypen und nicht mehr zugreifen kann.

Selbst wenn ein Prozess von einem anderen böswilligen Prozess oder Benutzer entführt wird, kann dieses Modell die Dateien, auf die es Zugriff hat, im schlimmsten Fall beschädigen. Beispielsweise hat der vsftp-Daemon keinen Zugriff auf Dateien, die beispielsweise von sendmail oder Samba verwendet werden. Diese Einschränkung wird von der Kernel-Ebene aus implementiert: Sie wird erzwungen, wenn die SELinux-Richtlinie in den Speicher geladen wird, und die Zugriffskontrolle wird somit obligatorisch.

Regeln der Namensgebung

Bevor wir fortfahren, finden Sie hier einen Hinweis zur SELinux-Namenskonvention. SELinux-Benutzer haben das Suffix "_u", Rollen das Suffix "_r" und Typen (für Dateien) oder Domänen (für Prozesse) das Suffix "_t".

Wie Prozesse auf Ressourcen zugreifen

Bisher haben wir gesehen, dass Dateien und Prozesse unterschiedliche Kontexte haben können und dass sie auf ihre eigenen Typen oder Domänen beschränkt sind. Wie läuft ein Prozess ab? Zur Ausführung muss ein Prozess auf seine Dateien zugreifen und einige Aktionen ausführen (Öffnen, Lesen, Ändern oder Ausführen). Wir haben auch gelernt, dass jeder Prozess nur auf bestimmte Arten von Ressourcen zugreifen kann (Dateien, Verzeichnisse, Ports usw.).

SELinux schreibt diese Zugriffsregeln in einer Richtlinie vor. Die Zugriffsregeln folgen einer standardmäßigen _allow-Anweisungsstruktur:

allow <domain> <type>:<class> { <permissions> };

Wir haben bereits über Domänen und Typen gesprochen. * Klasse * definiert, was die Ressource tatsächlich darstellt (Datei, Verzeichnis, symbolische Verknüpfung, Gerät, Ports, Cursor usw.)

Diese generische Erlaubnis-Anweisung bedeutet Folgendes:

  • Wenn ein Prozess einer bestimmten Domäne angehört

  • Das Ressourcenobjekt, auf das zugegriffen werden soll, hat eine bestimmte Klasse und einen bestimmten Typ

  • Dann erlauben Sie den Zugriff

  • Anderenfalls verweigern Sie den Zugriff

Um zu sehen, wie dies funktioniert, betrachten wir die Sicherheitskontexte des httpd-Daemons, der auf unserem CentOS 7-System ausgeführt wird:

system_u:system_r:httpd_t:s0     7126 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     7127 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     7128 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     7129 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     7130 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     7131 ?        00:00:00 httpd

Das Standard-Ausgangsverzeichnis für den Webserver lautet "+ / var / www / html". Erstellen Sie eine Datei in diesem Verzeichnis und überprüfen Sie den Kontext:

touch /var/www/html/index.html
ls -Z /var/www/html/*

Der Dateikontext für unseren Webinhalt lautet * httpd_sys_content_t *:

-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html

Wir können den Befehl + sesearch + verwenden, um die Art des Zugriffs zu überprüfen, der für den httpd-Daemon zulässig ist:

sesearch --allow --source httpd_t --target httpd_sys_content_t --class file

Die mit dem Befehl verwendeten Flags sind ziemlich selbsterklärend: Die Quelldomäne ist * httpd_t *, dieselbe Domäne, in der Apache ausgeführt wird. Wir interessieren uns für Zielressourcen, die Dateien sind und einen Typkontext von * httpd_sys_content_t * haben. Ihre Ausgabe sollte folgendermaßen aussehen:

Found 4 semantic av rules:
  allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;
  allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
  allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
  allow httpd_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename execute open } ;

Beachten Sie die erste Zeile:

allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;

Dies besagt, dass der httpd-Daemon (der Apache-Webserver) die E / A-Steuerung hat und den Zugriff auf Dateien des Typs * httpd_sys_content * liest, erhält, sperrt und öffnet. In diesem Fall hat Ihre "+ index.html" -Datei den gleichen Typ.

Wenn Sie noch einen Schritt weiter gehen, ändern Sie zunächst die Webseite ("+ / var / www / html / index.html"). Bearbeiten Sie die Datei, um diesen Inhalt zu enthalten:

<html>
   <title>
       This is a test web page
   </title>
   <body>
       <h1>This is a test web page</h1>
   </body>
</html>

Als nächstes ändern wir die Berechtigung des Ordners "+ / var / www / +" und seinen Inhalt, gefolgt von einem Neustart des httpd-Daemons:

chmod -R 755 /var/www
service httpd restart

Wir werden dann versuchen, über einen Browser darauf zuzugreifen:

image: https://assets.digitalocean.com/articles/SELinuxCentOS7/2.jpg [Zugreifen auf eine Webseite mit der richtigen SELiunux-Einstellung]

_ * Hinweis * + Je nachdem, wie Ihr Server eingerichtet ist, müssen Sie möglicherweise Port 80 in der IPTables-Firewall aktivieren, um eingehenden HTTP-Verkehr von außerhalb des Servers zuzulassen. Wir werden hier nicht auf die Details zum Aktivieren von Ports in IPTables eingehen. Es gibt einige ausgezeichnete DigitalOcean-https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall- using-iptables-on-ubuntu-14-04[articles] zu dem Thema, das Sie verwenden Kann benutzen. _

So weit, ist es gut. Der httpd-Daemon ist berechtigt, auf einen bestimmten Dateityp zuzugreifen. Dies wird beim Zugriff über den Browser angezeigt. Als nächstes wollen wir die Dinge ein wenig verändern, indem wir den Kontext der Datei ändern. Wir werden den Befehl + chcon + dafür verwenden. Das Flag "+ - type +" für den Befehl ermöglicht es uns, einen neuen Typ für die Zielressource anzugeben. Hier ändern wir den Dateityp in * var_t *.

chcon --type var_t /var/www/html/index.html

Wir können die Typenänderung bestätigen:

ls -Z /var/www/html/
-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0   index.html

Als nächstes, wenn wir versuchen, auf die Webseite zuzugreifen (d. H. Der httpd-Daemon versucht, die Datei zu lesen.) Möglicherweise wird ein * Verbotener * Fehler angezeigt, oder es wird die generische CentOS-Seite "Testing 123" angezeigt:

image: https://assets.digitalocean.com/articles/SELinuxCentOS7/3.jpg [Zugriff auf die Webseite mit falscher SELinux-Einstellung]

Was passiert hier? Offensichtlich wird jetzt ein Teil des Zugriffs verweigert, aber um wen handelt es sich dabei? Für SELinux ist der Webserver berechtigt, nur auf bestimmte Dateitypen zuzugreifen, und var_t gehört nicht zu diesen Kontexten. Da wir den Kontext der Datei index.html in var_t geändert haben, kann Apache ihn nicht mehr lesen und es wird eine Fehlermeldung angezeigt.

Um die Arbeit wieder aufzunehmen, ändern wir den Dateityp mit dem Befehl "+ restorecon +". Die Option -v zeigt die Änderung der Kontextbezeichnungen an:

restorecon -v /var/www/html/index.html
restorecon reset /var/www/html/index.html context unconfined_u:object_r:var_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0

Wenn wir versuchen, jetzt auf die Seite zuzugreifen, wird erneut der Text "Dies ist eine Test-Webseite" angezeigt.

Dies ist ein wichtiges Konzept, das Sie verstehen sollten: Um sicherzustellen, dass sich SELinux so verhält, wie es sollte, muss sichergestellt werden, dass Dateien und Verzeichnisse den richtigen Kontext haben. Wir werden am Ende dieses Abschnitts einen praktischen Anwendungsfall sehen, aber lassen Sie uns vorher noch ein paar Dinge besprechen.

Kontextvererbung für Dateien und Verzeichnisse

SELinux erzwingt etwas, das wir als "Kontextvererbung" bezeichnen können. Dies bedeutet, dass Prozesse und Dateien mit den Kontexten ihrer Eltern erstellt werden, es sei denn, dies ist in der Richtlinie festgelegt.

Wenn also ein Prozess namens "proc_a" einen anderen Prozess namens "proc_b" erzeugt, wird der erzeugte Prozess in derselben Domäne wie "proc_a" ausgeführt, sofern in der SELinux-Richtlinie nicht anders angegeben.

Wenn wir ein Verzeichnis mit dem Typ "some_context_t" haben, haben alle Dateien oder Verzeichnisse, die unter diesem Typ erstellt wurden, denselben Typkontext, sofern in der Richtlinie nichts anderes angegeben ist.

Um dies zu veranschaulichen, überprüfen wir die Kontexte des Verzeichnisses "+ / var / www / +":

ls -Z /var/www

Das Verzeichnis "+ html " in " / var / www / " hat den Typ "* httpd_sys_content_t *". Wie wir zuvor gesehen haben, hat die darin enthaltene Datei " index.html +" denselben Kontext (d. H. Den Kontext des übergeordneten Elements):

drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html

Diese Vererbung bleibt nicht erhalten, wenn Dateien an einen anderen Speicherort kopiert werden. Bei einem Kopiervorgang nimmt die kopierte Datei oder das kopierte Verzeichnis den Typkontext des Zielverzeichnisses an. Im folgenden Codeausschnitt kopieren wir die Datei "+ index.html" (mit dem Typ "httpd_sys_content_t") in das Verzeichnis "+ / var / +":

cp /var/www/html/index.html /var/

Wenn wir den Kontext der kopierten Datei überprüfen, werden wir feststellen, dass er in * var_t * geändert wurde, dem Kontext des aktuellen übergeordneten Verzeichnisses:

ls -Z /var/index.html
-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0   /var/index.html

Diese Änderung des Kontexts kann durch die Klausel "+ - preserver = context" im Befehl "+ cp" überschrieben werden.

Beim Verschieben von Dateien oder Verzeichnissen bleiben die ursprünglichen Kontexte erhalten. Im folgenden Befehl verschieben wir die Datei "+ / var / index.html " in das Verzeichnis " / etc / +":

mv  /var/index.html  /etc/

Wenn wir den Kontext der verschobenen Datei überprüfen, stellen wir fest, dass der * var_t * -Kontext im Verzeichnis "+ / etc / +" beibehalten wurde:

ls -Z /etc/index.html
-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0   /etc/index.html

Warum beschäftigen wir uns also so mit Dateikontexten? Warum ist dieses Konzept zum Kopieren und Verschieben wichtig? Denken Sie darüber nach: Vielleicht haben Sie beschlossen, alle HTML-Dateien Ihres Webservers in ein separates Verzeichnis unter dem Stammordner zu kopieren. Sie haben dies getan, um den Sicherungsvorgang zu vereinfachen und die Sicherheit zu erhöhen: Sie möchten nicht, dass Hacker einfach erraten, wo sich die Dateien Ihrer Website befinden. Sie haben die Zugriffssteuerung des Verzeichnisses aktualisiert, die Webkonfigurationsdatei so geändert, dass sie auf den neuen Speicherort verweist, den Dienst neu gestartet, aber er funktioniert immer noch nicht. Vielleicht können Sie sich dann als nächsten Fehlerbehebungsschritt die Kontexte des Verzeichnisses und seiner Dateien ansehen. Lassen Sie es uns als praktisches Beispiel ausführen.

SELinux in Aktion: Testen eines Dateikontextfehlers

Erstellen wir zunächst ein Verzeichnis mit dem Namen "+ www " unter dem Stammverzeichnis. Wir werden auch einen Ordner namens " html" und "+ www" erstellen.

mkdir -p /www/html

Wenn wir den Befehl + ls -Z + ausführen, werden wir feststellen, dass diese Verzeichnisse mit dem * default_t * -Kontext erstellt wurden:

ls -Z /www/
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 html

Als nächstes kopieren wir den Inhalt des Verzeichnisses + / var / www / html nach` + / www / html`:

cp /var/www/html/index.html /www/html/

Die kopierte Datei hat den Kontext * default_t *. Dies ist der Kontext des übergeordneten Verzeichnisses.

Wir bearbeiten nun die Datei "+ httpd.conf", um auf dieses neue Verzeichnis als Stammordner der Website zu verweisen. Wir müssen auch die Zugriffsrechte für dieses Verzeichnis lockern.

vi /etc/httpd/conf/httpd.conf

Zuerst kommentieren wir den vorhandenen Speicherort für das Dokument root aus und fügen eine neue Direktive + DocumentRoot + zu + / www / html + hinzu:

# DocumentRoot "/var/www/html"

DocumentRoot "/www/html"

Wir kommentieren auch den Abschnitt mit den Zugriffsrechten für den vorhandenen Dokumentenstamm aus und fügen einen neuen Abschnitt hinzu:

#<Directory "/var/www">
#    AllowOverride None
   # Allow open access:
#    Require all granted
#</Directory>

<Directory "/www">
   AllowOverride None
   # Allow open access:
   Require all granted
</Directory>

Wir belassen den Speicherort des Verzeichnisses "+ cgi-bin +" unverändert. Wir werden hier nicht auf die detaillierte Apache-Konfiguration eingehen. Wir möchten nur, dass unsere Site für SELinux-Zwecke funktioniert.

Starten Sie abschließend den httpd-Daemon neu:

service httpd restart

Nach dem Neustart des Servers wird beim Zugriff auf die Webseite derselbe Fehler "403 Forbidden" (oder die Standardseite "Testing 123") angezeigt, den wir zuvor gesehen haben.

Der Fehler tritt auf, weil sich der Inhalt der Datei "+ index.html" während des Kopiervorgangs geändert hat. Es muss wieder in den ursprünglichen Kontext (httpd_sys_content_t) zurückgesetzt werden.

Aber wie machen wir das?

Ändern und Wiederherstellen von SELinux-Dateikontexten

In einem früheren Codebeispiel haben wir zwei Befehle zum Ändern des Dateiinhalts gesehen: "+ chcon " und " restorecon ". Das Ausführen von ` chcon ` ist eine vorübergehende Maßnahme. Sie können damit vorübergehend Datei- oder Verzeichniskontexte ändern, um Fehler bei der Zugriffsverweigerung zu beheben. Diese Methode ist jedoch nur vorübergehend: Wenn Sie ein Dateisystem neu beschriften oder den Befehl ` restorecon +` ausführen, wird die Datei auf den ursprünglichen Kontext zurückgesetzt.

Wenn Sie + chcon + ausführen, müssen Sie den richtigen Kontext für die Datei kennen. Das Flag "+ - Typ " gibt den Kontext für das Ziel an. Für " restorecon " ist dies nicht erforderlich. Wenn Sie ` restorecon +` ausführen, wird auf die Datei der richtige Kontext erneut angewendet und die Änderungen werden dauerhaft übernommen.

Aber wenn Sie den korrekten Kontext der Datei nicht kennen, woher weiß das System, welcher Kontext angewendet werden soll, wenn es "+ restorecon +" ausführt?

Praktischerweise „merkt“ sich SELinux den Kontext jeder Datei oder jedes Verzeichnisses auf dem Server. In CentOS 7 werden Kontexte von Dateien, die bereits im System vorhanden sind, in der Datei + / etc / selinux / target / contexts / files / file_contexts + aufgelistet. Es handelt sich um eine große Datei, in der alle Dateitypen aufgelistet sind, die mit jeder von der Linux-Distribution unterstützten Anwendung verknüpft sind. Kontexte neuer Verzeichnisse und Dateien werden in der Datei + / etc / selinux / target / contexts / files / file_contexts.local + aufgezeichnet. Wenn wir also den Befehl + restorecon + ausführen, sucht SELinux in einer dieser beiden Dateien nach dem richtigen Kontext und wendet ihn auf das Ziel an.

Das folgende Code-Snippet zeigt einen Auszug aus einer der Dateien:

cat /etc/selinux/targeted/contexts/files/file_contexts
...
/usr/(.*/)?lib(/.*)?    system_u:object_r:lib_t:s0
/opt/(.*/)?man(/.*)?    system_u:object_r:man_t:s0
/dev/(misc/)?agpgart    -c      system_u:object_r:agp_device_t:s0
/usr/(.*/)?sbin(/.*)?   system_u:object_r:bin_t:s0
/opt/(.*/)?sbin(/.*)?   system_u:object_r:bin_t:s0
/etc/(open)?afs(/.*)?   system_u:object_r:afs_config_t:s0
...

Um den Kontext unserer index.html-Datei unter "+ / www / html +" dauerhaft zu ändern, müssen wir zwei Schritte ausführen.

  • Zuerst führen wir den Befehl + semanage fcontext + aus. Dadurch wird der neue Kontext in die Datei + / etc / selinux / target / contexts / files / file_contexts.local + geschrieben. Die Datei selbst wird jedoch nicht umbenannt. Dies machen wir für beide Verzeichnisse.

semanage fcontext --add --type httpd_sys_content_t "/www(/.*)?"
semanage fcontext --add --type httpd_sys_content_t "/www/html(/.*)?"

Um sicherzustellen, können wir die Dateikontextdatenbank überprüfen (beachten Sie, dass wir die Datei + file_contexts.local + verwenden):

cat /etc/selinux/targeted/contexts/files/file_contexts.local

Sie sollten die aktualisierten Kontexte sehen:

# This file is auto-generated by libsemanage
# Do not edit directly.

/www(/.*)?    system_u:object_r:httpd_sys_content_t:s0
/www/html(/.*)?    system_u:object_r:httpd_sys_content_t:s0

Als nächstes führen wir den Befehl + restorecon + aus. Dadurch wird die Datei oder das Verzeichnis mit den im vorherigen Schritt aufgezeichneten Daten neu gekennzeichnet:

restorecon -Rv /www

Dies sollte den Kontext in drei Ebenen zurücksetzen: das Verzeichnis der obersten Ebene "+ / www ", das Verzeichnis " / www / html" und die Datei "+ index.html" unter "+ / www / html +":

restorecon reset /www context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /www/html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /www/html/index.html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0

Wenn wir jetzt versuchen, auf die Webseite zuzugreifen, sollte dies funktionieren.

Es gibt ein nützliches Tool mit dem Namen "+ matchpathcon ", mit dem Sie kontextbezogene Probleme beheben können. Dieser Befehl zeigt den aktuellen Kontext einer Ressource an und vergleicht ihn mit den in der SELinux-Kontextdatenbank aufgelisteten. Wenn dies nicht der Fall ist, wird die erforderliche Änderung vorgeschlagen. Testen wir dies mit der Datei " / www / html / index.html ". Wir werden das ` -V +` Flag verwenden, das den Kontext überprüft:

matchpathcon -V /www/html/index.html

Die Ausgabe von + matchpathcon + sollte zeigen, dass der Kontext überprüft wurde.

/www/html/index.html verified.

Bei einer falsch beschrifteten Datei wird in der Nachricht der Kontext angegeben:

/www/html/index.html has context unconfined_u:object_r:default_t:s0, should be system_u:object_r:httpd_sys_content_t:s0

Domain-Übergang

Bisher haben wir gesehen, wie Prozesse auf Dateisystemressourcen zugreifen. Wir werden nun sehen, wie Prozesse auf andere Prozesse zugreifen.

Domänenübergang ist die Methode, mit der ein Prozess seinen Kontext von einer Domäne in eine andere ändert. Angenommen, Sie haben einen Prozess namens proc_a, der in einem Kontext von contexta_t ausgeführt wird. Beim Domänenübergang kann proc_a eine Anwendung (ein Programm oder ein ausführbares Skript) mit dem Namen app_x ausführen, die einen anderen Prozess erzeugt. Dieser neue Prozess könnte proc_b heißen und in der contextb_t-Domäne ausgeführt werden. So effektiv ist contexta_t transitioning zu contextb_t durch app_x. Die ausführbare Datei app_x fungiert als Eintragspunkt für contextb_t. Der Ablauf kann wie folgt dargestellt werden:

Der Fall eines Domain-Übergangs ist in SELinux ziemlich häufig. Betrachten wir den vsftpd-Prozess, der auf unserem Server ausgeführt wird. Wenn es nicht läuft, können wir den Befehl + service vsftpd start + ausführen, um den Daemon zu starten.

Als nächstes betrachten wir den systemd-Prozess. Dies ist der Vorfahr aller Prozesse. Dies ist die Ersetzung des System V-Init-Prozesses und wird in einem Kontext von * init_t * ausgeführt. :

ps -eZ  | grep init
system_u:system_r:init_t:s0         1 ?        00:00:02 systemd
system_u:system_r:mdadm_t:s0      773 ?        00:00:00 iprinit

Der in der * init_t * -Domäne ausgeführte Prozess ist von kurzer Dauer: Er ruft die ausführbare Binärdatei + / usr / sbin / vsftpd + auf, die den Typ Kontext * ftpd_exec_t * hat. Wenn die ausführbare Binärdatei gestartet wird, wird sie selbst zum vsftpd-Daemon und wird in der Domäne * ftpd_t * ausgeführt.

Wir können den Domänenkontext der Dateien und Prozesse überprüfen:

ls -Z /usr/sbin/vsftpd

Zeigt uns:

-rwxr-xr-x. root root system_u:object_r:ftpd_exec_t:s0 /usr/sbin/vsftpd

Prozess überprüfen:

ps -eZ | grep vsftpd

Zeigt uns:

system_u:system_r:ftpd_t:s0-s0:c0.c1023 7708 ? 00:00:00 vsftpd

In diesem Fall führt der in der Domäne * init_t * ausgeführte Prozess eine Binärdatei vom Typ * ftpd_exec_t * aus. Diese Datei startet einen Daemon in der Domäne * ftpd_t *.

Dieser Übergang kann weder von der Anwendung noch vom Benutzer gesteuert werden. Dies wurde in der SELinux-Richtlinie festgelegt, die beim Systemstart in den Speicher geladen wird. Auf einem Nicht-SELinux-Server kann ein Benutzer einen Prozess starten, indem er zu einem leistungsstärkeren Konto wechselt (vorausgesetzt, er hat das Recht dazu). In SELinux wird ein solcher Zugriff durch vordefinierte Richtlinien gesteuert. Auch aus diesem Grund soll SELinux die obligatorische Zugriffskontrolle implementieren.

Der Domainwechsel unterliegt drei strengen Regeln:

  • Der übergeordnete Prozess der Quelldomäne muss über die Ausführungsberechtigung für die Anwendung verfügen, die sich zwischen beiden Domänen befindet (dies ist der entrypoint).

  • Der Dateikontext für die Anwendung muss als entrypoint für die Zieldomäne angegeben werden.

  • Die ursprüngliche Domain muss in die Zieldomäne übergehen dürfen.

Führen Sie im obigen Beispiel für den vsftpd-Daemon den Befehl "+ sesearch +" mit verschiedenen Schaltern aus, um festzustellen, ob der Daemon diesen drei Regeln entspricht.

Zunächst muss die Quelldomäne init_t über die Ausführungsberechtigung für die Entrypoint-Anwendung mit dem Kontext ftpd_exec_t verfügen. Also, wenn wir den folgenden Befehl ausführen:

sesearch -s init_t -t ftpd_exec_t -c file -p execute -Ad

Das Ergebnis zeigt, dass Prozesse in der Domäne init_t Dateien des Kontexts ftpd_exec_t lesen, Attribute abrufen, ausführen und öffnen können:

Found 1 semantic av rules:
  allow init_t ftpd_exec_t : file { read getattr execute open } ;

Als nächstes prüfen wir, ob die Binärdatei der Eintrittspunkt für die Zieldomäne ftpd_t ist:

sesearch -s ftpd_t -t ftpd_exec_t -c file -p entrypoint -Ad

Und tatsächlich ist es so:

Found 1 semantic av rules:
  allow ftpd_t ftpd_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ;

Und schließlich muss die Quelldomäne init_t über die Berechtigung verfügen, auf die Zieldomäne ftpd_t zu wechseln:

sesearch -s init_t -t ftpd_t -c process -p transition -Ad

Wie wir unten sehen können, hat die Quelldomäne diese Berechtigung:

Found 1 semantic av rules:
  allow init_t ftpd_t : process transition ;

Nicht definierte Domains

Als wir das Domänenkonzept einführten, verglichen wir es mit einer hypothetischen Blase um den Prozess herum: Etwas, das festlegt, was der Prozess kann und was nicht. Dies ist es, was den Prozess einschränkt.

SELinux verfügt auch über Prozesse, die in nicht definierten Domänen ausgeführt werden. Wie Sie sich vorstellen können, haben unbeschränkte Prozesse alle Arten von Zugriff auf das System. Auch dann ist dieser Vollzugriff nicht willkürlich: Der Vollzugriff ist auch in der SELinux-Richtlinie festgelegt.

Ein Beispiel für eine nicht definierte Prozessdomäne wäre unconfined_t. Dies ist dieselbe Domäne, in der angemeldete Benutzer standardmäßig ihre Prozesse ausführen. Wir werden in den folgenden Abschnitten über Benutzer und ihre Zugriffe auf Prozessdomänen sprechen.

Fazit

Wir haben heute hier einige sehr wichtige SELinux-Konzepte behandelt. Die Verwaltung des Datei- und Prozesskontexts ist das Herzstück einer erfolgreichen SELinux-Implementierung. Wie wir im nächsten und https://www.digitalocean.com/community/tutorials/an-einführung-in-selinux-on-centos-7-teil-3-benutzer im letzten Teil dieser Reihe sehen werden], gibt es Ein weiterer Teil des Puzzles bleibt: der SELinux-Benutzer.