一个骚操作, nginx 只监听 1 个非标端口就实现 http 重定向 https

358 天前
 kingpo

家宽封了 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;
  ...
}
2517 次点击
所在节点    分享发现
22 条回复
kkocdko
357 天前
我理解你的意思。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
kingpo
356 天前
@kkocdko #21 学到了,不过我这个也不是我首创,也是网上找到的一种方案,当然他是不够优雅的,但是对于个人的低频使用场景来说它足够简单和能满足需求已经足够

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/942682

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX