Check if php-file exists in chroot jail

14 views
Skip to first unread message

maverick78

unread,
Mar 21, 2012, 10:05:38 AM3/21/12
to ng...@nginx.org
Hello!

I configured php-fpm to use build-in chroot. Everything works fine, but
there ist a problem when I try to check if a php-file exists.

server {
location ~ \.php$ {
root /public;
try_files $uri =404;
}
}

In this case, I alsways get 404 not found for php-files.

When I comment out try_files, the php-files are processed.

Is there a way of proper configuration in this case? How can I check if
a php-file really exists before I pass it to php-fpm?

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,224182,224182#msg-224182

_______________________________________________
nginx mailing list
ng...@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx

Valentin V. Bartenev

unread,
Mar 21, 2012, 12:12:49 PM3/21/12
to ng...@nginx.org
On Wednesday 21 March 2012 18:05:38 maverick78 wrote:
> Hello!
>
> I configured php-fpm to use build-in chroot. Everything works fine, but
> there ist a problem when I try to check if a php-file exists.
>
> server {
> location ~ \.php$ {
> root /public;
> try_files $uri =404;
> }
> }
>
> In this case, I alsways get 404 not found for php-files.
>
> When I comment out try_files, the php-files are processed.
>
> Is there a way of proper configuration in this case? How can I check if
> a php-file really exists before I pass it to php-fpm?
>

By setting proper root and permissions. If you get 404 here:

location ~ \.php$ {
root /public;
try_files $uri =404;
}

then /public/$uri isn't accessible to nginx or it doesn't exist. See error/debug
log for additional information.

wbr, Valentin V. Bartenev

maverick78

unread,
Mar 21, 2012, 1:10:19 PM3/21/12
to ng...@nginx.org
Thanks for your reply.

I got stuck with finding out the proper settings.

My files are located in /www/example.com/public. This is set as document
root in nginx server block.

In my pool of php-fpm I set a chroot path.

chroot = /www/example.com

That's why I have to set another path to document_root in my location
block for php-files.

root /public;

With these settings all my php-files are delivered by php-fpm. Nothing
to complain about. So, permissions and paths sem to be correct.

For security reasons I want to check, if the called file with
php-extension really exists. For this purpose I want to use try_files.
But when I put try_files $uri =404; in the php location block, I always
get an 404 error for php-files.

I think nginx cant find the right path because of the chroot setting in
php-fpm. Is the a way to get around this?

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,224182,224188#msg-224188

Valentin V. Bartenev

unread,
Mar 21, 2012, 2:57:44 PM3/21/12
to ng...@nginx.org
On Wednesday 21 March 2012 21:10:19 maverick78 wrote:
> Thanks for your reply.
>
> I got stuck with finding out the proper settings.
>
> My files are located in /www/example.com/public. This is set as document
> root in nginx server block.

But in your configuration you override it by "root /public". Just remove "root
/public" from the location directive or set it to "/www/example.com/public".

> In my pool of php-fpm I set a chroot path.
>
> chroot = /www/example.com
>
> That's why I have to set another path to document_root in my location
> block for php-files.
>
> root /public;

No, this directive is for nginx only. I suppose you use fastcgi for php-fpm and
you set "document root" by relevant fastcgi_param. Am I right? Please, provide
your full config.

wbr, Valentin V. Bartenev

Francis Daly

unread,
Mar 21, 2012, 3:00:53 PM3/21/12
to ng...@nginx.org
On Wed, Mar 21, 2012 at 01:10:19PM -0400, maverick78 wrote:

Hi there,

> My files are located in /www/example.com/public. This is set as document
> root in nginx server block.

That is relevant for files that nginx needs to touch.

> In my pool of php-fpm I set a chroot path.
>
> chroot = /www/example.com

That means that the filesystem from the perspective of your fastcgi
server is not the same as the filesystem from the perspective of nginx.

> That's why I have to set another path to document_root in my location
> block for php-files.
>
> root /public;

In general, nginx doesn't need to touch the php files, so it doesn't
care what "root" is set to. Except that the "default" values for some
important fastcgi_param parameters are based on what "root" is set to. So
it can matter there.

You must ensure that "fastcgi_param SCRIPT_FILENAME" is the name of the
file from the perspective of the fastcgi server.

In your case, setting "root /public" achieves that. (There are other
ways too.)

> For security reasons I want to check, if the called file with
> php-extension really exists. For this purpose I want to use try_files.
> But when I put try_files $uri =404; in the php location block, I always
> get an 404 error for php-files.

In general, nginx cannot know whether a file exists on your upstream
server; so this try_files cannot be the correct solution. In this case,
where the fastcgi server is (presumably) sharing a filesystem with the
nginx server, then it can work.

$uri is the filename that nginx would look for from the perspective
of nginx -- which in this case is rooted at /public (because of your
configuration). That file does not exist, so try_files correctly fails
to find it.

