Check if php-file exists in chroot jail

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:

On Wednesday 21 March 2012 18:05:38 maverick78 wrote:

}

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

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:

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 D. [email protected]

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

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 D. [email protected]

There a a lot of configuration-files, so I better put them into a
pastebin.

example.com vhost: example.com vhost config nginx - Pastebin.com
nginx.conf: nginx.conf - Pastebin.com
fastcgi_params fastcgi_params - Pastebin.com
php-fpm.conf: php-fpm.conf - Pastebin.com
php fpm pool configuration: php-fpm pool config - Pastebin.com

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

Posted at Nginx Forum:

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 :wink:

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,

f

Francis D. [email protected]

You are my hero. You found out the solution. That works fine. You made a
human very happy :smiley: And I think it may be help others too.

Posted at Nginx Forum:

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

2012/03/22 10:08:40 [notice] 2900#0: *3 “^(GET|HEAD|POST)$” matches
“GET”, client: 127.0.0.1, server: www.example.com, request: “GET
/hello.php HTTP/1.1”, host: “www.example.com
2012/03/22 10:08:40 [notice] 2900#0: *2 “^(GET|HEAD|POST)$” matches
“GET”, client: 127.0.0.1, server: www.example.com, request: “GET
/favicon.ico HTTP/1.1”, host: “www.example.com
2012/03/22 10:08:40 [error] 2900#0: *2 open()
“/www/example.com/public/favicon.ico” failed (2: No such file or
directory), client: 127.0.0.1, server: www.example.com, request: “GET
/favicon.ico HTTP/1.1”, host: “www.example.com
root@localhost:/var/log/nginx#

Thanks for your attention. But I think, I have to find another way of
chrooting or abandon it.

Nginx is great. There is no alternative for me. For example the
gzip-static module has no competition. :wink:

Posted at Nginx Forum: