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
相关产品推荐
相关产品推荐

