nginx反向代理多个位置

Ser*_* B. 1 nginx reverse-proxy

我想为多个应用程序制作一个反向代理。
像这样的东西:

https://proxyip/app1 -> https://10.10.0.1/
https://proxyip/app2 -> https://10.10.0.2/
etc.
Run Code Online (Sandbox Code Playgroud)

目前,我的配置是:

server {
    listen 443 ssl;
    server_name _;

    ssl_certificate     /etc/nginx/cert.crt;
    ssl_certificate_key /etc/nginx/cert.key;

    proxy_set_header    X-Real-IP               $remote_addr;
    proxy_set_header    Host                    $host;
    proxy_set_header    X-Forwarded-For         $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto       $scheme;

    client_max_body_size 0;

    error_log   syslog:server=unix:/dev/log;
    access_log  syslog:server=unix:/dev/log;

    location /app1/ {
        proxy_pass https://10.10.0.1/;
    }

    location /app2/ {
        proxy_pass https://10.10.0.2/;
    }

    location ~ /\. {
        deny all;
    }
}
Run Code Online (Sandbox Code Playgroud)

但没有任何作用。
当我转到https://proxyip/app1它时,它会将我重定向到https://proxyip/Account/login404。它应该转到https://proxyip/app1/Account/login. 这是日志:

Jun 06 15:05:44 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:05:44 +0300] "GET /app1 HTTP/1.1" 301 185 "-" "BrowserUserAgent"
Jun 06 15:05:44 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:05:44 +0300] "GET /app1/ HTTP/1.1" 302 0 "-" "BrowserUserAgent"
Jun 06 15:05:44 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:05:44 +0300] "GET /Account/Login?ReturnUrl=%2F HTTP/1.1" 404 571 "-" "BrowserUserAgent"
Jun 06 15:16:32 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:16:32 +0300] "GET /app1 HTTP/1.1" 301 185 "-" "BrowserUserAgent"
Jun 06 15:16:32 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:16:32 +0300] "GET /app1/ HTTP/1.1" 302 0 "-" "BrowserUserAgent"
Jun 06 15:16:32 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:16:32 +0300] "GET /Account/Login?ReturnUrl=%2F HTTP/1.1" 404 571 "-" "BrowserUserAgent"
Run Code Online (Sandbox Code Playgroud)

当我/从 proxy_pass 中删除尾随时,我从应用程序本身获得了 404。
日志:

Jun 06 15:21:42 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:42 +0300] "GET /app1 HTTP/1.1" 301 185 "-" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /app1/ HTTP/1.1" 404 1831 "-" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /Content/bundleCss HTTP/1.1" 404 571 "https://proxyip/app1/" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /Content/themes/base/jquery HTTP/1.1" 404 571 "https://proxyip/app1/" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /bundles/jquery HTTP/1.1" 404 571 "https://proxyip/app1/" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /bundles/bootstrap HTTP/1.1" 404 571 "https://proxyip/app1/" "BrowserUserAgent"
Jun 06 15:21:52 my_proxy nginx[3829]: my_proxy nginx: 192.168.0.10 - - [06/Jun/2017:15:21:52 +0300] "GET /bundles/extlibs HTTP/1.1" 404 571 "https://proxyip/app1/" "BrowserUserAgent"
Run Code Online (Sandbox Code Playgroud)

你能帮助我吗?

@Tero-Kilkanen:
我已经按照你说的做了:

location ~^/app1(.*)$ {
proxy_pass https://10.10.0.1$1;
}
Run Code Online (Sandbox Code Playgroud)

但还是什么都没有。这是日志:

Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /app1 HTTP/1.1" 404 1831 "-" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /Content/bundleCss HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/modernizr HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/jquery HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/bootstrap HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/extlibs HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /Content/themes/base/jquery HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/jquery HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/bootstrap HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Jun 08 10:07:33 my-proxy nginx[8882]: my-proxy nginx: 192.168.0.10 - - [08/Jun/2017:10:07:33 +0300] "GET /bundles/extlibs HTTP/1.1" 404 571 "https://10.10.0.1/app1" "UserAgent"
Run Code Online (Sandbox Code Playgroud)

应用程序 IIS 登录错误:

