Nginx proxy_pass仅部分工作

时间:2017-09-11 11:15:37

标签: nginx reverse-proxy php-7

我有以下设置

  • 主服务器 - 将其称为https://master.com
  • 从属服务器 - 将其称为https://slave.com

两者都在Ubuntu 16.04上运行Nginx

在主服务器上,我在/etc/nginx/sites-available/default文件

中创建了以下配置块
location /test
{
 rewrite ^/test(.*) /$1 break;
 proxy_pass https://slave.com;
 proxy_read_timeout 240;
 proxy_redirect off;
 proxy_buffering off;
 proxy_set_header Host $host;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto https;
}

service nginx reload稍后master.com,我可以执行以下操作

  • 浏览至https://master.com/test并查看slave.com\index.php的输出。
  • 浏览至https://master.com/test/test.txt并查看文件slave.com\test.txt
  • 中的文字
  • 浏览至https://master/com/test/test.jpg并查看文件slave.com\test.jpg中的图片。

但是,我无法执行以下任何操作

  • 浏览https://master.com/test/test.php而不是向我显示https://slave.com/test.php的输出,向我显示404错误消息
  • 浏览到https://master.com/test/adminer/adminer.php而不是向我显示从属设备上的Adminer实例的登录屏幕,https://slave.com/adminer/adminer.php向我显示master.com上Adminer实例的登录屏幕。 https://master.com/adminer/adminer.php

这显然是因为我在master.com的Nginx配置中遗漏了一些东西。但是,我无法看到它可能是什么。

为了完整性,这是我在两台服务器上的配置:

Ubuntu - 16.04.3 Nginx - 1.10.3 PHP - 7.0.22

我应该解释为什么^~是必需的,因为我原来的问题并不清楚。我有另一个块设置来处理master.com上的PHP脚本。

location ~ \.php$ 
{
 try_files $uri =404;
 fastcgi_split_path_info ^(.+\.php)(/.+)$;
 fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
 fastcgi_index index.php;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 include fastcgi_params;
}

由于Nginx处理这些指令的方式,这个块在处理.php文件时具有优先权,而master.com最终在本地查找实际在{{1}上的.php脚本}}。避免这种情况的唯一方法是使用slave.com

1 个答案:

答案 0 :(得分:3)

你的做法是错误的。处理/test的块内部重写并将其发送出块。 proxy_pass实际上从未发生过,因为新网址中没有/test。解决方案很简单,不要使用重写

location /test/
{
 proxy_pass https://slave.com/;
 proxy_read_timeout 240;
 proxy_redirect off;
 proxy_buffering off;
 proxy_set_header Host $host;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto https;
}

在位置路径末尾添加/proxy_pass服务器还会确保将/test/发送到proxy_pass地址之后的内容

修改-1

以下是我在发布此答案之前设置的示例测试用例。

events {
    worker_connections  1024;
}
http {
server {
   listen 80;

   location /test1 {
     proxy_pass http://127.0.0.1:81;
   }

   location /test2 {
     proxy_pass http://127.0.0.1:81/;
   }

   location /test3/ {
     proxy_pass http://127.0.0.1:81;
   }

   location /test4/ {
     proxy_pass http://127.0.0.1:81/;
   }

}

server {
   listen 81;

   location / {
     echo "$request_uri";
   }
}
}

现在结果解释了所有4个位置块之间的区别

$ curl http://192.168.33.100/test1/abc/test
/test1/abc/test

$ curl http://192.168.33.100/test2/abc/test
//abc/test

$ curl http://192.168.33.100/test3/abc/test
/test3/abc/test

$ curl http://192.168.33.100/test4/abc/test
/abc/test

正如您在/test4网址中看到的那样,代理服务器只能看到/abc/test