Navigation

Start Projekte Tutorials & Texte Archiv

Unternavigation

Admintools in PHP

Dieses Script beschäftigt sich mit folgender Problematik:
Wie kann man ein Admintool in PHP realisieren, ohne den Webserver bzw. dessen PHP-Instanz als Rootprozess laufen zu lassen?

PHP läuft normalerweise mit den Privilegien des Webservers. Über verschiedenste Wrapper kann man dies ändern und bspw. den virtuellen Host des Admintools unter UID 0, also Root, laufen lassen. Aus verständlichen Gründen sollte man darauf allerdings verzichten.

Gehen wir davon aus, dass der Apache unter www-data:www-data läuft. Wir stehen nun vor dem Problem, dass unser Benutzer keine administrativen Tätigkeiten ausführen kann. Nehmen wir aber an, dass unser Tool die Konfigurationsdateien des Apache ändern soll, so müsste er sie beschreiben können. Eine Lösung besteht darin, die Dateiberechtigungen entsprechend zu ändern. Aber gerade wenn man Shelluser hat, sollte man davon absehen.

Eine je nach Script vergleichsweise sichere Lösung kann man durch das Frontend-Backend-Prinzip erreichen. Den grundlegenden Ablauf kann man sich so vorstellen:
  1. Der Benutzer loggt sich im Frontend ein,
  2. wählt einen Menüpunkt, z.B. "Subdomains",
  3. gibt dort den Namen der Subdomain und das Zielverzeichnis ein und
  4. sendet dem Server seine Eingabe.
  5. Das Frontend speichert die Eingaben ab.
  6. Das vom Cron-Daemon als Root aufgerufene Backend arbeitet die Aufträge ab.
Das Backend kann man auf verschiedenen Wegen realisieren.
Vorschlag 1
Eine Möglichkeit sieht so aus, dass das Backend eine Kommandozeilenanwendung ist. Das Frontend kann seine Daten z.B. in einer SQL-Tabelle abspeichern. In dieser sind z.B. Operation-ID, User, Aktion und Optionen angegeben. Gemäß der Aktion führt das Backend die Operationen aus und löscht den Auftrag. Der Vorteil besteht darin, dass der Managementserver nicht mit dem betroffenen Server (Webserver, Mailserver usw.) identisch sein muss.
Vorschlag 2
Man benötigt ein Verzeichnis außerhalb des DocumentRoots, aber innerhalb des Open_Basedirs. Die Umgebung sieht also etwa so aus:
URL: http(s)://admin.{foo}.{bar}
DocumentRoot: /var/www/admin/www
Ablage: /var/www/admin/queue
Open_Basedir: /var/www/admin

Im Verzeichnis queue befindet sich eine Datei "cron", die Root gehört und die Berechtigung hat 700 hat.
Diese Datei hat folgenden Inhalt:
#!/bin/sh
find . -name \*.sh | while read file
do
  chmod a+x ${file}
  ${file}
  rm ${file}
done

Das Frontend schreibt nun simple Shellscripts in diesen Ordner. Wenn sich jemand eine Weiterleitung für QMail angelegt hat, erstellt das Frontend eine Datei im Ordner queue mit folgendem Inhalt:
echo "&{Benutzer}@{Domain}" >> /var/qmail/alias/.qmail-{Name des virtuellen Hosts}-{Benutzer}
Die Datei "cron" wird letzten Endes als Cronjob ausgeführt. Auf diese Art kann man PHP leicht mit der Shell verknüpfen, es gibt aber folgendes zu beachten:
  • Dateinamen dürfen nicht doppelt vorkommen. Das lässt sich durch Namen wie "{Domain}-{Aktion}-{zufällige mehrstellige Nummer}" erreichen.
  • Die Benutzereingaben müssen streng geprüft und escapt werden.