Access denied (403) for PHP files with Nginx + PHP-FPM
Asked Answered
W

7

26

I have been spending few hours on that issue and despite the high number of posts related to it, I cannot solve it. I have a Fedora 20 box with Nginx + PHP-FPM that worked quite good until today (after I reloaded php-fpm.service I guess). Nginx is serving static files with no problem, but any PHP file triggers an error 403.

The permissions are ok, nginx and php-fpm are running under the user "nginx":

root     13763  0.0  0.6 490428 24924 ?        Ss   15:47   0:00 php-fpm: master process (/etc/php-fpm.conf)
nginx    13764  0.0  0.1 490428  7296 ?        S    15:47   0:00 php-fpm: pool www
nginx    13765  0.0  0.1 490428  7296 ?        S    15:47   0:00 php-fpm: pool www
nginx    13766  0.0  0.1 490428  7296 ?        S    15:47   0:00 php-fpm: pool www
nginx    13767  0.0  0.1 490428  7296 ?        S    15:47   0:00 php-fpm: pool www
nginx    13768  0.0  0.1 490428  6848 ?        S    15:47   0:00 php-fpm: pool www

The served files have been set to nginx user as well, I even ended chmoding 777 those files to try, but still "Access denied" for any PHP files.

Below is a server of my Nginx config:

server {
        listen          80;
        server_name     localhost;

        root            /var/www/html;

         location ~ \.php$ {
            fastcgi_intercept_errors on;
            try_files $uri =404;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
}

The PHP-FPM pool:

[www]
...
listen = 127.0.0.1:9000
user = nginx
group = nginx
...

For the versions:

php-5.5.11 (as well as php-fpm-5.5.11 of course)

nginx-1.4.7

I am adding the Nginx error log:

 FastCGI sent in stderr: "Access to the script '/var/www/html' has been denied (see security.limit_extensions)" while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: localhost, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "xxx.xxx.xxx.xxx"

And precise that security.limit_extensions is correct, set to: security.limit_extensions = .php.

About the path permissions, /var/www/html can be traversed. What am I missing?

Wan answered 30/4, 2014 at 14:13 Comment(12)
I know it sounds weird, but did you double check whether you have edited the right php.ini file regarding to limit_extensions? I made this mistake the other day..Dimity
limit_extensions is present only in the FPM pool, for me with Fedora 20 in /etc/php-fpm.d/www.conf.. But thank you JohnWan
have you tried setting the fastcgi_pass to the socket address instead of the serveraddress (e.g. unix:/var/run/php-fpm/php-fpm.sock;)?Dimity
Yes I tried this too, but the result is the same. I'm running out of ideas with this issue..Wan
Well.. could you set the fastcgi_param SCRIPT_FILENAME to $fastcgi_script_name, reload fpm and try again? Without $document_root...Dimity
The same problem John, thxWan
Yeah it's kinda embarrassing but I had this problem two weeks ago and I didn't write down how I solved it, of course.. Anyway, here's my last idea and I kinda think that was the thing: Remove everything from the security.limit_extensions so it looks like this: security.limit_extensions = ..Dimity
I tried too ;] But without success. Then I get a 404 even if the file exists. Error log: FastCGI sent in stderr: "Unable to open primary script: /var/www/html (Success)" while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: localhost, request: "GET /info.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php-fpm.sock:", host: "xxx.xxx.xxx.xxx" Some thread suggested to set it to FALSE too, same result.Wan
Huh.. I think that we're heading in the right direction ;) please keep the limit_extensions empty and include fastcgi_split_path_info ^(.+\.php)(/.+)$;in your location block and try again with and without the $doc_root in SCRIPT_FILENAMEDimity
try this: location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;}Magnum
John, I found a solution and I feel stupid about it. In the php.ini, I switched the cgi.fix_pathinfo from 0 to 1 and everything is working now. Thank you for your time, you support helped! ;]Wan
Great! I'm gonna answer with all the possible solutions for future reference.. You don't have to accept it, of course!Dimity
D
41

Here are some possible solutions:

  1. In your php-fpm www.conf set security.limit_extensions to .php or .php5 or whatever suits your environment. For some users, completely removing all values or setting it to FALSE was the only way to get it working.

  2. In your nginx config file set fastcgi_pass to your socket address (e.g. unix:/var/run/php-fpm/php-fpm.sock;) instead of your server address and port.

  3. Check your SCRIPT_FILENAME fastcgi param and set it according to the location of your files.

  4. In your nginx config file include fastcgi_split_path_info ^(.+\.php)(/.+)$; in the location block where all the other fastcgi params are defined.

  5. In your php.ini set cgi.fix_pathinfo to 1

Dimity answered 30/4, 2014 at 16:20 Comment(5)
Are you sure is safe to set fix_pathinfo to 1 ? Check serverfault.com/questions/627903/…Horsepower
If #1 and #4 are implemented, it's perfectly safe to implement #5. Actually... #1 and #5 were defaulted to .php and 1 respectively in PHP 5.5.Solvolysis
I was trying to get .html files to run as .php files, so #1 above with "sudo systemctl restart php7.0-fpm" did it for me. Cheers.Elenoraelenore
Guys its not safe. In NGINX oficial website it says it opens a security hole that allows to upload something.Konstantine
when i change cgi.fix_pathinfo to 1, site works well.Mcvey
D
10

Please note that the above solution (set cgi.fix_pathinfo to 1) is a terrible idea. See https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/ for a good overview.

The issue is probably down to your application relying on PATH_INFO. Enable access logging for php to get more information about how your application is called to help you debug this issue.

Once again, just to be sure - the accepted solution is a terrible idea, and will likely get your site hacked.

Defame answered 6/2, 2015 at 3:23 Comment(1)
It's not a terrible idea and it won't get your site hacked. It's the default value for PHP 5.5. If you pass to PHP-FPM as instructed here you're fine: nginx.com/resources/wiki/start/topics/examples/phpfcgi/…Solvolysis
P
3

Do not forget to restart php5-fpm service after changing php.ini!!

service php5-fpm restart or service php5-fpm reload

fpm prestarts php5 so it is not enough to restart nginx to have the changes applied.

Pewit answered 11/12, 2015 at 8:40 Comment(0)
H
1

It may be related to selinux. If you use the shared folder of Virtual Box, you cannot change the access permissions in this folder in Linux. Therefore, you can solve it after closing selinux.

Hellbox answered 8/4, 2018 at 3:33 Comment(0)
L
0

For reference of those coming later: In the conf for your site try to add: fastcgi_param PATH_INFO $fastcgi_path_info; Also look at what SELinux is doing. To turn it off: setenforce 0 But then figure what script is the issue and put back to setenforce 1

Liard answered 2/4, 2015 at 1:19 Comment(0)
D
0

This could also happen if there is no index.php in your vhost document root.

Carefully double-check the www_root parameter in your nginx configuration. Then double check that the php file you're trying to hit is actually in there.

In my case, I mis-typed the vhost doc root path and so pointed it to an empty directory, yielding a 403.

Dragoon answered 12/11, 2015 at 19:57 Comment(0)
B
0

I ran into the same problem, and after trying all the suggestions above it still didn't work. Then I checked my files. Obviously I am not a server expert.

It turned out I have a folder /sites-available and /sites-enabled. I had updated the default file in the sites-available folder but not in the /sites-enabled folder. After doing that (and a restart of nginx), it all started to work.

Took me some time to solve this, I hope this helps someone else to fix it sooner.

Bestead answered 9/6, 2020 at 10:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.