【问题标题】:Nginx reverse proxy on another web server with redirection另一个带有重定向的 Web 服务器上的 Nginx 反向代理
【发布时间】:2019-09-15 11:07:59
【问题描述】:

系统的组件是
(来源:snag.gy

  • “nginx 服务器”-A
  • “第三方服务器”-B
  • “用户 PC”(浏览器)-C

服务器“A”和用户PC“C”连接在同一网络“网络A”中,但服务器“A”和第3方机器“B”连接在网络“网络B”中。 目标是通过服务器“A”从用户浏览器“C”访问第 3 方机器“B”。为了执行它,服务器“A”应该对第 3 方内容进行反向代理。 在服务器“A”上安装并配置了 Nginx 服务器。反向代理的规则是:

location ~* ^/3rdparty/(.*)___(.*)___(.*)___(.*)$ {
    proxy_pass https://$1.$2.$3.$4?$args;
    proxy_redirect     off;
    proxy_set_header   Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

使用我们想要为 URL 做反向代理的规则: http:///3rdparty/ => https:// 例如:

http:// 192.168.237.208/3rdparty/192___168___237___222 => https://192.168.237.222

实际上,我们希望附加到 URL 的所有内容都被重定向。 例如:

http://192.168.237.208/3rdparty/192___168___237___222/blah/blah => https://192.168.237.222/blah/blah

该配置适用于我们的其他设置,但在这种情况下的问题是:在第 3 方机器“B”上,有另一个 Web 服务器执行一些重定向:

https://192.168.237.222 => https://192.168.237.222/users/sign_in

所以,当我们把想要的 URI 放到浏览器中时,最终的结果是:

http://192.168.237.208/3rdparty/192___168___237___222 

“B”上的网络服务器获取 URL 的主机名并附加重定向规则 (users/sign_in),这导致浏览器正在请求以下 URL:

https://192.168.237.208/users/sign_in

这在服务器“A”上不可用(实际上它在“B”上)=>我们得到了 http 错误代码 302(临时移动)。 是否缺少我们未应用的配置规则?还是应该更新/转发任何其他 http 请求头参数?

【问题讨论】:

    标签: redirect nginx configuration proxy reverse-proxy


    【解决方案1】:

    192.168.237.222 的后端连接对只连接到192.168.237.208 的客户端是透明的

    当服务器B(后端)发回/users/sign_in重定向时,它被反向传播到客户端,客户端将其应用于他连接的服务器,即服务器A(网关/代理),导致错误请求/users/sign_in 上的 192.168.237.208。 您需要记住重定向是由客户端传播回并由客户端处理的,而不是网关/代理。

    我会做如下的事情:

    location ~* ^/3rdparty/([0-9]{1-3})___([0-9]{1-3})___([0-9]{1-3})___([0-9]{1-3})(/.*)?$ {
        proxy_pass https://$1.$2.$3.$4$5$is_args$args;
        proxy_redirect     off;
        proxy_set_header   Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    

    详情:

    1. 修改您的正则表达式以匹配在后端 IP 地址附加 /blah/blah 的请求,并使用另一个变量 ($5) 将它们复制粘贴到 proxy_pass 指令的末尾
    2. 使用$is_args nginx 嵌入变量而不是问号(如果没有参数要传递给后端,请避免在请求中包含它)
    3. 尝试改进正则表达式以匹配 IP 地址编号(快速而肮脏,我为您提供的那个仍然会导致不正确的匹配,但至少比通配符更好)

    现在,您需要将服务器 B (192.168.237.222) 上的客户端重定向到 /3rdparty/192___168___237___222/users/sign_in,这是一个可以针对服务器 A 请求的位置(192.168.237.208,唯一连接到的服务器客户端)并愉快地转发到正确的后端。

    ===========

    您也可以依赖 nginx proxy_redirect 指令,而不是将其设置为关闭,并让您的后端服务器做出像 https://192.168.237.221/users/sign_in 这样的重定向答案。然后proxy_redirect 将允许您针对192.168.237.208 将这些代理答案重写为正确的URI。

    为此,请尝试以下操作(注意,我仍在使用惰性 IP 地址掩码):

        proxy_redirect     ~*^https://([0-9]{3}).([0-9]{3}).([0-9]{3}).([0-9]{3})(/.*)?$ http://192.168.237.208/3rdparty/$1___$2___$3____$4$5;
    

    我想知道 $is_args$args 这样的变量是否在这种情况下起作用:

        proxy_redirect     ~*^https://([0-9]{3}).([0-9]{3}).([0-9]{3}).([0-9]{3})(/.*)?$ http://192.168.237.208/3rdparty/$1___$2___$3____$4$5$is_args$args;
    

    【讨论】:

    • proxy_redirect 的文档明确指出,当使用变量指定 proxy_pass 时,不能使用 'default' 参数,Aleksandar 就是这种情况。我想这就是为什么它被第一手关闭的原因。
    猜你喜欢
    • 2020-09-22
    • 1970-01-01
    • 2018-01-20
    • 2020-04-19
    • 1970-01-01
    • 2014-07-25
    • 2017-07-17
    • 2017-08-16
    • 1970-01-01
    相关资源
    最近更新 更多