Webseite mit nginx einem Nutzer assignen
Apache zu betreuen lehrt: AssingUserID XY Gruppe Z – ein einfaches, solides System, dazu noch ein paar Chroot-Verzeichnisse und die Kundenkonten sind fertig für verschiedene Webseiten. Auf nginx umzustellen, ist ein Bruch in der Denke, aber relativ schnell möglich. Applikationen wie WordPress laufen problemlos und auch andere Systeme lassen sich leicht damit umsetzen. Doch eine Sache hat mich bei Nginx immer gestört: Das fehlende AssignUserId von Apache. Nach über 3 Monaten mit nginx bin ich heute auf die Lösung gestoßen.
Das Ausgangsszenario
Auf meinem Server habe ich ein paar Kundenkonten, so dass ein paar Webseiten auch sicherheitstechnisch von meinen abgekoppelt sind. Die Umsetzung war bisher fast wie bei Apache: Es werden Kundenverzeichnisse angelegt, die root:root gehören. Darin werden jeweils Ordner für data und html angelegt, die ab dieser Ebene einem bestimmten Linux-Nutzer in der Gruppe www-data gehören. Kurzum diese Verzeichnisse wurden nach dem Standardverfahren gechrooted.
Anschließend bekamen alle Dateien und Ordner die Schreibrechte auf die Gruppe, damit z.B. WordPress automatisch aktualisieren konnte und Dateiänderungen über SFTP möglich waren. Doch dieses Szenario hatte neben Sicherheitsbedenken auch eine Schwäche: Nach und nach wurden automatisch aktualisierte Pluginverzeichnisse mit www-data:www-data angelegt, die dann nicht mehr für den SFTP-Benutzer editierbar waren.
Die Lösung
Per Zufall stieß ich darauf, dass nicht nginx die treibende Kraft in diesem Szenario ist, sondern der FPM Worker bei PHP. Bei nginx gibt es keine Möglichkeit einem Nutzer eine bestimmte Domain zu assignen, so dass dieser Webserverprozess mit diesem Nutzer ausgeführt wird, sondern es gibt nur einen nginx Nutzer, der alle Prozesse ausführt. Aber da alle PHP-Anwendungen über FPM zu nginx geschickt werden – ähnlich wie bei einer Datenbankverbindung – lässt sich dort ein User assignen. Damit ist das Problem gelöst, denn nun laufen alle PHP-Prozesse einer bestimmten Domain mit einem vorher festgelegtem Nutzer und damit funktionieren Webanwendungen ohne dass Schreibrechte auf die Gruppe gesetzt werden müssen.
Voraussetzung ist allerdings, dass nginx mit der Gruppe www-data läuft und alle SFTP-Nutzer in dieser Gruppe sind.
Umsetzung
Bei Debian / Ubuntu liegen die Einstellungsdateien für fpm unter /etc/php5/fpm/pool.d/. Hier liegt bereits eine www.conf, die ja bereits eingestellt wurde: Dort wird festgelegt, auf welcher Adresse FPM lauscht, welcher Nutzer und welche Gruppe diesen Prozess mit welchen Berechtigungen ausführen dürfen etc. Da über FPM das komplette pool.d-Verzeichnis eingebunden wird, lassen sich beliebig viele Konfigurationen für diese PHP Prozesse erstellen und in jeder einzelnen Datei lassen sich ein anderer Nutzer und eine andere Gruppe definieren – PHP Einstellungen z.B. auch, um bestimmte PHP Dienste für manche Domains / Kunden zu verbieten.
Das ist eine Beispielconf-Datei, die unter pool.d abgelegt wird. Zwei Dinge sind wichtig zu wissen:
- Für jede neue Conf muss ein anderer Port / Socket definiert werden, d.h. für jede neue Conf wird der Listen-Port erhöht (z.B. auf 9001, 9002 etc.).
- Dieser Listen-Port muss dann natürlich in nginx auch bei der php location bei der jeweiligen Kundendomain gesetzt werden.
Erst dann können die PHP-Prozesse getrennt voneinander funktionieren. In Kürze zusammengefasst: Linux Nutzer anlegen, Webseitenverzeichnis(se) diesem Nutzer assignen, PHP Prozessdatei mit anderem Listen-Port anlegen, den Listen-Port bei nginx in der jeweiligen Domain anpassen. Alles neustarten und fertig.