Nginx proxy_pass仅部分起作用 [英] Nginx proxy_pass only works partially

查看:145
本文介绍了Nginx proxy_pass仅部分起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下设置

  • 主服务器-称为https://master.com
  • 从服务器-称为https://slave.com
  • Master server - call it https://master.com
  • Slave server - call it https://slave.com

两者都在Ubuntu 16.04上运行Nginx

Both run Nginx on Ubuntu 16.04

在主服务器上,我已经在/etc/nginx/sites-available/default文件中创建了以下配置块

On the master server I have created the following configuration block in my /etc/nginx/sites-available/default file

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;
}

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

A service nginx reload later on master.comand I can do the following

  • 浏览到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中的图像.
  • Browse to https://master.com/test and view the output from slave.com\index.php.
  • Browse to https://master.com/test/test.txtand see the text in the file slave.com\test.txt
  • Browse to https://master/com/test/test.jpg and see the image in the file slave.com\test.jpg.

但是,我不能执行以下任何操作

However, I cannot do any of the following

  • 浏览到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
  • Browse to https://master.com/test/test.phpwhich instead of showing me the output from https://slave.com/test.php shows me a 404 error message
  • Browse to https://master.com/test/adminer/adminer.phpwhich instead of showing me the login screen for the Adminer instance on the slave, https://slave.com/adminer/adminer.phpshows me the login screen for the Adminer instance on master.comi.e. https://master.com/adminer/adminer.php

这显然是因为我在master.com的Nginx配置中缺少某些内容.但是,我看不出那是什么.

This is clearly because I am missing something in my Nginx configuration on master.com. However, I am unable to see what that might be.

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

In the interests of completeness, here is my configuration on both servers:

Ubuntu -16.04.3 Nginx -1.10.3 PHP -7.0.22

Ubuntu - 16.04.3 Nginx - 1.10.3 PHP - 7.0.22

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

I should explain why the ^~ is required since this is not clear from my original question. I have another block setup to handle PHP scripts on master.com.

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最终在本地寻找实际上在slave.com上的.php脚本.避免这种情况的唯一方法是使用^~

Because of the way Nginx processes these directives this block takes priority when it comes to handling .php files and master.com ends up looking locally for .php scripts that are actually on slave.com. The only way to avoid this is to use ^~

推荐答案

您的方法是错误的.在处理/test的块内,将其重写并发送到该块之外.实际上,proxy_pass永远不会发生,因为新URL中没有/test.解决方案很简单,不要使用重写

Your approach is wrong. Inside the block which handles /test your rewrite it and send it out of the block. The proxy_pass never actually happens because the new URL doesn't have /test in it. Solution is simple, don't use rewrite

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地址

Appending / at the end of the location path and also the proxy_pass server will make sure what is after /test/ is sent to your proxy_pass address

编辑1

这是我在发布此答案之前设置的示例测试用例.

Here is a sample test case I had set before posting this answer.

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个位置块之间的区别

Now the results explains the difference between all 4 location blocks

$ 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

As you can see in /test4 url the proxied server only sees /abc/test

这篇关于Nginx proxy_pass仅部分起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