
需求:
通过一个端口9190可以实现http和https同时访问
例如:
http://10.189.189.189:9190/#/public/login
https://10.189.189.189:9190/#/public/login
真实的地址是:
http协议:http://10.189.189.189:9997/#/public/login

https协议:http://10.189.189.189:28443/#/public/login

分析:
1、Nginx 本身无法使用1个端口同时处理 HTTP 和 HTTPS 请求
2、可以通过 stream 模块 + ssl_preread 实现:
监听同一个端口9190,自动识别客户端发来的是 HTTP 还是 HTTPS流量,并分别转发给后端的 HTTP(9997端口) 服务和 HTTPS (28443端口) 服务
3、这样就实现了只用1个端口可以同时访问http和https页面,这不属于“Nginx 在同一端口提供两种协议”,而是通过四层代理智能分流。
4、需要使用新版本的nginx,并启用 --with-stream 和 --with-stream_ssl_preread_module模块
具体操作:
1、检查nginx是否启用--with-stream 和 --with-stream_ssl_preread_module模块
/data/server/nginx/sbin/nginx -V 2>&1 | grep -o 'with-stream\|with-stream_ssl_preread_module'
2、重新编译nginx,添加模块
/data/server/nginx/sbin/nginx -V #查看nginx编译参数,如果未启用,需要添加上面两个模块,重新编译nginx
./configure --prefix=/data/server/nginx --user=www --group=www --without-http_memcached_module --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-http_realip_module --with-stream --with-stream_ssl_preread_module --with-http_flv_module --with-http_mp4_module --http-client-body-temp-path=/data/server/nginx/client --http-proxy-temp-path=/data/server/nginx/proxy --http-fastcgi-temp-path=/data/server/nginx/fcgi --http-uwsgi-temp-path=/data/server/nginx/uwsgi --with-openssl=/data/server/nginx/packages/openssl-1.1.1w --with-zlib=/data/server/nginx/packages/zlib-1.3 --with-pcre=/data/server/nginx/packages/pcre-8.45 --add-module=../ngx_cache_purge-2.3
make #重新编译不需要执行make install
3、备份旧文件
mv /data/server/nginx/sbin/nginx /data/server/nginx/sbin/nginx.old
4、使用新文件替换旧文件
cp /data/server/nginx/packages/nginx-1.24.0/objs/nginx /data/server/nginx/sbin/nginx
5、检查nginx配置文件是否正常运行
/data/server/nginx/sbin/nginx -t
6、最后重新启动nginx,再次检查模块
/data/server/nginx/sbin/nginx -V 2>&1 | grep -o 'with-stream\|with-stream_ssl_preread_module'
with-stream
with-stream_ssl_preread_module
![]()
已经可以看到这2个模块了
7、修改nginx配置文件
cp /data/server/nginx/conf/nginx.conf /data/server/nginx/conf/nginx.conf.bak
7.1在nginx主配置文件引入stream模块
mkdir -p /data/server/nginx/conf/stream #创建目录
vi /data/server/nginx/conf/nginx.conf #stream块必须在顶层,和 http 是平级的,不能嵌套在 http 内
stream{
include /data/server/nginx/conf/stream/*.conf;
}
:wq! #保存退出

7.2创建stream规则
cd /data/server/nginx/conf/stream
vi 9190.conf #规则名字自己定义
log_format stream_log '$remote_addr [$time_local] -> $upstream_addr ($ssl_preread_protocol)';
upstream backend_http {
server 127.0.0.1:9997; # HTTP 后端
}
upstream backend_https {
server 127.0.0.1:28443; # HTTPS 后端
}
map $ssl_preread_protocol $backend {
"" backend_http; # 非TLS流量 → HTTP
default backend_https; # TLS流量 → HTTPS
}
# 监听统一入口端口9190
server {
listen 9190 ; # 修改为你希望的统一端口9190
listen [::]:9190 ;
proxy_pass $backend;
ssl_preread on; #必须启用,否则 $ssl_preread_protocol 为空
proxy_timeout 5s;
proxy_connect_timeout 5s;
access_log /data/server/nginx/logs/stream-access.log stream_log;
}
:wq! #保存退出
最后重启nginx服务

7.3进行测试
浏览器均能打开下面的地址,说明配置成功。
http://10.189.189.189:9190/#/public/login

https://10.189.189.189:9190/#/public/login

扩展阅读:
通过stream 模块 + ssl_preread模块,必须使用浏览器安全端口,否则浏览器打不开页面
例如上面的端口如果使用10080端口,crul 从命令行可以可以访问,但是通过浏览器无法访问页面。

浏览器安全端口列表
一、完全安全的端口(推荐使用)
HTTP标准端口:
80 - HTTP协议默认端口
8080 - HTTP备用端口(最常用)
8000 - 开发常用端口
8888 - 开发常用端口
HTTPS标准端口:
443 - HTTPS协议默认端口
8443 - HTTPS备用端口
其他常用安全端口:
3000-3999(前端开发常用)
5000-5999(后端开发常用)
7000-7999(应用服务)
9000-9999(管理界面)
至此,Nginx 单端口兼容 HTTP 与 HTTPS:基于 stream 模块与 ssl_preread 的智能分流方案完成。

②190706903
③203744115
