You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx经端口转发网关代理后重定向丢失端口的问题求助

解决Nginx代理后重定向丢失公网端口的问题

问题场景

Nginx部署在局域网内,监听80端口,通过企业网关的公网IP+非标准端口(如public_ip:56480 --> local_ip:80)对外提供访问,Nginx将请求代理至本机9000端口的应用。请求流程如下:

  • 客户端请求http://public_ip:56480/
  • 网关将请求转发至内网Nginx的http://local_ip:80/
  • Nginx代理请求至http://localhost:9000/
  • 应用返回302重定向至/secure/login
  • 实际浏览器被重定向至http://public_ip/secure/login(丢失了56480端口),但预期应该是http://public_ip:56480/secure/login

测试输出

wget -S 命令输出

user@machine:~$ wget -S http://x.x.x.x:56480
--2023-03-24 22:16:27--  http://x.x.x.x:56480/
Connecting to x.x.x.x:56480... connected.
HTTP request sent, awaiting response... 
  HTTP/1.1 302 Found
  Server: nginx/1.18.0 (Ubuntu)
  Date: Fri, 24 Mar 2023 21:16:27 GMT
  Content-Type: text/plain; charset=utf-8
  Content-Length: 0
  Connection: keep-alive
  Location: http://x.x.x.x/secure/login
  Set-Cookie: PLAY_ERRORS=; Max-Age=0; Expires=Fri, 24 Mar 2023 21:16:27 GMT; Path=/
  Set-Cookie: PLAY_FLASH=url=%2F; Path=/
  Set-Cookie: PLAY_SESSION=; Max-Age=0; Expires=Fri, 24 Mar 2023 21:16:27 GMT; Path=/
  Cache-Control: no-cache
Location: http://x.x.x.x/secure/login [following]
--2023-03-24 22:16:27--  http://x.x.x.x/secure/login
Connecting to x.x.x.x:80... connected.
............

更新后的 curl -I --location 命令输出

user@host:~$ curl -I --location http://x.x.x.x:56480
HTTP/1.1 302 Found
Server: nginx/1.18.0 (Ubuntu)
Date: Sat, 25 Mar 2023 16:41:08 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Location: http://x.x.x.x/secure/login
Set-Cookie: PLAY_ERRORS=; Max-Age=0; Expires=Sat, 25 Mar 2023 16:41:08 GMT; Path=/
Set-Cookie: PLAY_FLASH=url=%2F; Path=/
Set-Cookie: PLAY_SESSION=; Max-Age=0; Expires=Sat, 25 Mar 2023 16:41:08 GMT; Path=/
Cache-Control: no-cache

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Sat, 25 Mar 2023 16:41:08 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Keep-Alive: timeout=35
Location: https://x.x.x.x/secure/login?__uri=/secure/login&

curl: (51) SSL: no alternative certificate subject name matches target host name 'x.x.x.x'

当前Nginx配置

location / {
    proxy_pass http://localhost:9000;
    proxy_redirect http://localhost:9000/ /;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
}

解决方案

问题核心是网关转发时,Nginx未获取并传递正确的公网端口给后端应用,导致应用生成的重定向URL丢失端口。以下是两种可靠的配置修改方案:

方案1:固定公网端口(端口不变时推荐)

直接在配置中指定公网端口,确保重定向URL和请求头包含正确端口:

location / {
    proxy_pass http://localhost:9000;
    # 替换应用返回的重定向地址,补上公网端口
    proxy_redirect http://x.x.x.x/ http://x.x.x.x:56480/;
    
    # 传递带端口的Host头,让后端应用生成正确的重定向URL
    proxy_set_header Host $host:56480;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    # 传递端口信息给后端应用(如果应用支持读取该头部)
    proxy_set_header X-Forwarded-Port 56480;
}

方案2:动态获取端口(网关传递X-Forwarded-Port时使用)

如果网关会在转发请求时传递X-Forwarded-Port头,可通过变量动态获取端口:

location / {
    proxy_pass http://localhost:9000;
    # 动态替换重定向地址中的端口
    proxy_redirect http://$host/ http://$host:$http_x_forwarded_port/;
    
    # 传递带动态端口的Host头
    proxy_set_header Host $host:$http_x_forwarded_port;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Port $http_x_forwarded_port;
}

内容的提问来源于stack exchange,提问作者ilya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:37:56