Apache FastCgi, PHP-FPM, Suexec error Permission Denied

advertisements

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


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.