Nginx - php-fpm: access restrictions for some php pages

Hello,

I have a folder containing some PHP files served with php-fpm (fastcgi);
inside tihs folder, I have a file which I want to be allowed for
internal
IPs and deny for external.

The problem I have is that with this configuration…

PHP

location ~ ^/some/path/(.*.php)$ {
alias /some/path/;
fastcgi_split_path_info ^(.+.php)(/.+)$;

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

# With php5-cgi alone:

fastcgi_pass 127.0.0.1:9000;

# With php5-fpm:

fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;

Changes due to the alias declaration

fastcgi_param SCRIPT_FILENAME $document_root/$1;
fastcgi_param SCRIPT_NAME /$1;
}

PHP: phpinfo() access restrictions

location = /some/path/phpinfo.php {
allow 10.0.0.0/24;
deny all;
}

…access to /some/path/phpinfo.php is managed correctly but the fastcgi
rules are not applied (I download the phpinfo.php file); while with this
configuration…

PHP

location ~ ^/some/path/(.*.php)$ {
alias /some/path/;
fastcgi_split_path_info ^(.+.php)(/.+)$;

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

# With php5-cgi alone:

fastcgi_pass 127.0.0.1:9000;

# With php5-fpm:

fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;

Changes due to the alias declaration

fastcgi_param SCRIPT_FILENAME $document_root/$1;
fastcgi_param SCRIPT_NAME /$1;
}

PHP: phpinfo() access restrictions

location ~ ^/some/path/phpinfo.php$ {
allow 10.0.0.0/24;
deny all;
}

…/some/path/phpinfo.php is interpreted correctly but access
restrictions
are not applied.

How can I fix the configuration in order that /some/path/phpinfo.php
gets
interpreted and access restrictions are applied?

Posted at Nginx Forum:

On Thu, Jan 31, 2013 at 06:22:35AM -0500, m.desantis wrote:

Hi there,

I have a folder containing some PHP files served with php-fpm (fastcgi);
inside tihs folder, I have a file which I want to be allowed for internal
IPs and deny for external.

One request is handled in one location.

Module ngx_http_core_module for details of how the one location is
chosen.

How can I fix the configuration in order that /some/path/phpinfo.php gets
interpreted and access restrictions are applied?

In your location that matches this request, put both your “access
control” and your “fastcgi handling” configuration.

f

Francis D. [email protected]

On Thu, Jan 31, 2013 at 06:53:40AM -0500, m.desantis wrote:

You mean like this?

No.

Read the mail again.

But now restriction rules are applied to all PHP files; instead I want to
apply them just to some PHP files; should I use a nested location? something
like this?

No.

Your very first example was almost correct. You had

location = /some/path/phpinfo.php {
}

which you said was the one location which matched the request that you
cared about.

In that location, put all of the configuration that you want for
that request.

(It is probably only six lines, since you know exactly what filename you
want the fastcgi server to process.)

f

Francis D. [email protected]

You mean like this?

location ~ ^/some/path/(.*.php)$ {
alias /some/path;
fastcgi_split_path_info ^(.+.php)(/.+)$;
# # NOTE: You should have “cgi.fix_pathinfo = 0;” in php.ini
#
# # With php5-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
# Changes due to the alias declaration
fastcgi_param SCRIPT_FILENAME $document_root/$1;
fastcgi_param SCRIPT_NAME /$1;
allow 10.0.0.0/24;
deny all;
}

But now restriction rules are applied to all PHP files; instead I want
to
apply them just to some PHP files; should I use a nested location?
something
like this?

location ~ ^/some/path/(.*.php)$ {
alias /some/path;
fastcgi_split_path_info ^(.+.php)(/.+)$;
# # NOTE: You should have “cgi.fix_pathinfo = 0;” in php.ini
#
# # With php5-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
# Changes due to the alias declaration
fastcgi_param SCRIPT_FILENAME $document_root/$1;
fastcgi_param SCRIPT_NAME /$1;
location ~ /phpinfo.php$ {
allow 10.0.0.0/24;
deny all;
}
}

Posted at Nginx Forum:

On Thu, Jan 31, 2013 at 12:02:13PM +0000, Francis D. wrote:

On Thu, Jan 31, 2013 at 06:53:40AM -0500, m.desantis wrote:

