Confusion over apparently conflicting advice in guide/wiki/examples

I’d call myself very much a beginner with NGiNX, but I’ve been looking
further through the documentation, particularly the
Pitfalls and Common Mistakes | NGINX page, and now I’m left with confusion!

This page PHP FastCGI Example | NGINX says
“This guide run fine on php.ini cgi.fix_pathinfo = 1 (the default). Some
guide insist to change it to cgi.fix_pathinfo = 0 but doing that make
PHP_SELF variable broken (not equal to DOCUMENT_URI).”.

But Pitfalls and Common Mistakes | NGINX says:
Set cgi.fix_pathinfo=0 in php.ini. This causes the PHP interpreter to
only
try the literal path given and to stop processing if the file is not
found.

And the provided nginx/sites-available/default says

NOTE: You should have “cgi.fix_pathinfo = 0;” in php.ini

Which is correct?

My second question: As I understand it, you should always make parameter
changes only where they are needed, and in an overriding way - ie: one
never
touches php.ini itself.
So, I am looking at this entry:

http://wiki.nginx.org/Pyrocms

In the server stanza there is:

server {
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
fastcgi_read_timeout 180;

and then separately it says to add to fastcgi_params the following:

fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors off;

Some of those numbers are HUGE - most of the buffer defaults are
normally
4k|8k. And 3 minutes between connections? Is this over-the-top? And the
three items in server are conflicted by different values in fastcgi
params.

And isn’t that going to “pollute” the whole fpm server? I thought it
would
be better to have it in the fpm pool, so first I had it like this:

php_value[upload_max_filesize] = 128M
php_value[max_file_uploads] = 60
php_value[default_socket_timeout] = 180
php_value[date.timezone] = ‘Europe/London’
php_value[session.gc_maxlifetime] = 28800

The I realised I only needed these high values for one area of my
server, so
again I changed it:

location ~ /upload/ {
    location ~ \.(php)$ {
        try_files $uri =404;
        set $php_value "post_max_size = 128M";
        set $php_value "$php_value \n upload_max_filesize = 128M";
        set $php_value "$php_value \n session.gc_maxlifetime = 

28800";
set $php_value “$php_value \n max_file_uploads = 60”;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE $php_value;
include fastcgi_params;
}
}

And it works fine. No core ini files are touched, only the area which
need
to change is changed.

Also, the example config has:

location ~ .php {
fastcgi_pass unix:/tmp/domain.sock;
fastcgi_split_path_info ^(.+.php)(.*)$;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;

But the Pitfalls guide suggests this is dangerous.

So, my question would be:

Is this example file wrong/outdated/dangerous?

Or am I completely misunderstanding something?

Posted at Nginx Forum:

Hi BR and thank you for your reply. You said:

Where does the ‘sites-available’ directory of nginx came from?

Standard “apt-get install nginx” on Ubunutu. Stable and mainline.
Like Apache, ‘sites-available’ contains all sites, then you can symlink
to
‘sites-enabled’ for running sites.
It’s just the Ubuntu way :slight_smile:

There is no such DOCUMENT_URI server variable in PHP
The nginx wiki has not the reputation of being a trustable source

I know you say not to trust the wiki (it appears in
PHP FastCGI Example | NGINX) but it also is in the standard
install
of nginx on ubuntu which comes with an /etc/nginx/fastcgi_params file
containing
fastcgi_param DOCUMENT_URI $document_uri;

Perhaps it should not even be there? Should I report it as a possible
error
to the Ubuntu package maintainers?

The ‘0’ value seems to exist for backward-compatibility as it provides a
broken environment.
Thus, scripts relying on such a value are highly suspicious to my eyes.
What exactly are you referring to in the pitfalls page saying that you
setup is dangerous?​

Well, in your reply you say that it provides a broken environment, but
as I
mentioned, in both the nginx wiki AND in the default config file which
comes
with a standard nginx install on Ubuntu, it says

NOTE: You should have “cgi.fix_pathinfo = 0;” in php.ini

So, you can understand my confusion here! PHP says leave it on. You say
leave it on. Nginx stand install and wiki says turn it off so that nginx
doesn’t keep trying files. The pitfalls page says:


“For instance, if a request is made for /forum/avatar/1232.jpg/file.php
which does not exist but if /forum/avatar/1232.jpg does, the PHP
interpreter
will process /forum/avatar/1232.jpg instead. If this contains embedded
PHP
code, this code will be executed accordingly.
Options for avoiding this are:
Set cgi.fix_pathinfo=0 in php.ini. This causes the PHP interpreter to
only
try the literal path given and to stop processing if the file is not
found.”

​​
On Mon, Mar 3, 2014 at 10:11 PM, talkingnews [email protected]
wrote:

This page PHP FastCGI Example | NGINX says
“This guide run fine on php.ini cgi.fix_pathinfo = 1 (the default). Some
guide insist to change it to cgi.fix_pathinfo = 0 but doing that make
PHP_SELF variable broken (not equal to DOCUMENT_URI).”.

To know what cgi.fix_path_info does ​depending on its value, rely on
core
php.ini
documentationhttp://php.net/manual/en/ini.core.php#ini.cgi.fix-pathinfo
.
The default value of ‘1’ fixes an erroneous behavior of earlier PHP
versions not using PHP_INFO information properly. THe ‘0’ value seems to
exist for backward-compatibility as it provides a broken environment.
Thus, scripts relying on such a value are highly suspicious to my eyes.
Where does the ‘sites-available’ directory of nginx came from? I do not
have such one (using Debian official stable package, currently 1.4.5).

Besides, there is no such DOCUMENT_URI server variable in PHP (at least
as
of 4.1.0 as the list of PHP server
variableshttp://php.net/manual/en/reserved.variables.server.phpstates
and I wonder if it had ever existed before).
Another note: what the wiki says is not exact, refer to PHP
documentation
to know the real impact of PHP configuration directives (sounds
obvious…).

The nginx wiki has not the reputation of being a trustable source of
information. Prefer referring to the official documentation, either
nginx
or PHP one.

My second question: As I understand it, you should always make parameter

changes only where they are needed, and in an overriding way - ie: one
never
touches php.ini itself.

​Well, changing php.ini file modifies the behavior for all scripts using
it. If you have multiple environments needing different specific
settings,
then it is indeed safer to configure them on-the-fly through FastCGI
parameterization of nginx. Thus, basing all your different
configurations
on top of the default one is a rather straightward way of doing it.
Moreover, when updating PHP packages between major versions, its default
configuration files​

​usually also change. When you will wish to ​test your production setup
for
an upgrade, you will be happier if you are as close to the original
files
as possible.

But the Pitfalls guide suggests this is dangerous.

​What exactly are you referring to in the pitfalls page saying that you
setup is dangerous?​


B. R.

On Tue, Mar 04, 2014 at 03:51:36PM -0500, talkingnews wrote:

Hi there,

continuing from my previous mail…

to the Ubuntu package maintainers?
nginx is the fastcgi client. It can send any key/value pairs to the
fastcgi server. If you read the fastcgi spec, you’ll see that certain
keys
are expected to exist. And if you read your fastcgi server
documentation,
you’ll see that certain keys are heeded. Those lists of keys may not
be identical.

A lot of the fastcgi_params file seems to be things that some common
fastcgi servers and/or the code they run will typically make use of.
They
are things added to be helpful in some cases, which are unlikely to ever
be harmful.

Perhaps your fastcgi server will be happy with just “fastcgi_param
SCRIPT_FILENAME /tmp/env.php”, and with no other fastcgi_param values
at all. Or perhaps it ignores SCRIPT_FILENAME and instead uses some
different keys to identify the file to be processed.

And perhaps your next fastcgi server will do something different.

You must configure your nginx to say whatever your fastcgi server needs
to hear. Many of the “default” params are to make it Just Work with
different servers. (I think.)

So, you can understand my confusion here! PHP says leave it on. You say
leave it on. Nginx stand install and wiki says turn it off so that nginx
doesn’t keep trying files.

No. nginx doesn’t keep trying files. The fastcgi server might, but
that’s
a “fix your fastcgi server” issue.

So what I meant was that setting cgi.fix_pathinfo = 1 may leave this
security gap of executing unwanted code.

…in the php interpreter.

Not in nginx. Fix php problems in php, and things will be easier.

Cheers,

f

Francis D. [email protected]

On Mon, Mar 03, 2014 at 04:11:52PM -0500, talkingnews wrote:

Hi there,

I’d call myself very much a beginner with NGiNX, but I’ve been looking
further through the documentation, particularly the
http://wiki.nginx.org/Pitfalls page, and now I’m left with confusion!

The wiki is pretty much free for anyone to edit. The documentation is
somewhere else.

This page PHP FastCGI Example | NGINX says
“This guide run fine on php.ini cgi.fix_pathinfo = 1 (the default). Some
guide insist to change it to cgi.fix_pathinfo = 0 but doing that make
PHP_SELF variable broken (not equal to DOCUMENT_URI).”.

But http://wiki.nginx.org/Pitfalls says:
Set cgi.fix_pathinfo=0 in php.ini. This causes the PHP interpreter to only
try the literal path given and to stop processing if the file is not found.

Two different wiki pages, two different authors with different
requirements and expectations. Probably.

The short version is: nginx and php and fastcgi are three different
things. nginx doesn’t care what php configuration you use. nginx also
doesn’t care if your php configuration works at all. It’s the job of
the person doing the configuring to care about that.

Which is correct?

You’re more likely to get correct php advice on a php list.

I suspect that the only reason it is mentioned anywhere on the nginx
wiki is that some time ago, someone reported that they configured
their nginx to ask their fastcgi server to consider the filename
/var/www/file.txt/fake.php to be a php script; and the fastcgi server
and/or php interpreter instead processed the file /var/www/file.txt as
a php script; and that this was a problem and that it was also somehow
nginx’s problem or fault.

(I agree it’s a problem; I disagree it’s nginx’s problem.)

I’d say use “cgi.fix_pathinfo = 0”, and fix any php script or
environment
that has problems.

But I’d also say don’t expect good knitting advice on a non-knitting
list.

My second question: As I understand it, you should always make parameter
changes only where they are needed, and in an overriding way - ie: one never
touches php.ini itself.

That’s another php question. nginx doesn’t care.

fastcgi_connect_timeout 60;

three items in server are conflicted by different values in fastcgi params.
Maybe those big values are suitable for that specific application. Or
maybe the random author who put it into the wiki found that this set of
values worked for them without testing what else might have worked.

In this case, putting values both at server level and in a file included
at location level means that the nginx inheritance rules will apply,
and not all of the server-level values will matter.

(And putting any non-fastcgi_param values in a file called
fastcgi_params
is probably a poor idea.)

And isn’t that going to “pollute” the whole fpm server?

No.

Those settings are purely for the fastcgi client, which is nginx.

The only ones the server sees are fastcgi_param values – and they are
random key/value pairs that nginx doesn’t care about. The fastcgi server
does with them whatever it wants.

I thought it would
be better to have it in the fpm pool, so first I had it like this:

php_value[upload_max_filesize] = 128M
php_value[max_file_uploads] = 60
php_value[default_socket_timeout] = 180
php_value[date.timezone] = ‘Europe/London’
php_value[session.gc_maxlifetime] = 28800

php question.

        fastcgi_pass   unix:/var/run/php5-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME

$document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE $php_value;
include fastcgi_params;
}
}

