2

I give below an execerpt of of /etc/nginx/sites-available/default file

server {
        listen 443 ssl;
        server_name example.com;

        root /var/www/html;
        index index.php index.html;

location  / {
             try_files $uri $uri/ = 404;
}

location /rproxy/ {
                  proxy_pass https://example.org:8144/;
}     

location ~ \.php$ {
 try_files $uri = 404;
 fastcgi_split_path_info ^(.+\.php)(/.+)$;
 ....
} 

The example.org:8144 server

has the files and

  • index.php - returns hello World
  • bonjour.php - returns bonjour

Now here is the issue:

If I browse to https://example.com/rproxy it promptly returns hello world - the expected result.

However, if I browse to https://example.com/rproxy/bonjour.php (or even https://example.com/rproxy/index.php) I get a 404 error.

I understand what is happening here. My Nginx configuration is causing the example.com instance of Nginx to attempt to find all *.php files locally (i.e. on example.com) which fails when the file I am seeking is in fact on example.org:8144.

I imagine that there is a relatively simple way to tell Nginx when NOT to attempt to attempt to execute a PHP file - when it is in fact on rproxy. However, my knowledge of Nginx confugration is too limited for me to be able to figure out just how I alter the configuration. I'd be most obliged to anyone who might be tell me how to change the configuration to prevent this from happening.


I should clarify something here:

I need to be able to run PHP scripts on Both SERVERS example.com and example.org.

There is a very easy workaround here - I use a different extension, say php5, for php scripts on the proxied server, example.org. However, that is easily liable to lead to unforseen problems.

DroidOS
  • 8,530
  • 16
  • 99
  • 171
  • ...this is not how nginx config works. Your upstream should be configured to handle the PHP request if that's what you want. Use `$request_uri` to pass what was requested on. – Amelia Mar 23 '15 at 14:46
  • @Amelia - I am not sure I understand your comment but perhaps my question requires some clarification. Just done that. – DroidOS Mar 23 '15 at 14:51

2 Answers2

11

For nginx regexp locations have bigger priority than prefix locations. But

If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.

So try to replace

location /rproxy/ {

with

location ^~ /rproxy/ {
SeriousDron
  • 1,296
  • 9
  • 12
0

The upstream servers you pass things to have no knowledge of your nginx config. Similarly, your nginx has no idea how your upstream should respond to requests. Neither of them will ever care about the other's configuration.

This is a start for actually passing the name of your script on, but there's a bunch of different ways to do it and they all entirely depend on how the upstream is configured. Also, don't use regexes if you can avoid it; there's no point in slowing everything down for no reason.

upstream reverse {
    server example.org:8144;
}

server {
    listen 443 ssl;
    server_name example.com;

    root /var/www/html;
    index index.php index.html;

    location  / {
        try_files $uri $uri/ =404;
    }

    location /rproxy {
        proxy_pass https://reverse/$request_uri;
    }     

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_pass /blah/tmp.sock;
    }
 }

The (not necessarily smart) but neat way is when you define your PHP block to fall back to your upstream instead of =404 (again, this is a terrible idea unless you know what you're doing, but it can be done):

location @proxy {
    proxy_pass https://upstream$request_uri;
}
location ~ \.php$ {
   try_files $uri @proxy;
   fastcgi_split_path_info ^(.+\.php)(/.+)$;
   include fastcgi_params;
   fastcgi_pass /blah/tmp.sock;
}
Amelia
  • 2,967
  • 2
  • 24
  • 39