2
votes

I have made a setup of Apache2.4 + FastCgi, PHP-FPM, SuExec which works correctly without Suexec. But when i enable Suexec its giving me File does not exist error (404 Not Found Error in browser when i access php script).

Note: PHP Script works through PHP-FPM when i turn OFF "FastCgiWrapper" but when i turn ON its giving me 404 error.

Apache Error Log (Last Line):

[authz_core:debug] [pid 3906:tid 140546979436288] mod_authz_core.c(802): [client 192.168.91.132:58225] AH01626: authorization result of Require all granted: granted
[authz_core:debug] [pid 3906:tid 140546979436288] mod_authz_core.c(802): [client 192.168.91.132:58225] AH01626: authorization result of <RequireAny>: granted
[authz_core:debug] [pid 3906:tid 140546979436288] mod_authz_core.c(802): [client 192.168.91.132:58225] AH01626: authorization result of Require all granted: granted
[authz_core:debug] [pid 3906:tid 140546979436288] mod_authz_core.c(802): [client 192.168.91.132:58225] AH01626: authorization result of <RequireAny>: granted
[core:info] [pid 3906:tid 140546979436288] [client 192.168.91.132:58225] AH00128: File does not exist: /etc/apache2/fcgi-app/info.php

Configuration:

/etc/apache2/mods-available/fastcgi.conf

FastCgiWrapper On

/etc/apache2/suexec/www-data

/var/www/html
/cgi-bin

/etc/apache2/sites-available/example.net.conf

<VirtualHost *:80>
        ServerName example.net
        ServerAdmin [email protected]
        DocumentRoot /var/www/html/example.net/public_html
        LogLevel debug
        ErrorLog ${APACHE_LOG_DIR}/error.log

    SuexecUserGroup example examplegrp
    AddHandler php-fcgi-hand .php
    Action php-fcgi-hand /php-fcgi-uri
    Alias /php-fcgi-uri fcgi-app
    FastCgiExternalServer fcgi-app -socket /var/run/php5-fpm-example.sock -pass-header Authorization -idle-timeout 30000 -flush

    <Location /php-fcgi-uri>
            Require all granted
    </Location>

</VirtualHost>

/etc/php5/fpm/pool.d/example.conf

[example]
user  = example
group = examplegrp
listen = /var/run/php5-fpm-example.sock
listen.owner = example
listen.group = examplegrp
listen.mode = 0666
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

/var/www/html/example.net/cgi-bin/php.cgi

#!/bin/sh 
PHP_FCGI_CHILDREN=5
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=500
export PHP_FCGI_MAX_REQUESTS
exec /var/www/html/example.net/cgi-bin

Folder Structure and Permission

/var/www/html/example.net/cgi-bin/php.cgi
/var/www/html/example.net/public_html/info.php

drwxrwxrwx 13 www-data www-data var
    |____drwxr-xr-x 5 www-data www-data www
        |____drwxr-xr-x 6 www-data www-data html
            |____ drwxr-xr-x 4 example  examplegrp example.net
                |______ drwxr-xr-x 2 example examplegrp cgi-bin
                    |_____-r-xr-xr-x 1 example examplegrp php.cgi

                |______ drwxr-xr-x 2 example examplegrp public_html
                    |_____-rwxr-xr-x 1 example examplegrp info.php
2
Unless I am blind, I do not see anything here that shows you are using PHP-FPM. It appears you are using PHP-CGI. FPM uses Pools connected by either a socket or tcp. None of your examples show this usage.Diemuzi
@Diemuzi i have configured vhost to use PHP-FPM and it works fine but when i turn on "FastCgiWrapper" its giving me error "404 Not Found". Please check my updated question.sravis

2 Answers

1
votes

I wrote this working configuration long ago and it works on Apache 2.4.x so I'm going to recommend you give it a try https://gist.github.com/diemuzi/3849349. It's too large to post in an answer here. You'll find all the configurations you'll need. You may even see something I have done differently compared to what you have posted here too.

However I will also recommend that you stop thinking about using the FastCgiExternalServer like you are trying and as you will find in my example. But instead look into using the mod_proxy_fcgi. This is a much simpler way of connecting to FPM now and it does support sockets as of recently.

Here is an example of the mod_proxy_fcgi way:

# PHP-FPM via Socket
<IfModule proxy_module>
    <IfModule proxy_fcgi_module>
        ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/usr/local/php/etc/php-fpm/[USERNAME].sock|fcgi://localhost/vhosts/[DOMAIN]/public/
    </IfModule>
</IfModule>

Of course you will want to change the unix: path and the path to your root document too. Notice the localhost part, that is not a mistake. It really does not matter what you put for localhost but I figured it looked better. Yes, my domain is accessible via the IP and Domain even though it says localhost so don't let that fool you.

If you want to use the TCP way of using mod_proxy_fcgi you can do it this way too:

# PHP-FPM via TCP
<IfModule proxy_module>
    <IfModule proxy_fcgi_module>
        <Location ~ ^/(.*\.php(/.*)?)$>
            ProxyPass fcgi://127.0.0.1:[PORT]/vhosts/[DOMAIN]/public/
        </Location>
    </IfModule>
</IfModule>

Of course make sure the 127.0.0.1:[PORT] matches what you have inside of your FPM Pool, so change it accordingly. Again, make sure you change the path to the document root too.

The three answers I've given you are all working examples. I even tested just before I posted this answer.

0
votes

You ask for Apache to run as user example, but you set the configuration file for user www-data . The documentation says that the config file /etc/apache2/suexec/www-data is read when the Apache user is www-data. I never experimented with that, but it might be that you need to set the config file /etc/apache2/suexec/example. One thing that I find a bit confusing is these two stages: the Apache user and then the target user, which is allowed to run the target cgi. Suexec runs checks in these two stages. The custom version of suexec allows a different Apache user to run with a different config file, but this is different from the selection of a target user with the SuexecUserGroup Apache directive. We don't need to change the Apache user, if we only want to change the target user, the one that will run the CGI. For that purpose, the pristine version is sufficient. Anyway, this is my understanding. I hope it helps someone.