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.