Migliorare le prestazioni di PHP attivando la cache realpath

Uno dei problemi di performance che si possono riscontrare in PHP (in generale non solo per PHP 7) è il mancato uso della cache realpath quando si attiva open_basedir (e/o nelle versione più vecchie di PHP, safe_mode).
La realpath cache è una meccanismo che permette di memorizzare nella cache dei percorsi le posizioni di file/directory per ridurre al minimo la ricerca sul disco.

Il parametro open_basedir contiene una lista di cartelle, questa lista viene utilizzata per ricercare i file richiesti da uno script PHP. Se il file non è nelle cartelle indicate, PHP si rifiuterà di aprirlo. Vengono risolti anche i link simbolici (symlink) in modo da verificare che conducano ad una delle cartelle nella lista. Praticamente, si tratta di una meccanismo di sicurezza che permette di negare l’accesso al filesystem del sistema operativo.

Per attivare il parametro open_basedir è sufficiente inserire una cartella: per esempio open_basedir=”/var/www/webZ/”.

Quando un file viene richiesto viene lanciata una funzione lstat per ogni cartella che compone il percorso, questo è il tracciato dei controlli fatti per il file /var/www/webZ/web/wp-includes/pluggable.php

[pid 2908] lstat(“/var/www/webZ/web/wp-includes/pluggable.php”, {st_mode=S_IFREG|0644, st_size=84285, …}) = 0
[pid 2908] lstat(“/var/www/webZ/web/wp-includes”, {st_mode=S_IFDIR|0755, st_size=12288, …}) = 0
[pid 2908] lstat(“/var/www/webZ/web”, {st_mode=S_IFDIR|0711, st_size=4096, …}) = 0
[pid 2908] lstat(“/var/www/webZ”, {st_mode=S_IFDIR|0755, st_size=4096, …}) = 0
[pid 2908] lstat(“/var/www”, {st_mode=S_IFDIR|0755, st_size=4096, …}) = 0
[pid 2908] lstat(“/var”, {st_mode=S_IFDIR|0755, st_size=4096, …}) = 0
[pid 2908] stat(“/var/www/webZ/web/wp-includes/pluggable.php”, {st_mode=S_IFREG|0644, st_size=84285, …}) = 0

Se successivamente PHP avesse la necessità di aprire il file /var/www/webZ/web/wp-includes/pluggable-deprecated.php, verranno rivalutati tutti percorsi: /var/www/webZ/web/wp-includes, /var/www/webZ/web…

Se per comporre una singola pagina PHP vengono richiesti molti file e se il file è contenuto in una cartella molto “profonda” nell’albero del filesystem, potete facilmente vedere come la maggior parte delle operazioni eseguite dal sistema operativo per eseguire lo script siano lstat. Poter ridurre il numero di lstat, consente un notevole risparmio di tempo e l’aumento della velocità del vostro sito.

Come indicato precentemente, attivando il parametro open_basedir viene disattivata la realpath cache.
Per attivare la cache realpath occorre disattivare open_basedir ma ciò cosa comporta?

In pratica si consente ad uno script PHP di accedere a qualsiasi file sul filesystem, salvo permessi UNIX e ACL.
Se PHP viene eseguito con l’utente root, tutti i file possono essere letti, modificati, cancellati da uno script PHP.
Ne conviene che è opportuno eseguire PHP con un utente che possa accedere solo ai file contenuti nella sua cartella web e limitare l’accesso alle funzioni PHP (es. /usr/local/php)

Tuttavia è possibile contare su un’alternativa Realpath Turbo. Il tool consente, pur disabilitando open_basedir, di restringere la possibilità di accedere a file e cartelle.

Realpath Turbo può essere compilato e pacchettizzato sottoforma di pacchetto Debian o Ubuntu e installato sul proprio web server, con l’indicazione di disattivare qualsiasi funzione PHP che può essere usata per creare/manipolare collegamenti simbolici. Una delle precauzioni potrebbe essere quella di disattivare la funzione symlink nel file php.ini:
disable_functions = symlink,link

Realpath Turbo può essere trovato qui (https://github.com/Whissi/realpath_turbo), mentre la versione compatibile con PHP7 qua (https://github.com/Mikk3lRo/realpath_turbo)

La compliazione è abbastanza semplice, tuttavia richiede l’installazione di compilatori come gcc e php-dev…

$ tar -xaf realpath_turbo*
$ cd realpath_turbo*
$ phpize
$ ./configure
$ make
# make install

In alternativa si può procedere alla configurazione e compilazione su un sistema di sviluppo sul quale è installato gcc, devscripts, dh-make. Quindi va recuperato il pacchetto .deb.

$ tar -xaf realpath_turbo*
$ cd realpath_turbo*
$ mv realpath_turbo* realpath-turbo-1.3
$ phpize
$ ./configure
$ dh_make -s -e example@example.com -n -c gpl
$ sudo debuild binary

A questo punto nella cartella che contiene la directory realpath-turbo-1.3 ci sarà un pacchetti .deb (realpath-turbo_1.3_amd64.deb)

Una volta installato il pacchetto si può modificare il file php.ini del sito web inserendo questi valori:

extension=turbo_realpath.so
realpath_cache_security = 1
realpath_cache_basedir = “/var/www/webZ/:/usr/share/php”
open_basedir = “”

extension=turbo_realpath.so è necessaria per indicare di caricare l’estensione di Realpath Turbo.
realpath_cache_security = 1 significa che Realpath Turbo è attivo, se fosse 0 sarebbe disattivato.
Nella definizione di realpath_cache_basedir vanno inserite le cartelle a cui viene concesso l’accesso.
open_basedir = “” serve a disattivare open_basedir
A questo punto potremmo verificare nuovamente il tracciato di una richiesta PHP e vedere come le cose siano migliorate.

L’attivazione della cache RealPath consente di utilizzare strumenti come Opcache, Memcache e APC in modo più efficiente.