And it works fine. No core ini files are touched, only the area which need
to change is changed.

Strictly a php question still. nginx (the fastcgi client) can send any
key/value pairs as fastcgi_params. What the fastcgi server does with
them
is not nginx’s concern. If your fastcgi server does something useful
with PHP_VALUE, then it can be useful for you to set it, like you do
here.

But nginx doesn’t know what the values mean, or what they invite your
fastcgi server to do.

Also, the example config has:

location ~ .php {
fastcgi_pass unix:/tmp/domain.sock;
fastcgi_split_path_info ^(.+.php)(.*)$;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;

But the Pitfalls guide suggests this is dangerous.

The Pitfalls guide should explain why it is suggests this is dangerous.

What url might match this location?

What fastcgi_param SCRIPT_FILENAME might your fastcgi server receive?

What file might your fastcgi server process as if it were a php script?

If you can’t tell, then there’s a danger – but it’s not necessarily on
the nginx side.

So, my question would be:

Is this example file wrong/outdated/dangerous?

Or am I completely misunderstanding something?

I suspect that the multiple voices on the wiki have not explained
clearly
to you why what they suggest is true, is true.

Perhaps it’s not true at all. Or perhaps it is true in a specific set
of circumstances – which differ for each voice.

Are things any clearer if you limit yourself to things at
http://www.nginx.org/ ? Perhaps there aren’t enough examples there,
I don’t know.

Good luck with it,

f

Francis D. [email protected]

Thanks for the replies, and especially to Francis for clearly
differentiating the aspects and responsibilities of the NGiͶX “flow”, if
I
can call it that.

The only remaining confusion comes with the provided nginx config files
which appear to contradict best practice (as well as setting up
parameters
which don’t even exist!) , but I now realise and acknowledge that this
will
be an issue for the Ubuntu NGiͶX package maintainer, not NGiͶX.

I think what I might do is to do another complete brand new install of
NGiͶX
and PyroCMS, see what the most minimal config changes I can make from
the
default are for my application, test the hell out of it, and tentatively
make changes to the Wiki page for the Pyrocms config.

Thanks again. PS - as I post this, I see below that today has set a new
record for numbers of users and guests on the forum. Excellent!

Posted at Nginx Forum:

On Wed, Mar 05, 2014 at 04:52:29PM -0500, talkingnews wrote:

Hi there,

just to avoid sending package maintainers on a wild goose chase…

The only remaining confusion comes with the provided nginx config files
which appear to contradict best practice

To understand that, you should probably find what “best practice”
actually is, and (more importantly) the specific set of circumstances
when this set of best practice applies.

Pretty much all guidelines have exceptions.

(as well as setting up parameters
which don’t even exist!)

I’m not sure what you mean by that. In the context of fastcgi / php, if
you set “fastcgi_param HELLO $request_uri;”, then when you look in your
php $_SERVER (or wherever your fastcgi server presents the information),
you will have a parameter HELLO with the value of the incoming request.

If a fastcgi_param is set (explicitly or implicitly), it exists. If it
is not, it does not.

The “defaults”, either from Ubuntu or nginx, are presumably “a set that
the author thinks are probably frequently useful”.

You can always set exactly the values that your fastcgi server, your
version of php, and your application, require, and remove all of the
others. And then do it again when you add another application, or change
any of your stack.

Good luck with it,

f

Francis D. [email protected]