Apache con ExecCGI y FPM

Escrito el 2022-09-22 por Alberto Ferrer
Tiempo de lectura: 2 minuto(s)
Etiquetas: apache execcgi php-fpm perl

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.