Nginx 重写将流量发送到 IP 地址,而不是 URL

Nginx rewrite sends traffic to IP address, not URL

我将 nginx 设置为 docker 微服务的反向代理。有一个位置块将 url 从 /wrong 重写为 /right:

    server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;
        server_name example.com;

        location /right {
            proxy_pass http://microservice_servers;
        }

        location /wrong {
            rewrite ^/wrong/(\w+) /right/ redirect;
        }
    }

这样做的目的是将 url 从 https://example.com/wrong/otherstuff 重写为 https://example.com/right/otherstuff。 但实际发生的是,它重写为 http://<ip_address>/right/otherstuff.

(一个可能的复杂因素是我无法控制该站点的证书。这些证书由客户端控制,客户端将它们放在我们服务器前面的应用程序网关上。所以我的 nginx 配置只有在端口 80 处理 http 流量,没有来自 443 的 https。我不确定这是否真的相关,但为了以防万一,它是相关的。)

我已经尝试对重写块进行各种更改,包括添加 $server_name、将标志更改为 last(return 是正确的内容但没有更改url),并将标志更改为 break(这不是 return 预期的内容)。

知道这里发生了什么吗?

默认情况下,您的 rewrite...redirect 语句将生成 302 响应,其中包含在 HTTP 位置响应 header.

中指定的完整 URL

您可以使用 curl -I https://example.com/wrong/otherstuff 来确认这一点。

Nginx根据原请求填写协议和域名。此 server 块通过 http 接收请求,我们可以从您的问题推断主机 header 使用其 IP 地址。

您需要在 rewrite 语句中指定完整的 URL:

rewrite ^/wrong/(\w+) https://example.com/right/ redirect;

或者,使用相对 URLs:

absolute_redirect off;

详情见this document