Wie kann ich mit SELinux PHP-Skripte einschränken?

8

Ich möchte verschiedene PHP-Anwendungen auf meinem SL6.4-Webserver (RHEL 6.4-Neuerstellung) unterteilen, damit sie nicht auf die Daten der anderen zugreifen können. Es scheint, dass SELinux dazu in der Lage sein könnte, aber ich bin mir bei den Details nicht sicher. Meine Frage besteht aus zwei Teilen:

  1. Wie verwaltet SElinux PHP-Skripte, die im Apache-Prozess mit mod_php ausgeführt werden? Tritt der Prozess beim Ausführen des PHP-Skripts irgendwie in den Skriptkontext ein oder funktioniert dies nur, wenn Skripte über CGI oder FastCGI außer Betrieb ausgeführt werden? Wenn es zum Ausführen des PHP-Skripts in einen Skriptkontext übergeht, was verhindert, dass ein PHP-Fehler einen Übergang zurück zum Haupt-httpd-Kontext auslöst? Wenn ich eine alternative PHP-Bereitstellungsmethode benötige, wäre das gut zu wissen.
  2. Wie kann ich Skripte / Anwendungen trennen, damit TinyTinyRSS nicht auf Dinge zugreifen kann, die OpenCloud gehören? Es sieht so aus, als ob ich dazu in der Lage sein sollte, indem ich deaktiviere httpd_unifiedund separate Kontexte httpd_ttrss_*und httpd_opencloud_*Sätze von Kontexten parallel zu httpd_user_foound bereitstelle httpd_sys_foo. Angesichts der Anzahl der Apps, die ich verwenden kann, kann es sogar ausreichen, die Unterscheidung zwischen System und Benutzer ohne neue Kontexte zu verwenden. Ich habe jedoch nicht viel Dokumentation darüber gefunden, welche Auswirkungen das Ausschalten genau httpd_unifiedhat oder wie verschiedene HTTP-Kontexte eingerichtet werden. Besonders bei PHP-Skripten läuft via mod_php.

Ich kann problemlos neue SELinux-Richtlinienmodule erstellen, möchte jedoch eine Dokumentation, die darauf hinweist, was die neue Richtlinie bewirken muss und wie sie sich gut in die SELinux-Richtlinie integrieren lässt.

Wenn es ein verlorener Grund ist, diese Trennung nur mit SELinux zu versuchen, und ich separate httpds in verschiedenen Kontexten oder möglicherweise sogar LXC-Containern hochfahren muss, wäre dies ebenfalls eine nützliche Antwort.

Michael Ekstrand
quelle
Dies kann von den Mitteln abhängen, mit denen Sie PHP ausführen möchten. Sie haben 'mod-php' markiert, wollten aber nur bestätigen, dass dies die Methode ist, die Sie verwenden möchten.
Matthew Ife
@MIfe Ich verwende derzeit mod_php, bin aber offen für den Wechsel zu einer anderen Bereitstellungsmethode, wenn dies einfacher ist.
Michael Ekstrand

Antworten:

5

Der beste Weg, um diese Trennungsstufe zu erreichen, besteht darin, keine Typübergänge, sondern Kategorie- / MCS-Übergänge zu verwenden. Dies verhält sich ein wenig wie die svirtImplementierung in libvirt KVM.

OK, das erste, was Sie tun müssen, ist ein httpd-Modul namens herunterzuladen mod_selinux. Es schwebt schon seit einiger Zeit in den Fedora-Repos herum, hat es aber leider nie wirklich in die EL6-Systeme geschafft.

In jedem Fall können Sie das Paket aus Fedora-Quellen neu erstellen. Ich habe dies auf einer Fedora-Maschine gemacht, aber Sie können das gleiche Paket einfach von einem Spiegel herunterladen. Ich habe F16 als Basis verwendet, während es läuft httpd-2.2.

yumdownloader --source mod_selinux --releaserver=16
...
mod_selinux-2.2.2454-3.fc15.src.rpm                        |  23 kB   00:00

Wenn Sie es heruntergeladen haben, erstellen Sie es erneut auf Ihrer EL6-Box.

rpmbuild --rebuild mod_selinux-2.2.2454-3.fc15.src.rpm
...
Wrote: /home/build/rpmbuild/RPMS/x86_64/mod_selinux-2.2.2454-3.el6.x86_64.rpm

Installieren Sie schließlich das Modul.

rpm -i /home/build/rpmbuild/RPMS/x86_64/mod_selinux-2.2.2454-3.el6.x86_64.rpm

Das RPM installiert ein Modul, für httpddas Sie benötigen, sowie eine Richtlinie, für httpddie dies ebenfalls erforderlich ist.

Die Datei für dieses Modul ist in installiert /etc/httpd/conf.d/mod_selinux.conf.

Der erste Schritt in diesem Prozess besteht darin, die Anzahl der Kategorien zu erhöhen, unter denen der httpd-Hauptprozess ausgeführt wird, damit untergeordnete Threads erstellt werden können, die den richtigen Bereich umfassen. In der Datei ändern:

selinuxServerDomain     *:s0

