Nginx Location Block

heya-

I’m having some interesting dramas with Nginx location block. I put it
down to a misconfiguration in my conf files, but I can’t locate what it
possible could be.

Briefly, my setup is using an Nginx frontend server to do SSL offloading
then pass requests to my backend Nginx servers which then process the
request via fastCGI.

My issue is when I try to access URIs like /cms/index.php?blah, the
frontend Nginx gives 404. Access with /cms/ and Nginx passes the request
to the backend.

Here is my frontend location block:

location / {
limit_req zone=root burst=300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header HTTPS on;
proxy_set_header X-Forwarded-HTTPS on;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_pass http://webpool;
}

Here is my log entry for accessing the URI.

“25/May/2015:14:33:01 +1000” “example.com” -275 428 “GET /cms/index.php
HTTP/1.1” “404” “-” “10.107.0.8” “Mozilla/5.0 (X11; Linux x86_64;
rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.6.0”

What I don’t understand is this, why does Ngnix pass the URI /cms/ to my
backend fine, but add /cms/index.php to the end and it does not pass to
the backend?

I’ve read and re-read the below and I’m drawing blanks, as my
understanding is, it should work.

Many thanks in advance for helping me understand my problem.

–julian

Hi Julian.

Am 25-05-2015 07:44, schrieb Julian De Marchi:

heya-

I’m having some interesting dramas with Nginx location block. I put it
down to a misconfiguration in my conf files, but I can’t locate what it
possible could be.

Briefly, my setup is using an Nginx frontend server to do SSL
offloading
then pass requests to my backend Nginx servers which then process the
request via fastCGI.

You must tell nginx to use fcgi.

http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html

but you config snippet shows.

http://nginx.org/en/docs/http/ngx_http_proxy_module.html

proxy_set_header X-Real-IP       $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header HTTPS             on;
proxy_set_header X-Forwarded-HTTPS on;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_pass  http://webpool;

}

[snipp]

I’ve read and re-read the below and I’m drawing blanks, as my
understanding is, it should work.

maybe you could also read.

http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html

and for deeper understanding try

Many thanks in advance for helping me understand my problem.

HTH

–julian

Aleks

On 25/05/15 17:04, Aleksandar L. wrote:

Hi Julian.

Heya Aleksandar,

Thanks for your kind reply.

You must tell nginx to use fcgi.

Module ngx_http_fastcgi_module

but you config snippet shows.

I did not communicate clearly about my snippet. I apologize for this.
The snippet is from my frontend Nginx server where the problem is
occurring. I know this 100% as the 404 error is generated by the
frontend Nginx server not my backend nginx server.

–julian

On Mon, May 25, 2015 at 03:44:26PM +1000, Julian De Marchi wrote:

Hi there,

Briefly, my setup is using an Nginx frontend server to do SSL offloading
then pass requests to my backend Nginx servers which then process the
request via fastCGI.

My issue is when I try to access URIs like /cms/index.php?blah, the
frontend Nginx gives 404. Access with /cms/ and Nginx passes the request
to the backend.

Here is my frontend location block:

Is this the only location{} block in the only server{} block in your
frontend nginx.conf file? Are there any “include” directives that
might add others? Are there any rewrite-module directives outside this
location{}?

What I don’t understand is this, why does Ngnix pass the URI /cms/ to my
backend fine, but add /cms/index.php to the end and it does not pass to
the backend?

How do you know that it does not pass it to the backend?

Do you watch a tcpdump trace, or do you watch the backend access log,
or something like that?

f

Francis D. [email protected]

On 27/05/15 09:45, Francis D. wrote:

to the backend.

Here is my frontend location block:

Is this the only location{} block in the only server{} block in your
frontend nginx.conf file? Are there any “include” directives that
might add others? Are there any rewrite-module directives outside this
location{}?

For this virtual host, yes it is. My rewriting logic is performed in the
backend. There are no include directives.

What I don’t understand is this, why does Ngnix pass the URI /cms/ to my
backend fine, but add /cms/index.php to the end and it does not pass to
the backend?

How do you know that it does not pass it to the backend?

Do you watch a tcpdump trace, or do you watch the backend access log,
or something like that?

I’m watching the backend access log for the virtual host and never see
it come in. When a requests reaches the backend I also insert headers so
I can tell which backend server handled the request.

–julian

On Wed, May 27, 2015 at 09:58:42AM +1000, Julian De Marchi wrote:

On 27/05/15 09:45, Francis D. wrote:

On Mon, May 25, 2015 at 03:44:26PM +1000, Julian De Marchi wrote:

Hi there,

My issue is when I try to access URIs like /cms/index.php?blah, the
frontend Nginx gives 404. Access with /cms/ and Nginx passes the request
to the backend.

Is this the only location{} block in the only server{} block in your
frontend nginx.conf file? Are there any “include” directives that
might add others? Are there any rewrite-module directives outside this
location{}?

For this virtual host, yes it is. My rewriting logic is performed in the
backend. There are no include directives.

I am unable to reproduce what you report.

The configuration you have shown, plus some assumed configuration that
you have not shown, should not do what you report it does do.

Can you try using a separate access_log in this frontend server{} block,
and confirming that the request is handled by this server{} and not by
any other one?

How do you know that it does not pass it to the backend?

I’m watching the backend access log for the virtual host and never see
it come in. When a requests reaches the backend I also insert headers so
I can tell which backend server handled the request.

Does the backend configuration include anything that would log to a
different access log, or not log at all?

Or can you (temporarily, or on a test system) replace the backend with
one that just does “return 200 here”, and confirm that you do not get
that response when you make the second request?

Is there any form of caching going on? Are you testing using “curl”
or a bigger browser?

f

Francis D. [email protected]

On 27/05/15 10:15, Francis D. wrote:

Does the backend configuration include anything that would log to a
different access log, or not log at all?

Apparently so… When I access via the frontend my error log for the
backend looks like below. Which is quite normal.

[haweb-05.vpn] 10:31:58 [err] [local7] [nginx] 2015/05/27 10:31:58
[error] 5060#0: *135068 FastCGI sent in stderr: “Primary script unknown”
while reading response header from upstream, client: 10.106.1.19,
server: example.com, request: “GET /cms/index.php HTTP/1.0”, upstream:
“fastcgi://unix:/var/run/php53-fpm.sock:”, host: “example.com

However when I modify my hosts file to talk directly to one of my
backend servers I get the 404. I’ll figure out the logs later, but now I
have the answers I’m after and the culprit of my issue.

location @rewrite {
  # Some modules enforce no slash (/) at the end of the URL
  # Else this rewrite block wouldnt be needed (GlobalRedirect)
  rewrite ^/(.*)$ /index.php?q=$1;
}

Thanks for your help.

–julian