Nginx配置在一个端口下,同时支持http与https两种协议 续集
|
admin
2025年12月10日 0:27
本文热度 11
|
上篇文章【Nginx】设置https和http同时使用同一个端口访问,并且访问http跳转到https,是利用 497代码进行跳转。
较新版本 Nginx 的 stream 模块,支持同一个端口进行http和https分流
nginx配置在一个端口下,同时支持http与https两种协议
Nginx 不支持 在 同一个端口 同时提供 HTTP 和 HTTPS 服务,原因如下:
解决方案
虽然 Nginx 本身不支持 HTTP 和 HTTPS 共享同一端口,但你可以使用 SSL 预读(SSL Preread) 技术,通过 Nginx 的 stream 模块在 同一端口 上区分 HTTP 和 HTTPS 流量。
配置方式:使用 stream 模块监听 443 端口并区分 HTTP/HTTPS
# 在 http 之外的全局配置中
stream {
map $ssl_preread_protocol $name {
"" http_backend; # 没有 TLS 的是 HTTP
default https_backend; # 有 TLS 的是 HTTPS
}
upstream http_backend {
server 127.0.0.1:8080; # HTTP 服务器
}
upstream https_backend {
server 127.0.0.1:8443; # HTTPS 服务器
}
server {
listen 443;
proxy_pass $name;
ssl_preread on;
}
}
http {
server {
listen 8080;
server_name www.hqyman.cn;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
server {
listen 8443 ssl;
server_name www.hqyman.cn;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
}
工作原理
stream 监听 443 端口
使用 ssl_preread 读取数据流,判断是否是 HTTPS(即是否有 TLS 握手)。
如果是 HTTP,转发到 http_backend(127.0.0.1:8080)。
如果是 HTTPS,转发到 https_backend(127.0.0.1:8443)。
http {} 配置 HTTP 和 HTTPS
最终效果
这样,你就能在 一个端口(443) 上同时支持 HTTP 和 HTTPS 访问! 🎯🚀
同一端口(443)支持 HTTP 和 HTTPS 访问的 Nginx 实现原理
Nginx 通过 stream 模块 和 ssl_preread 技术,在 443 端口 自动区分 HTTP 和 HTTPS,并将请求转发到不同的后台端口(8080 和 8443)。
📌 主要技术点
1. stream 模块
2. ssl_preread on;
3. map 变量映射
map $ssl_preread_protocol $proxy_backend {
"" http_backend; # 没有 TLS 的是 HTTP
default https_backend; # 有 TLS 的是 HTTPS}
4. stream 服务器配置
server
{
listen 443;
proxy_pass $proxy_backend;
ssl_preread on;
}
📌 访问流程
🟢 情况 1:客户端访问 HTTP
curl -v http://www.hqyman.cn:443
客户端发送 HTTP 请求(明文)
Nginx ssl_preread 检测到是 HTTP
Nginx map 规则匹配:$ssl_preread_protocol 为空 → 选择 http_backend
代理到 127.0.0.1:8080(HTTP 服务器)
服务器返回 HTTP 响应
🔵 情况 2:客户端访问 HTTPS
curl -v https://www.hqyman.cn:443
客户端发送 TLS ClientHello 握手包
Nginx ssl_preread 读取 TLS 协议
Nginx map 规则匹配:发现是 HTTPS → 选择 https_backend
代理到 127.0.0.1:8443(HTTPS 服务器)
服务器继续握手并建立 HTTPS 连接
📌 为什么要这样做?
默认情况下,Nginx 不能在同一端口同时处理 HTTP 和 HTTPS
适用于负载均衡或网关
📌 方案优缺点
| 优点 | 缺点 |
|---|
| 允许 HTTP 和 HTTPS 共用 443 端口 | stream 只能代理 TCP 层,无法解析 HTTP 请求路径 |
ssl_preread | |
| 兼容性好 | 需要额外的 http {} 服务器监听 8080 / 8443 |
📌 总结
✅ 通过 stream + ssl_preread,Nginx 无需额外端口 就能在 443 端口同时支持 HTTP 和 HTTPS。
✅ 适用于负载均衡、网关、同一 IP 端口共用的场景。
✅ 高效,无需解密 HTTPS,直接转发 TCP 流量。
🚨 缺点:无法做 HTTP → HTTPS 自动跳转,但可以用前端 JS 或 meta refresh 解决。
这个方案特别适合 👉 企业级 Nginx 反向代理、云服务器、Kubernetes Ingress 网关 🚀
阅读原文:原文链接
该文章在 2025/12/10 18:50:16 编辑过