nginx单端口支持http和https多协议
nginx单端口支持http和https多协议
home again前情概要:企业系统一开始上线只支持http,后面数据上来了,数据中带有url地址的用的也是http。现在为了安全考虑要升级https,我们知道nginx中一个端口只有一种协议,甲方又只给了一个对外端口,那么历史数据中带有http的地址怎么办?势必会遇到497错误。其实这个问题还算容易解决,直接据库替换也能解决,但是生成的二维码要如何解决?有的还把二维码打印出来了。。。
所以我们要有一个方法,可以在同一个端口既能支持http又能支持https,并且http要强制跳转到https,满足安全需求。nginx的ngx_stream_ssl_preread_module
模块就是用来解决这个问题的:
The ngx_stream_ssl_preread_module module (1.11.5) allows extracting information from the ClientHello message without terminating SSL/TLS, for example, the server name requested through SNI or protocols advertised in ALPN. This module is not built by default, it should be enabled with the –with-stream_ssl_preread_module configuration parameter.
简单一句就是这个模块能够请求时判断请求用的是不是 ssl 协议,以及ssl的协议版本。
一、安装模块
在最新版的nginx中,这个模块默认安装了。我遇到的是用 yum 安装nginx没有 stream 模块。
yum install nginx-mod-stream -y |
nginx模块安装路径在:/etc/nginx/nginx.conf
。然后在nginx.conf配置文件里加载模块:
load_module /usr/lib64/nginx/modules/ngx_stream_module.so; |
但是在新版的nginx中会提示你不需要手动 load_module,因为nginx已经自动加载好了。
二、主配置
在 nginx.conf 配置中加:
stream { |
然后在站点配置文件中:
server { |
上面的含义:访问服务器8080端口,会走到 $ssl_preread_protocol 中,根据映射关系,如果请求头带 ssl 协议,走 https 的server,不然走 http 的server。
跟反向代理不一样,反向代理对外表现的只是 8080 server配置的内容;ssl_preread则是把上有的server给拿了过来。也就是说如果是用http协议访问8080,则8080的server相当于:
server { |
如果https协议访问8080,则其server变成了:
server { |
是不是非常nice😊?这不是相当于一个端口配置了两种协议了么😏?上面在4000 server中配置了http到https的重定向,也就是说无论http还是https协议,最后都走到了https,完美实现需求,历史数据都不是问题了。