NGINX使用相同TCP端口同时服务HTTP和HTTPS

九月 01, 2024 [网络与安全] #Git #obsidian #开源许可 #网络

NGINX使用相同TCP端口同时服务HTTP和HTTPS

前面有提到过,在nginx中可以用error_page 497来重定向使用http到使用https协议的TCP端口。但是利用497做内部重定向需要跳转location,在一些复杂的NGINX场景下处理流量会比较麻烦。

文章传送门:

另外还有一种方法是先用stream读取协议类型,再内部转发到各自服务端口的用法。缺点是流量会在NGINX内部流转两次,效率不够高。

文章传送门 https://www.huangyuexiang.com/2020/05/09/Nginx配置一个端口同时处理多种协议/

最近Tengine有一个新的提交,实现了相同TCP端口同时服务HTTP和HTTPS:

https://github.com/alibaba/tengine/commit/573a423e26b2dc84ea86c9b883617cbd3bae4a75

查看该提交源码,发现实现起来挺简单的,于是移植到了原生NGINX(OpenResty也能正常使用),并且制作了一个针对NGINX-1.21.4版本的补丁

https://git.hanada.info/hanada/ngx_core_patches/-/blob/main/ngx_http_listen_https_allow_http_1.21.4%2B.patch

版本兼容性:该补丁兼容 Nginx 1.21.4 及更高版本,包括 OpenResty 环境。

传统上,Nginx 在不同端口处理 HTTP 和 HTTPS 流量:端口 80 用于 HTTP,端口 443 用于 HTTPS。ngx_http_listen_https_allow_http 补丁打破了这一常规,允许 Nginx 配置中的一个服务器块在同一端口上接受 HTTP 和 HTTPS 请求。

语法:listen address[:port] [ssl] [https_allow_http] …; 默认值:listen *:80 | *:8000; 上下文:server

server {
  listen 443 ssl https_allow_http;
  ssl_certificate /path/to/cert.pem;
  ssl_certificate_key /path/to/key.pem;
  # ... 其他配置 ...
}

在此配置中,服务器块设置为在端口 443(HTTPS 默认端口)监听,并启用了 SSL。https_allow_http 参数允许同一端口处理标准 HTTP 请求。

https请求

http请求

  1. 灵活性:此补丁在网络环境对端口有严格限制的场景下尤其有用,例如,某些网络环境仅允许少数端口用于外部通信。
  2. 配置简化:对于 HTTP 和 HTTPS 需要进行类似处理的情况,单端口管理可以简化配置。

虽然这个功能增加了灵活性,但正确处理安全隐患至关重要:

此补丁源自 Tengine,补丁版权归属Alibaba Group Holding Limited所有,请遵循BSD-2-Clause License开源许可证使用本补丁。

https://github.com/alibaba/tengine/blob/master/LICENSE

该补丁已在 Nginx 1.21.4 版本上进行了测试和验证。有兴趣的访客可以将此补丁应用到 Nginx 设置中,并作为自定义 Nginx 构建的一部分进行编译。


注意:与任何自定义补丁一样,在部署到生产环境前,建议进行彻底测试,以确保与现有配置和第三方模块的兼容性。