Apache con ExecCGI y FPM
Una simple receta con notas de como se debe configurar un Virtual Host con Apache para que ejecute CGIs y PHP.
Esta configuración de Apache se realizo bajo Ubuntu 22.04 con el modulo de proxy_fcgi , setenvif y cgid. El modulo cgid se habilita cuando nuestro MPM es event mientras que cuando ejecutamos prefork el modulo a utilizar es cgi.
En Ubuntu se habilita o deshabilita el modulo mediante el comando: a2enmod cgi{d} dependiendo del MPM a utilizar. Para conocer mas sobre estos comandos a2enmod/a2dismod pueden visitar el siguiente enlace. Para PHP-FPM puede que deban ejecutar a2enconf y pueden leer mas sobre esto en este otro enlace.
Estos módulos se deben habilitar si nuestro MPM es event , esto se puede verificar mediante:
sudo apachectl status |grep -i 'Server MPM:'
La configuración para Apache sera la siguiente:
<VirtualHost *:80>
ServerAdmin alberto@localhost.barrahome.org
ServerName localhost.barrahome.org
DocumentRoot /home/alberto/public_html
DirectoryIndex index.php index.html
ErrorLog ${APACHE_LOG_DIR}/error-localhost.barrahome.org.log
CustomLog ${APACHE_LOG_DIR}/access-localhost.barrahome.org.log combined
<Directory />
Options -FollowSymLinks +SymLinksIfOwnerMatch
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/localhost.barrahome.org.sock|fcgi://localhost/"
</FilesMatch>
<IfModule mod_alias.c>
<IfModule mod_cgi.c>
Define ENABLE_USR_LIB_CGI_BIN
</IfModule>
<IfModule mod_cgid.c>
Define ENABLE_USR_LIB_CGI_BIN
</IfModule>
<IfDefine ENABLE_USR_LIB_CGI_BIN>
ScriptAlias /cgi-bin/ /home/alberto/public_html/cgi-bin/
<Directory "/home/alberto/public_html/cgi-bin/">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Require all granted
</Directory>
</IfDefine>
</IfModule>
</VirtualHost>
Tengan en cuenta que estoy utilizando PHP-FPM con un pool dedicado localhost.barrahome.org.sock. Los permisos para /home y para /home/alberto son de ejecución.
Aquí el script de Perl el cual he creado para la prueba:
#!/usr/bin/perl
use strict;
use warnings;
print "Content-type: text/html\n\n";
print "Hello World";
print "<pre>\n";
my $key;
foreach $key (sort keys(%ENV)){
print "$key = $ENV{$key}<p>";
}
print "</pre>";
Algo importante, se puede aplicar +ExecCGI directamente a /home/alberto/public_html y evitar tener que utilizar cgi-bin.
NOTA: Quiero destacar que utilizar SymLinksIfOwnerMatch en el caso de ser requerido ayuda también a prevenir ataques del tipo Symlink Attack. En PHP esto se previne mediante la configuración del valor open_basedir.