Apache con ExecCGI y FPM

Creado: Septiembre 22, 2022 - Actualizado: Octubre 8, 2022

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.

Artículos relacionados