User Tools

Site Tools


doc:appunti:linux:sa:apache_php_optimization

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
doc:appunti:linux:sa:apache_php_optimization [2025/02/28 09:43] – [proxy_fcgi e php-fpm] niccolodoc:appunti:linux:sa:apache_php_optimization [2025/03/31 10:42] (current) – [Metodo chroot] niccolo
Line 8: Line 8:
 </code> </code>
  
-===== MPM prefork =====+I moduli disponibili installati dal pacchetto **apache2** sono **event**, **prefork** e **worker**. 
 + 
 +Per una configurazione Apache + PHP-FPM, il modulo MPM event è la scelta preferita. Offre migliori prestazioni, scalabilità ed efficienza gestendo le connessioni in modo asincrono, mentre PHP-FPM elabora separatamente gli script PHP. 
 + 
 +===== Modulo MPM prefork e mod-php =====
  
 Con una installazione standard Debian di Apache e PHP è probabile che sia in uso il modulo **[[https://httpd.apache.org/docs/current/mod/prefork.html|prefork]]**. Questo modulo prevede che ogni richiesta HTTP venga eseguita da un singolo thread e questo garantisce che funzionino correttamente anche le librerie //non-thread-safe//, come è il PHP. Un processo centrale gestisce il pool di istanze Apache che vengono attivate. Con una installazione standard Debian di Apache e PHP è probabile che sia in uso il modulo **[[https://httpd.apache.org/docs/current/mod/prefork.html|prefork]]**. Questo modulo prevede che ogni richiesta HTTP venga eseguita da un singolo thread e questo garantisce che funzionino correttamente anche le librerie //non-thread-safe//, come è il PHP. Un processo centrale gestisce il pool di istanze Apache che vengono attivate.
Line 17: Line 21:
   * **/etc/apache2/mods-enabled/php8.2.load**   * **/etc/apache2/mods-enabled/php8.2.load**
  
-In questo modo il modulo PHP viene caricato in ogni processo Apache, anche se il server deve fornire pagine statiche senza PHP. Inoltre il fatto che PHP sia //not thread safe//, costringe ad usare il MPM //prefork//, che è la configurazione più lenta possibile.+In questo modo il modulo PHP viene caricato in ogni istanza del processo Apache, anche se il server deve fornire pagine statiche senza PHP. Inoltre il fatto che PHP sia //not thread safe//, costringe ad usare il MPM //prefork//, che è la configurazione più lenta possibile. 
 + 
 +La configurazione del modulo è in **/etc/apache2/mods-available/mpm_prefork.conf**. Ad esempio è possibile aumentare il numero massimo di workers attivabili, ecc: 
 + 
 +<file> 
 +StartServers            5 
 +MinSpareServers         5 
 +MaxSpareServers         10 
 +MaxRequestWorkers       150 
 +MaxConnectionsPerChild 
 +</file>
  
-===== proxy_fcgi e php-fpm =====+===== Modulo MPM event, proxy_fcgi e php-fpm =====
  
 Secono le **[[https://cwiki.apache.org/confluence/display/httpd/php|raccomandazioni più recenti]]** tuttavia il modo più efficiente per eseguire Apache + PHP è tramite il modulo Apache **proxy_fcgi** che si interfaccia con il motore PHP tramite **php-fpm** (PHP FastCGI Process Manager). Secono le **[[https://cwiki.apache.org/confluence/display/httpd/php|raccomandazioni più recenti]]** tuttavia il modo più efficiente per eseguire Apache + PHP è tramite il modulo Apache **proxy_fcgi** che si interfaccia con il motore PHP tramite **php-fpm** (PHP FastCGI Process Manager).
Line 39: Line 53:
 </code> </code>
  
-Con il comando+È necessario anche attivare la configurazione per collegare Apache al motore php-fpm, eseguendo il comando:
  
 <code> <code>
Line 45: Line 59:
 </code> </code>
  
-viene creato il link **/etc/apache2/conf-enabled/php8.2-fpm.conf**. Questa configurazione indica ad Apache come gestire tutti i file PHP, cioè interagendo con l'engine PHP tramite il socket **/run/php/php8.2-fpm.sock**.+In questo modo viene creato il link **/etc/apache2/conf-enabled/php8.2-fpm.conf**. Questo file indica ad Apache come gestire i file PHP, cioè interagendo con l'engine PHP tramite il socket **/run/php/php8.2-fpm.sock**.
  
-Per sicurezza verifichiamo che il modulo php sia disabilitato e disinstalliamo definitivamente il pacchetto:+Per sicurezza verifichiamo che il modulo legacy mod-php sia disabilitato e disinstalliamo definitivamente il pacchetto:
  
 <code> <code>
Line 59: Line 73:
 systemctl status php8.2-fpm systemctl status php8.2-fpm
 </code> </code>
 +
 +Infine si cambia il modulo MPM da prefork a event:
 +
 +<code>
 +a2dismod mpm_prefork
 +a2enmod mpm_event
 +systemctl restart apache2.service
 +</code>
 +
 +Controllare che le pagine PHP siano correttamente interpretate e che il modulo MPM event sia effettivamente in uso:
 +
 +<code>
 +apachectl -V | grep 'Server MPM'
 +Server MPM:     event
 +</code>
 +
  
 === Altri moduli Apache consigliati === === Altri moduli Apache consigliati ===
Line 135: Line 165:
   </IfModule>   </IfModule>
 </file> </file>
 +
 +===== Segregazione VirtualHost =====
 +
 +Su un host che ospita più di un VirtualHost potrebbe essere desiderabile isolare il PHP di un VirtualHost dai file degli altri VirtualHost ed anche dai file dell'intero sistema. Dal punto di vista della sicurezza ad esempio non è bene che da PHP sia possibile fare l'''fopen()'' di file tipo **/etc/passwd** oppure del file **wp-config.php** del Wordpress installato su un altro VirtualHost.
 +
 +Essenzialmente si può agire con un **chroot** per processo PHP oppure con la direttiva **open_basedir** del PHP.
 +
 +Il primo metodo è quello formalmente più corretto e sicuro, in quanto il processo PHP sarebbe effettivamente in esecuzione in un ambiente chroot e sarebbe il sistema operativo stesso a impedirgli di accedere fuori dalla propria DocumentRoot. Tuttavia questo metodo comporta **notevoli problemi** perché ad esempio impedisce l'**accesso alle librerie** PHP o JavaScript installate a livello di sistema.
 +
 +Il metodo che utilizza la direttiva **open_basedir** invece è più flessibile, ma affida la sicurezza all'assenza di bug nell'implementazione del linguaggio PHP.
 +
 +==== Metodo chroot ====
 +
 +Supponiamo che la DocumentRoot di un sito sia **/var/www/html/site.example.org/www/**, queste sono le direttive da aggiungere al file di configurazione **/etc/php/7.4/fpm/pool.d/pool.d.include/site.example.org.conf**:
 +
 +<file>
 +[site.example.org]
 +user = site-example-org
 +group = site-example-org
 +
 +; This PHP-FPM instance is chrooted.
 +chroot = /var/www/html/site.example.org
 +chdir = /www
 +; Values set here with php_admin_value belong to this pool only.
 +; doc_root: (without chroot would be empty or the Apache DocumentRoot).
 +php_admin_value[doc_root] = /www
 +; cgi.fix_pathinfo: this is mandatory to let the chroot works.
 +; See https://www.php.net/manual/en/ini.core.php#ini.cgi.fix-pathinfo
 +php_admin_value[cgi.fix_pathinfo] = 0
 +</file>
 +
 +In questo modo si ha un processo **php-fpm** che gira con le credenziali di //user// e //group// indicate e che è chrooted nella directory indicata.
 +
 +Purtroppo questa soluzione impedisce il corretto funzionamento delle librerie PHP, ad esempio il pacchetto **php-mail** installa i propri file in **/usr/share/php/** ed è impossibile eseguire il comando ''require_once "Mail.php";''.
 +
 +Vedere la discussione **[[https://serverfault.com/questions/733230/apache-file-not-found-after-setting-up-php-fpm-chroot|Apache: "File Not Found" after setting up php-fpm chroot]]**.
 +
 +==== Metodo open_basedir ====
 +
 +Con la direttiva PHP **open_basedir** si pone un limite a tutte le funzioni PHP che aprono file dal filesystem (ad esempio ''include'' o ''fopen()''). Il manuale PHP tuttavia avverte: //**Caution** open_basedir is just an extra safety net, that is in no way comprehensive, and can therefore not be relied upon when security is needed//.
 +
 +Ecco quindi come configurare l'istanza PHP-FPM di un VirtualHost nel file **/etc/php/7.4/fpm/pool.d/site.example.org.conf**:
 +
 +<file>
 +[site.example.org]
 +user = site-example-org
 +group = site-example-org
 +php_admin_value[open_basedir] = /var/www/html/site.example.org:/usr/share/phpmyadmin:/usr/share/doc/phpmyadmin:/etc/phpmyadmin:/var/lib/phpmyadmin:/usr/share/php:/usr/share/javascript:/tmp
 +</file>
 +
 +Come si vede è necessario avere l'accortezza di includere tutte le directory delle estensioni installate a livello di sistema. Nell'esempio sopra è compreso il pacchetto **phpMyAdmin**, le varie **librerie PHP** e **JavaScript**. Anche la directory **/tmp** potrebbe essere utilizzata per la creazione di file temporanei, ecc.
  
 ===== Web Resources ===== ===== Web Resources =====
  
   * **[[https://cwiki.apache.org/confluence/display/httpd/php|Running PHP on Apache httpd]]**   * **[[https://cwiki.apache.org/confluence/display/httpd/php|Running PHP on Apache httpd]]**
 +  * **[[https://cwiki.apache.org/confluence/display/httpd/PHP-FPM|High-performance PHP on apache httpd 2.4.x using mod_proxy_fcgi and php-fpm]]**
 +  * **[[https://cwiki.apache.org/confluence/display/HTTPD/Php-fcgid|Running PHP with fcgid]]** - :!: Se si esegue Apache 2.4 è preferibile il metodo php-fpm.
   * **[[https://computingpost.medium.com/php-8-2-how-to-install-on-debian-11-or-10-74bb37b281d4|PHP 8.2 — How to Install on Debian 11 or 10]]**   * **[[https://computingpost.medium.com/php-8-2-how-to-install-on-debian-11-or-10-74bb37b281d4|PHP 8.2 — How to Install on Debian 11 or 10]]**
   * **[[https://www.alessioligabue.it/blog/apache-ssl-php-fpm-debian|Installare Apache, HTTPS e PHP-FPM in Debian 12]]**   * **[[https://www.alessioligabue.it/blog/apache-ssl-php-fpm-debian|Installare Apache, HTTPS e PHP-FPM in Debian 12]]**
  
doc/appunti/linux/sa/apache_php_optimization.1740732214.txt.gz · Last modified: 2025/02/28 09:43 by niccolo