I have a scenario with nginx/1.4.6
running on Ubuntu 14.04
but with php/5.2.10
inside a chroot Ubuntu 9.10
(Karmic Koala).
My issue is that all requests to php files result in the dreaded "No input file specified.
"
I have the site stored inside the chroot, so it is readable both from php inside the chroot jail and from nginx outside of the jail with this setup:
From nginx' point of view:
/var/chroot/karmic/var/www/domains/dummysite/web:
. www-data:www-data drwxr-xr-x
index.php www-data:www-data -rw-r--r--
test.jpg www-data:www-data -rw-r--r--
And inside chroot
From php's point of view:
/var/www/domains/dummysite/web:
. www-data:www-data drwxr-xr-x
index.php www-data:www-data -rw-r--r--
test.jpg www-data:www-data -rw-r--r--
And index.php
is dead simple!
<?php
echo '<h1>Hello World</h1> Foo bar...';
?>
I have started php-fcgi with spawn-fcgi from lighttpd using this command:
LANG=C chroot /var/chroot/karmic /usr/bin/spawn-fcgi -C 12 -a 127.0.0.1 -p 9000 -u www-data -g www-data -f /usr/bin/php5-cgi -P /var/run/fastcgi-php.pid
Nginx can successfully serve the static test.jpg, but php-fcgi fails to read index.php
# /etc/nginx/site-enabled/dummysite -> /etc/nginx/site-available/dummysite:
server {
listen 80;
root /var/chroot/karmic/var/www/domains/dummysite/web;
server_name dummysite.wtf;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
index index.php index.html;
allow all;
}
location ~ ^/index\.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_intercept_errors on;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /var/www/domains/dummysite/web$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/www/domains/dummysite/web;
include fastcgi_params;
}
}
As far as I have understood, this should be the correct syntax. I have also tried with some variations such as $document_root$fastcgi_script_name
, without SCRIPT_NAME
or DOCUMENT_ROOT
set and with SCRIPT_FILENAME
relative to DOCUMENT_ROOT
or the root
inside the server
block.
I have no open_basedir
restrictions set in php.
Despite having maximum logging enabled in php and nginx, I get no workable information in either php.log, nginx.error.log or dummysite.wtf.error.log.
I have resorted to connecting to php-fcgi directly with the cgi-fcgi
utility directly and this is the response I get:
env -i SCRIPT_NAME=index.php DOCUMENT_ROOT=/var/www/domains/dummysite/web SCRIPT_FILENAME=/var/www/domains/dummysite/web/index.php QUERY_STRING= REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000
Status: 404 Not Found
X-Powered-By: PHP/5.2.10-2ubuntu6
Content-type: text/html
No input file specified.
The same result applies to all calls with SCRIPT_FILENAME
set to
- /index.php
- /web/index.php
- /dummysite/web/index.php
- /domains/dummysite/web/index.php
- /www/domains/dummysite/web/index.php
- /var/www/domains/dummysite/web/index.php
- /karmic/var/www/domains/dummysite/web/index.php
- /chroot/karmic/var/www/domains/dummysite/web/index.php
- /var/chroot/karmic/var/www/domains/dummysite/web/index.php
And I have tried the same with various DOCUMENT_ROOT
.
Best Answer
TL;DR
And
Long solution
Ok, this is how I solved it (I thought it might come handy to someone). As php-cgi isn't very verbose I resorted to using strace to capture php's file operations to disk.
Then I called the php-fcgi directly with:
And the interesting lines in the strace was
Ok, so clearly, it successfully tried to lstat
[...]/web/index.php
(which has the correct 0644 permissions), but then it tried to open/index.php
. This led me to experiment withSCRIPT_NAME
, and voila!So, my first problem was that my nginx config should read
To be honest; I have no idea why this is. I thought the purpose of
SCRIPT_NAME
is not to point to the file but merely state the name of the file. But I guess I must have misunderstood its purpose.But, unfortunately, my issues where not over just yet. For when I tried to
curl http://dummysite.wtf/
, it still saidNo input file specified.
So, yet again,
strace
to the rescue!And right there is the answer,
SCRIPT_NAME
,SCRIPT_FILENAME
andDOCUMENT_ROOT
appears two times, the first time they are correct, the second time with an incorrect value. It turns out theinclude fastcgi_params
directive in the nginxserver
block will insert these variables itself, and as I put this include statement last in mylocation
block, it was effectively overriding my previous settings.This is how I fixed this:
And in the fastcgi_params file that is included i changed one line to this
And finally, glorious success!
This is one way to run a fatally old php version inside a chrooted jail on top of modern software such as ubuntu 14.04 LTS and nginx 1.4.x :-)