Web-Root und temporäre Dateien auf restriktivem Dateisystem

Web-Root noexec

In diesem Artikel beschreibe ich das Anlegen und Einbinden eines Images auf Basis des ext2-Dateisystems.
Dieses möchte ich als Web-Root sowie Verzeichnis für temporäre Dateien meiner PHP-Installation verwenden.
Eingebunden wird das Dateisystem unter Angabe diverser Sicherheitsoptionen, die etwa die Ausführung von Dateien unterbindet. Mehr dazu im Verlauf…

Mit einer Blockgröße von 1024 Byte, erstelle ich 5242880 Blocks gefüllt mit „0en“ in einem Image, das künftig die virtuelle Festplatte ist. Multipliziert erhalte ich 5120MB, 5GB:

dd if=/dev/zero of=/usr/local/noexec.img bs=1024 count=5242880

Nun erstelle ich ein einfaches ext2 Dateisystem, die Vorteile von ext3,4 sind nicht relevant. Journaling übernimmt bereits das übergeordnete Dateisystem, falls aktiv.

mke2fs /usr/local/noexec.img

Die Warnung mit „y“ bestätigen:

/usr/local/noexec.img is not a block special device.
Proceed anyway? (y,n) y

Da es sich nicht um ein „block device“ handelt, ist das okay.
Um das Dateisystem zukünftig automatisch und unter Angabe der Sicherheitsoptionen „nodev“, „nosuid“ und „noexec“ einzubinden, wird nun ein Eintrag in die Datei „/etc/fstab“ erstellt.
„loop“ wird benötigt, da das „Gerät“ auf sich selbst zurück zeigt, ergo kein eigenständiges Gerät ist.

echo "/usr/local/noexec.img /mnt/noexec ext2 loop,nodev,nosuid,noexec 0 0" >> /etc/fstab

Zu den „noXYZ“-Optionen eine kleine Erklärung:

  • nodev: Untersagt den Zugriff auf „device nodes“ aus – üblicherweise – „/dev“
  • noexec: Untersagt die Ausführung von Dateien
  • nosuid: Untersagt „setuid“, um Privilegien abzuändern

Zuerst erstelle ich das Zielverzeichnis, in welches das Dateisystem sofort eingebunden wird („mount -a“), anschließend wird die Verzeichnisstruktur erstellt:

mkdir /mnt/noexec
mount -a
mkdir /mnt/noexec/{tmp,www}

Nun kann eine rekursive Kopie des aktuellen Web-Roots angelegt werden. Darauf folgen Anpassungen der Rechte/Besitzer, in diesem Fall gehört das Web-Root dem Benutzer „www-data“:

cp -R /altes/www-verzeichnis/* /mnt/noexec/www
chown -R www-data: /mnt/noexec/www/
chmod 777 /mnt/noexec/tmp

Wird ein FPM-Worker für PHP eingesetzt, kann in der jeweiligen Konfiguration, etwa „/etc/php5/fpm/pool.d/www.conf“, Folgendes eingefügt werden. Diese Einträge haben gegenüber jenen via „php.ini“ höhere Priorität:

php_admin_value[open_basedir] = /mnt/noexec
php_admin_value[upload_tmp_dir] = /mnt/noexec/tmp
php_admin_value[session.save_path] = /mnt/noexec/tmp
php_admin_value[sys_temp_dir] = /mnt/noexec/tmp
php_admin_value[disable_functions] = exec,system,passthru,shell_exec,popen,escapeshellcmd,proc_open,proc_nice,ini_restore

Oder direkt in der Konfiguration des entsprechenden PHP-Moduls, z.B. „/etc/php5/cgi/php.ini“ oder „/etc/php5/cli/php.ini“:

open_basedir = /mnt/noexec
upload_tmp_dir = /mnt/noexec/tmp
session.save_path = /mnt/noexec/tmp
sys_temp_dir = /mnt/noexec/tmp
disable_functions = exec,system,passthru,shell_exec,popen,escapeshellcmd,proc_open,proc_nice,ini_restore

„disable_functions“ beinhaltet Funktionen, die zur Auführung von Befehlen benutzt werden können. Diese sollten generell deaktiviert werden.
Zudem hat „open_basedir“ keinen Einfluss auf den Pfad von Binaries, die etwa durch exec(„/bin/ls“) ausgeführt werden!
Auch befindet sich „ls“ nicht auf dem abgesicherten Dateisystem, weshalb die Ausführung nicht blockiert würde.

Zum Abschluss den Web-Server auf das neue Web-Root „/mnt/noexec/www“ zeigen lassen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.