You mean like this?

No.

Read the mail again.

Re-reading that, it comes across as more abrupt than I intended. Sorry
about that.

If you can now tell what I meant in the previous mail, can you suggest
any phrasing or extra information that would have made it clear on
first reading?

(And if you can’t tell what I meant in the previous mail, that’s useful
information too.)

Thanks,

f

Francis D. [email protected]

Re-reading that, it comes across as more abrupt than I intended. Sorry
about that.

No problem; unfortunately my english is poor, so easily I run into
misunderstandings when I communicate in english with other people.

If you can now tell what I meant in the previous mail, can you suggest
any phrasing or extra information that would have made it clear on
first reading?

An extra information which would have been useful to me is a
configuration
code example, because is less prone to misunderstandings by me (due to
my
comprehension skills), or maybe some link about the matter I submitted
(if
known), because I couldn’t find on the web any infos about the needings
I
have
(maybe just because the solution is trivial).

Anyway, I have a doubt: in the previous reply you sent, you say

Your very first example was almost correct. You had

location = /some/path/phpinfo.php {
}

which you said was the one location which matched the request that you
cared about.

In that location, put all of the configuration that you want for
that request.

So I think you mean something like this:

location = /some/path/phpinfo.php {

common configurations…

configuration for some children urls…

}
location ~ /some/path/(.*.php)$ {

common configurations…

}

I found that a nested locations configuration works too:

location ~ ^/some/path/(.*.php)$ {

configuration for some children urls…

location ~ /phpinfo.php$ {

common configurations…

}
}

Of the two options I would prefer the last, because I avoid to write two
different configurations equal between each other, which would imply
that
every
time I change one configuration I have to duplicate it into the other
location
(but above all I have a loss of logic). Do you have some considerations
which
maybe I miss about the difference between the two configurations?

Posted at Nginx Forum:

On Thu, Jan 31, 2013 at 09:12:07AM -0500, m.desantis wrote:

An extra information which would have been useful to me is a configuration
code example, because is less prone to misunderstandings by me (due to my
comprehension skills), or maybe some link about the matter I submitted (if
known), because I couldn’t find on the web any infos about the needings I
have

What documentation did you find your current configuration in? If it is
something on the nginx.org domain, then possibly it can be adjusted to
be clearer for the next person.

(maybe just because the solution is trivial).

The solution is straightforward when you know how nginx works.

One request is handled in one location. Whatever configuration you want
to apply to a specific request must be available in the location which
handles that request. (There are some subtleties where one client http
request can become multiple nginx requests.)

I find it easier to keep the locations simple. To me, that means
separate
locations for separate configurations.

Anyway, I have a doubt: in the previous reply you sent, you say

location = /some/path/phpinfo.php {
}

In that location, put all of the configuration that you want for
that request.

So I think you mean something like this:

location = /some/path/phpinfo.php {

common configurations…

configuration for some children urls…

}

Yes. Inside that location block, put your allow and deny directives. And
also put your fastcgi directives.

The fastcgi directives are possibly only something like:

fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /some/path/some/path/phpinfo.php

This location, because of the =, will only handle one type of http
request. The query string part, after the ?, can vary. But the rest of
the http request is fixed. There are no other urls that will match
this location.

I found that a nested locations configuration works too:

location ~ ^/some/path/(.*.php)$ {

configuration for some children urls…

location ~ /phpinfo.php$ {

common configurations…

}
}

There isn’t enough actual example configuration there to know for sure,
but it looks to me like that will not do what you want.

Of the two options I would prefer the last, because I avoid to write two
different configurations equal between each other, which would imply that
every
time I change one configuration I have to duplicate it into the other
location

For me, doing that is a good thing. When you’re changing the
configuration, you should know why you are doing it. search-and-replace
should allow you to verify that you are changing all and only what you
mean to change without too much extra work.

(but above all I have a loss of logic). Do you have some considerations
which
maybe I miss about the difference between the two configurations?

One works; the other doesn’t?

You can probably make the nested location do what you want by adding a
few more lines to it. It might be a useful exercise to do that, and then
compare the two working configurations.

(You can possibly tidy the “main” php configuration too – there aren’t
many requests which would lead to your “fastcgi_split_path_info” or
“fastcgi_index” directives making a difference.)

f

Francis D. [email protected]