
家宽封了 80,443 ,服务只能带端口访问
设置 nginx 监听一个高位端口如 2222 指向 443 ,另一个 3333 指向 80
因为非标准端口,没法同时监听 80 和 443
访问带指向 443 的端口 2222 时,如果开了强制 ssl ,只能 https 访问,http 访问时就会报 400 错,因为 http 是 3333 端口监听的,这样在访问时输入就很麻烦了。
怎么才能实现在一个端口访问,http 也能重定向呢,找了几天发现方法
有点骚,但能实现 nginx 只监听 1 个非标端口 http 重定向 https
本质是修改利用 497 错误码重定向指向 https 的地址
客户端请求未使用 HTTPS 协议,但如果您已启用强制 SSL ,并且客户端尝试使用 HTTP 协议访问您的网站,则会收到 HTTP 497 错误。我们这时候就修改 497 的页面指向我们 https 即可
server { listen 2222 ssl; server_name your.site.tld; ssl on; ... error_page 497 https://$host:2222$request_uri; ... } 1 rekulas 2023-05-24 22:45:51 +08:00 我都没理解到你的回路,http 访问报错判断下端口 301 不就行了?是不是想复杂了 |
2 eudemonwind 2023-05-24 22:54:03 +08:00 via Android 扫到你开了 http 直接封宽带 |
3 kingpo OP @rekulas #1 非标准端口你 xxx.com:2222 只能监听 443 ,这时候不能同时监听 80 ,你这时候 http://xxx.com:2222 访问是报 400 ,301 也还是报 400 ;你 80 是通过 3333 ,http://xxx.com:3333 这个才可以 301 过去 https//:xxx.com:2222 ,我默认要访问的是 xxx.com:2222 ,只记一个端口就行 |
4 kingpo OP @eudemonwind #2 没那么严重吧,翻了之前的帖子好多老哥都开端口访问的 |
5 kingpo OP 这里实现的是 1 个端口直接访问 http 和 https 的效果,正常是要两个端口 |
7 kaedeair 2023-05-24 23:26:48 +08:00 这个用 traefik 写两条路由,一条 http ,一条 https ,用相同的 entrypoint ,然后在 http 的路由加个 RedirectSchema 的中间件很容易实现,不必死死抱着 nginx |
12 olaloong 2023-05-24 23:57:18 +08:00 via Android 这样也行啊 我是套了层 haproxy 来端口复用,rdp ssh http https 全在一个端口上 |
13 ochatokori 2023-05-25 00:27:41 +08:00 via Android @rekulas #11 看完你这条我终于看懂楼主想说什么了 |
14 Tink PRO 我理解,就算是没封 80 和 443 ,你 nginx 也得开两个端口呀,只监听 443 不是也不能跳吗 |
15 chronos 2023-05-25 09:12:11 +08:00 @Tink 他这个方案就是只开放一个 https 的端口,当 http 协议访问 https 的端口进来时返回 497 状态码告诉浏览器要使用 https 协议来访问。 |
16 netnr 2023-05-25 09:13:11 +08:00 via Android 我来当大聪明,以下都能正常访问 http://your.site.tld:2222 https://your.site.tld:2222 https 的 2222 端口是正常配置的,http 也能访问是因为触发了 https 的 497 错误码,利用这个错误码来访问 以上有个前提是 80 443 都被封了 |
17 Imr 2023-05-25 09:20:36 +08:00 nginx 自己就有更优雅的解决办法 用 stream 里的 ssl_preread ,类似下面配置(没有验证) stream { upstream http { server 127.0.0.1:80; } upstream https { server 127.0.0.1:443; } map $ssl_preread_protocol $upstream { default https; "" http; } server { listen 2222; listen [::]:2222; proxy_pass $upstream; ssl_preread on; } } |
19 yunyuyuan 2023-05-25 10:16:26 +08:00 贴一下我的,直连 /zerotier 通用配置,好处是打洞的服务也可以用域名+https 访问: server { listen [::]:5678 ssl; listen 443 ssl; listen 80; server_name foo.example.com foo-zto.example.com; error_page 497 https://$host:5678$request_uri; set $whole_url "$scheme://$host"; if ($whole_url ~ ^http://[^.]*-zto) { return https://$host$request_uri; } } * 直连用 http://foo.example.com:5678 ,重定向到 https://foo.example.com:5678 。 * zerotier 用 http://foo-zto.example.com ,可以重定向到 https://foo-zto.example.com 。foo-zto.example.com 解析地址是 vpn 组网的地址 |
20 dandeli0n 2023-05-25 11:04:49 +08:00 说的好,我选择用 stream_ssl_preread 模块,同 #17 |
21 kkocdko 2023-05-25 23:23:42 +08:00 我理解你的意思。HTTP 到 HTTPS 重定向这个问题我研究过,并没有标准答案。 最常见的方法是 80 端口和 443 端口同时监听,重定向用 302 或者 497 都有,对于监听单个非默认端口,Nginx 有使用 stream_ssl_preread 的,楼主的方法我也看到别人用过,并不是首创。 顺便讲一些更深入一点的东西。要区分 HTTP 和 HTTPS ,观察 TCP 连接进来的第一个字节即可。如果第一个字节是 0x16 那就说明对方希望进行 TLS 握手,是 HTTPS ,正常服务。如果不是,那就要当作 HTTP 来解析,并进行重定向。 参考实现如下。这里我还使用了一个偷懒技巧,不解析 HTTP 直接给客户端灌一段 JS 来实现重定向。 https://github.com/kkocdko/ksite/blob/76f8f15b02412fc1bf765517518dd10f8c44fbba/src/tls.rs#L109 |