Zu

selinuxServerDomain     *:s0-s0:c0.c1023

Jetzt müssen Sie jedem virtuellen Host in Apache eine Kategorie zuweisen. Dies erfolgt durch Hinzufügen einer Zeile wie im folgenden Beispiel selinuxDomainVal.

<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/host1
    ServerName host1.virtual
    selinuxDomainVal *:s0:c0
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/host2
    ServerName host2.virtual
    selinuxDomainVal *:s0:c1
</VirtualHost>

Als Nächstes kennzeichnen Sie im Dokumentstamm für jeden Host die Dokumentwurzeln in derselben Kategorie wie die in der httpd-Konfiguration angegebenen.

chcon -R -l s0:c0 /var/www/vhosts/host1
chcon -R -l s0:c1 /var/www/vhosts/host2

Wenn Sie möchten, dass die Kennzeichnung bei einer erneuten Kennzeichnung des Systems berücksichtigt wird, sollten Sie auch die lokale Richtlinie aktualisieren!

semanage fcontext -a -t httpd_sys_content_t -r s0-s0:c0 '/var/www/vhosts/host1(/.*)?'
semanage fcontext -a -t httpd_sys_content_t -r s0-s0:c1 '/var/www/vhosts/host2(/.*)?'

Und das ist es! Es ist unmöglich, das Stammverzeichnis Ihres Dokuments zu verlassen und jetzt in anderen zu suchen.

Matthew Ife
quelle
2
Beachten Sie, dass mod_selinuxdies keinen vollständigen Schutz vor PHP-Fehlern bietet. Wenn ein Angreifer nach dem Ausnutzen eines virtuellen Hosts mit eingeschränktem Kontext eine kontrollierte Speicherbeschädigung ausführen kann, kann er möglicherweise Code in den Apache-Prozess einfügen, der im Standard-httpd-Kontext ausgeführt wird, oder Deaktivieren Sie diese Option mod_selinuxfür nachfolgende Anforderungen, die vom selben Arbeitsprozess verarbeitet werden. Caches wie APC werden auch von allen virtuellen Hosts gemeinsam genutzt. Wenn dies ein Problem darstellt, ist eine vollständige Prozesstrennung erforderlich (Verwendung von CGI oder FastCGI für PHP oder sogar separate httpd-Instanzen, wenn Sie auch vor httpd-Fehlern schützen möchten).
Sergey Vlasov
Threads können nur 'typgebundene' Übergänge ausführen, man kann nicht 'wirklich' in eine andere Begrenzung übergehen, so dass dies vollständig gültig ist. Trotzdem kann ein Angreifer selbst unter den oben beschriebenen Umständen Apache nur innerhalb seiner Selinux-Begrenzung manipulieren.
Matthew Ife
@ SergeyVlasov Danke für das Heads Up. Das primäre Bedrohungsmodell, um das ich mir Sorgen mache, ist jemand, der Fehler in einer PHP-Anwendung ausnutzt, um die Daten oder die Konfiguration einer anderen zu manipulieren. Fehler in PHP selbst sind besorgniserregend, aber beim Abwägen von Konfigurationsschwierigkeiten und Schutz scheint diese Lösung das zu erreichen, was ich brauche.
Michael Ekstrand
@MatthewIfe schätze die Antwort sehr, große Hilfe. Ich wollte nur darauf hinweisen, dass wir für alle anderen, die sich das ansehen, den zusätzlichen Schritt unternehmen müssen, eine benutzerdefinierte Richtlinie zu erstellen, um dem Zugriff auf den httpd-Dienst den erforderlichen Zugriff zu ermöglichen setcurrent. Ich habe unten eine zusätzliche Antwort mit Details hinzugefügt.
Oucil
1

Ich weiß, dass diese Frage 7 Jahre alt ist, aber die Antwort von @MatthewIfe oben war instrumental, erforderte aber ein paar zusätzliche Schritte. Wir verwenden CentOS8, das immer noch nicht im Lieferumfang enthalten ist. Die mod_selinuxobige Antwort war also perfekt, um es zu installieren.

Nach der Installation und nach einer korrekten Einrichtung konnte Apache jedoch die AVC-Tests nicht bestehen und konnte nicht gestartet werden. Die Fehler in dem /var/log/httpd/error.log, /var/log/messagesund /var/log/audit/audit.logwaren nicht sehr hilfreich.

Am Ende musste ich zwei zusätzliche Dienstprogramme installieren, mit denen ich die Selinux-AVC-Fehler beheben konnte. Dies bedeutete, dass ich eine benutzerdefinierte Richtlinie erstellen musste, um dem httpdDienst den Zugriff auf den setcurrentBefehl unter Selinux zu ermöglichen.

Die Lösung finden Sie hier: Apache vhost-Berechtigungstrennung mithilfe von SELinux-Kontexten unter CentOS8

Hoffe, das hilft allen anderen, darüber zu stolpern.

oucil
quelle
1
Die Politik hat sich in 7 Jahren stark weiterentwickelt. Ein großes Lob für die Aktualisierung der Antwort.
Matthew Ife