2017-06-08 12:41:27.264 /Error/NotFound - "E:\wwwroot\MyAppPool\Error\NotFound" 404 "app-server" - 0 2105 587
2017-06-08 12:41:27.264 /app1 - "E:\wwwroot\MyAppPool\app1" 404 "app-server" - 0 2105 587
Run Code Online (Sandbox Code Playgroud)

连接成功时的应用程序 IIS 日志(无代理):

2017-06-09 06:46:36.934 / - "E:\wwwroot\MyAppPool" 302 "app-server" - 0 267 612
2017-06-09 06:46:44.673 /Account/Login ReturnUrl=%2F "E:\wwwroot\MyAppPool\Account\Login" 200 "app-server" - 0 17530 743
2017-06-09 06:46:44.878 /bundles/modernizr v=inCVuEFe6J4Q07A0AcRsbJic_UE5MwpRMNGcOtk94TE1 "E:\wwwroot\MyAppPool\bundles\modernizr" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 11477 634
2017-06-09 06:46:44.892 /bundles/jquery v=Z_3sx_Om2qdGQNW4A5Csgy0WZLaXSa4Eg8ukUl26_Qw1 "E:\wwwroot\MyAppPool\bundles\jquery" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 96542 631
2017-06-09 06:46:44.905 /Scripts/app/signatureHelper.js - "E:\wwwroot\MyAppPool\Scripts\app\signatureHelper.js" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 10309 600
2017-06-09 06:46:44.920 /bundles/bootstrap v=H2j5HUSj46jlSq1Se76I-uTAYq6y_MryNeOkhmo3adE1 "E:\wwwroot\MyAppPool\bundles\bootstrap" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 40031 634
2017-06-09 06:46:45.234 /Content/bundleCss v=QR3LEdUKMTwhOusb6Ic-dRnsOi-C89Qfl8hxv_73Pr41 "E:\wwwroot\MyAppPool\Content\bundleCss" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 679954 649
2017-06-09 06:46:45.417 /Content/themes/base/jquery v=GZKJzOOlsTUy2AD4HAw4TdqockAuF9srZRUOXVJLoJQ1 "E:\wwwroot\MyAppPool\Content\themes\base\jquery" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 45215 658
2017-06-09 06:46:45.456 /bundles/extlibs v=4Ziz4fY8b9xGa5ThFN7ipb8OedxUWcMRvcf0slVL57E1 "E:\wwwroot\MyAppPool\bundles\extlibs" 200 "app-server" "https://10.10.0.1/Account/Login?ReturnUrl=%2F" 0 6293867 632
2017-06-09 06:46:46.451 /fonts/glyphicons-halflings-regular.woff - "E:\wwwroot\MyAppPool\fonts\glyphicons-halflings-regular.woff" 200 "app-server" "https://10.10.0.1/Content/bundleCss?v=QR3LEdUKMTwhOusb6Ic-dRnsOi-C89Qfl8hxv_73Pr41" 0 23690 676
Run Code Online (Sandbox Code Playgroud)

Ter*_*nen 5

nginx proxy_pass文档指出,当proxy_pass使用 URI 指定时,将使用 proxy_pass 目标并且location不使用路径。

例子:

location /app1 {
    proxy_pass http://proxy.example.com/app1;
}
Run Code Online (Sandbox Code Playgroud)

使用此配置,所有以 开头的请求http://example.com/app1将以http://proxy.example.com/app1. 这包括http://example.com/app1/dir1.

解决这个问题的解决方案是在location指令中使用正则表达式捕获,并在proxy_pass目标中使用捕获的变量,如下所示:

location ~ ^/app1(.*)$ {
    proxy_pass http://proxy.example.com$1;
}
Run Code Online (Sandbox Code Playgroud)

这将使 nginx 将字符串附加app1proxy_pass目标行之后。


小智 1

您的设置应该可以在 proxy_pass 指令中没有最后一个斜杠 / 的情况下运行。

您需要考虑的一件事是,当代理流量通过时,位置路径也将被传递,这意味着当有人请求时:

https://proxyip/app1,nginx会向后端请求以下url:https://10.10.0.1/app1

这将导致:

https://proxyip/app1  => https://10.10.0.1/app1 
https://proxyip/app2  => https://10.10.0.2/app2
Run Code Online (Sandbox Code Playgroud)

这里的解决方案是:

  1. 在后端服务器上创建自定义重写配置,您将在其中将 appX 重写为 /
  2. 将您的应用移动到后端服务器特定位置对应的子文件夹中。