You must tell try_files the name of the file that you want to check for --
which in this case is presumably /web/example.com$uri.

Use that in your try_files directive

> I think nginx cant find the right path because of the chroot setting in
> php-fpm. Is the a way to get around this?

You need to tell try_files the nginx-based file to look for, and
fastcgi_param the php-fpm-based file to look for.

The above should do that. (Untested.)

f
--
Francis Daly fra...@daoine.org

maverick78

unread,
Mar 21, 2012, 5:22:17 PM3/21/12
to ng...@nginx.org
There a a lot of configuration-files, so I better put them into a
pastebin.

example.com vhost: http://pastebin.com/ibAfvGNu
nginx.conf: http://pastebin.com/mRtvvDq4
fastcgi_params http://pastebin.com/mqxQPAK6
php-fpm.conf: http://pastebin.com/2DSEescT
php fpm pool configuration: http://pastebin.com/zkek7TzN

The above with try_files /web/example.com$uri =404; doesn't work either.

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,224182,224198#msg-224198

Francis Daly

unread,
Mar 21, 2012, 7:22:14 PM3/21/12
to ng...@nginx.org
On Wed, Mar 21, 2012 at 05:22:17PM -0400, maverick78 wrote:

> The above with try_files /web/example.com$uri =404; doesn't work either.

Is it /web or /www?

If the result is still "doesn't work", then the debug log is probably
worth investigating.

f
--
Francis Daly fra...@daoine.org

_______________________________________________

Francis Daly

unread,
Mar 22, 2012, 2:45:57 PM3/22/12
to ng...@nginx.org
On Thu, Mar 22, 2012 at 05:24:10AM -0400, maverick78 wrote:

Hi there,

> Ops, sorry. It's www. Tht was a fault of mine and I corrected it. But
> it's the same result. Every .php-page shows 404 not found.

This time, I've actually tested what I suggest ;-)

try_files takes arguments of uris, which it then looks for as files by
prefixing $document_root.

So you must leave "root" set correctly for nginx if you want nginx to
care about files.

Without try_files in this case, nginx doesn't care about files; with it,
it does.

So: leave "root" alone (as /www/example.com/public), and just set the
correct fastcgi_param values.

Something like:

include fastcgi.conf;
fastcgi_param SCRIPT_FILENAME /public$fastcgi_script_name;

could be sufficient. You might also want

fastcgi_param DOCUMENT_ROOT /public;

if your code cares about that variable.

Then "try_files $uri =404" and "fasctcgi_pass ..." work for me.

> And the
> dubug-log only complains about the favicon that cannot be found. But the
> file hello.php (a hello world script) definitely exists.

For information: that's not the debug log.

The debug log shows every uri / filename that try_files tests (among
many other things).

If you still have difficulties, it may be worth enabling the debug log
just to see what it does show.

Good luck with it,

maverick78

unread,
Mar 22, 2012, 4:17:46 PM3/22/12
to ng...@nginx.org
You are my hero. You found out the solution. That works fine. You made a
human very happy :D And I think it may be help others too.

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,224182,224241#msg-224241

Volodymyr Kostyrko

unread,
Mar 22, 2012, 8:33:06 AM3/22/12
to public-nginx-jCiJ...@plane.gmane.org, maverick78

maverick78 wrote:
> There a a lot of configuration-files, so I better put them into a
> pastebin.
>
> example.com vhost: http://pastebin.com/ibAfvGNu
> nginx.conf: http://pastebin.com/mRtvvDq4
> fastcgi_params http://pastebin.com/mqxQPAK6

And that's your poison:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

You haven't said anywhere that nginx is chrooted but your php-fpm pool
surely is. This way you should use full path in nginx config and submit
relative path to php-fpm.

Here's my sample setup for chrooted yii app:

== nginx.conf
server {
listen
server_name
root /home/user/www/sitedir;
access_log /var/log/nginx/site.access.log;
error_log /var/log/nginx/site.error.log;
index index.php;
set $docroot /www/sitedir;

location / {
expires 1d;
try_files $uri $uri/ @missing;
}

location @missing {
rewrite ^ /index.php?url=$uri last;
}

include "/home/user/etc/nginx_php.conf";
}
==

== nginx_php.conf
location ~ .*\.php$ {
try_files $uri =404;
include /usr/local/etc/nginx/fastcgi_params;
fastcgi_pass unix:/home/user/www/.fastcgi.php.socket;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $docroot$fastcgi_script_name;
}
==

> php-fpm.conf: http://pastebin.com/2DSEescT
> php fpm pool configuration: http://pastebin.com/zkek7TzN
>
> The above with try_files /web/example.com$uri =404; doesn't work either.

PS: Remember that some php modules do require access to extra files and
even devices like '/tmp' and '/dev/crypto'.

--
Sphinx of black quartz judge my vow.

Reply all
Reply to author
Forward
0 new messages