请教一下大佬们,设置的四层代理如下:
stream {
map $ssl_preread_server_name $name {
www.example.com home; # Home Page
default defaultpage;
}
upstream home {
server 127.0.0.1:44301;
}
upstream defaultpage {
server 127.0.0.1:44300;
}
server {
listen 443 reuseport;
listen [::]:443 reuseport;
proxy_pass $name;
ssl_preread on;
}
}
在七层代理的 server 里监听 44301 ,使用 location /home/ 来指向部署的服务。 实际访问时,如果访问 https://www.example.com/home/ 可以正常访问。 但访问 https://www.example.com/home 就会跳转到 https://www.example.com:44301/home/
由于部署的项目本身不支持自定义路径,修改源码工程量太大,已放弃通过 locaion 来指向服务的方式。
不过我还是很想知道,为啥会暴露 44301 的端口,原理是啥,是在哪个环节暴露的,应该怎么避免这个问题?
1
phpfpm 2023-03-21 23:28:54 +08:00
敌人在内部
|
2
deorth 2023-03-22 00:18:00 +08:00 via Android
站点本身有 301 ,你这种情况只能放弃 tcp 反代改用 http 反代
|
3
icaolei OP @deorth #2 有点疑惑,站点本身应该不知道我在 nginx 监听的端口是多少啊,站点的 301 应该也是发送到 443 端口,最多也是发送到站点本身部署端口(例如使用 docker 将站点容器部署在 8000 ),讲道理的话站点的 301 应该还是会走到四层代理去,然后再走七层代理,最多也是走到 8000 去,为啥会直接 301 到 44301 端口呢?
|
4
NewYear 2023-03-22 08:53:44 +08:00
你想歪了,跳转行为有 2 个发起方,一个是通过浏览器,相对路径,另一个是通过服务器,绝对路径。
如果你只考虑转发流量,不替换服务器发给客户端的内容,就是现在的结果。 解决办法就是要替换内容,涉及到 HTTPS ,这个就麻烦了,自己研究一下吧 |
5
koloonps 2023-03-22 09:01:47 +08:00
nginx 只是一个 http clent 。服务监听到自己的端口为 44301 直接发起重定向
|
6
Judoon 2023-03-22 09:29:00 +08:00
我测了一下,nginx 的规则中,location 后面跟的 path 末尾如果加 / ,则在访问 https://www.example.com/home 时 nginx 本身会写一个 301 到 https://www.example.com/home/ 和后端服务无关。
把这个路径后面的 / 去掉大概率就好了。如果不是这个原因,应该也可以通过其他方式解决 301 后的端口问题 |
7
winglight2016 2023-03-22 10:22:05 +08:00
不了解四层转发,不过,SSL 只跟最前端设置有关,内部服务使用 http 就可以了。
lz 这个问题,应该是把反向代理设置成了 301 重定向导致的,统一使用 proxypass 就可以了——切记上游服务不要使用 https |
8
coolloves 2023-03-22 10:59:49 +08:00
@icaolei proxy_redirect http://upstream-server:44301/ https://example.com/; 更改重定向地址试试
|
9
icaolei OP @coolloves #8 谢谢,这个是打补丁的做法,肯定是可以的。类似的做法还有不用 location ,直接用三级域名。但是我更想了解原理和如何避免这个问题,所以还是要研究下。
|
10
icaolei OP @koloonps #5 请教一下,服务在 docker 容器里面,容器内外都是 8000 端口,这样容器化了它也能监听到流量是从 44301 来的吗?
|
11
icaolei OP @winglight2016 #7 七层代理里面已经是用的 proxypass 了,感觉不像是 proxypass 导致的问题。
|
12
yinmin 2023-03-23 12:17:15 +08:00 1
正解是:监听 44301 网站配置的问题,加下面一行即可解决问题。
absolute_redirect off; 另外,你的 nginx 配置还有 2 个优化的地方。 1.网站程序无法获得浏览器的 IP 地址,解决的方法是启用 proxy_protocol 协议。调整如下: server { listen 443 reuseport; listen [::]:443 reuseport; proxy_pass $name; proxy_protocol on; ssl_preread on; } 然后监听 44301 的 listen 改成: listen 44301 ssl http2 proxy_protocol; 2.建议去掉 map 的 default 行,提升 tls 安全。客户端必须提供正确域名才会建立 tls 连接,能抵御网络盲扫后攻击。 |
13
yinmin 2023-03-23 12:30:23 +08:00 1
@icaolei 服务在容器里,有 3 种配置方法:
(1) bridge 网络,-p 127.0.0.1:8000:8000 ,容器内的服务绑定到 0.0.0.0:8000, docker 映射到主机 127.0.0.1:8000 ,nginx 直接 proxy 到 127.0.0.1:8000 (2) host 网络,不设-p 参数,容器内服务绑定到 127.0.0.1:8000 ,nginx 直接 proxy 到 127.0.0.1:8000 (3) 建立 docker 虚拟内网,容器使用虚拟内网固定 ip 地址,不设-p 参数,容器内服务绑定到内网 ip:8000 ,nginx 直接 proxy 到内网 ip:8000 方式一:比较常见,但在超大流量下会有性能问题 方式二:高性能,适合超大流量使用 方式三:如果部署多个容器联动(程序容器、数据库容器、redis 容器等),所有容器都使用虚拟内网固定 ip ,都不设-p 参数,部署方便且安全。 |