前置条件: nginx-1.15.2 以上
1.15.2 版本新增了 $ssl_preread_protocol 变量,通过该变量可以使用 stream 反向代理时预先判断连接是否为SSL/TLS协议或者为非SSL/TLS协议,从而实现同一个端口来转发不同的业务,
stream_ssl_preread
模块检查初始ClientHello
在SSL或TLS连接消息,并且提取其可用于管理连接几个值。$ssl_preread_protocol
版本1.15.2中添加的变量从消息client_version
字段中捕获最新的SSL / TLS版本号ClientHello
。如果消息中supported_versions
存在扩展名ClientHello
,则变量设置为TLSv1.2/TLSv1.3
。
实例:在一台反向代理服务器上运行Nginx,并监听443端口,后端有两组服务,一个为HTTPS(开启TLS1.2/1.3)网站服务,另一个为SSH 服务,我们要实现这两组服务运行在同一个端口上(配置的443端口)--入口请求由Nginx自动区分。
为简便,我这时直接使用 docker环境
nginx 版本
# docker exec -it nginx nginx -V nginx version: nginx/1.15.10 built by gcc 8.2.0 (Alpine 8.2.0) built with OpenSSL 1.1.1b 26 Feb 2019 ...<省略若干行>...
目录文件
# tree ./nginx-with-L4-reuse/ ./nginx-with-L4-reuse/ ├── config │ └── nginx │ ├── conf.d │ │ └── default.conf │ ├── fastcgi.conf │ ├── fastcgi_params │ ├── mime.types │ └── nginx.conf └── docker-compose.yaml 3 directories, 6 files
docker-compose.yaml
# docker-compose.yaml version: "2.4" services: nginx: container_name: nginx image: nginx:alpine network_mode: host volumes: - ./config/nginx:/etc/nginx/:ro ports: - "443:443" restart: always
nginx.conf
user nginx; worker_processes 2; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } stream { log_format stream '{"@access_time":"$time_iso8601",' '"clientip":"$remote_addr",' '"pid":$pid,' '"pro":"$protocol",' '"ssl_pro": "$ssl_preread_protocol"', '"pro":"$protocol",' '"stus":$status,' '"sent":$bytes_sent,' '"recv":$bytes_received,' '"sess_time":$session_time,' '"up_addr":"$upstream_addr",' '"up_sent":$upstream_bytes_sent,' '"up_recv":$upstream_bytes_received,' '"up_conn_time":$upstream_connect_time,' '"up_resp_time":"$upstream_first_byte_time",' '"up_sess_time":$upstream_session_time}'; upstream ssh { server 192.168.50.212:22; } upstream web { server 192.168.50.215:443; } map $ssl_preread_protocol $upstream { default ssh; "TLSv1.2" web; "TLSv1.3" web; } # SSH and SSL on the same port server { listen 443; proxy_pass $upstream; ssl_preread on; access_log /var/log/nginx/stream_443.log stream; } }
启用nginx 服务
docker-compose up -d
客户端分别发起HTTPS与SSH请求
TLS
# curl -I -H "Host: xx.com" https://127.0.0.1/ -k HTTP/1.1 200 OK Server: nginx Date: Wed, 03 Apr 2019 14:23:11 GMT Content-Type: text/html Content-Length: 561 Last-Modified: Tue, 19 Mar 2019 02:38:29 GMT Connection: keep-alive ETag: "5c905625-231" Strict-Transport-Security: max-age=15768000 Accept-Ranges: bytes
* SSH ``` # ssh 127.0.0.1 -p 443
Last login: Wed Apr 3 21:54:52 2019 from 192.168.50.212
```
分别对应的请求日志
HTTPS
{ "@access_time": "2019-04-03T13:54:45+00:00", "clientip": "127.0.0.1", "pid": 7, "pro": "TCP", "ssl_pro": "TLSv1.2", "stus": 200, "sent": 5384, "recv": 266, "sess_time": 0.122, "up_addr": "192.168.50.215:443", "up_sent": 423, "up_recv": 5384, "up_conn_time": 0.001, "up_resp_time": "0.001", "up_sess_time": 0.012 }
SSH
{ "@access_time": "2019-04-03T13:54:53+00:00", "clientip": "127.0.0.1", "pid": 7, "pro": "TCP", "ssl_pro": "-", "stus": 200, "sent": 3115, "recv": 3888, "sess_time": 1.288, "up_addr": "192.168.50.212:22", "up_sent": 3911, "up_recv": 3115, "up_conn_time": 0, "up_resp_time": "0.008", "up_sess_time": 1.287 }
$ssl_preread_protocol 实现IP层实现了不同业务配置,在某种需求上很有意义--虽然存在功能限制。然而Tengine-2.3.0 已经实现的IP层基于域名转发,或许这一特性会引入到Nginx。
资料引用:
推荐本站淘宝优惠价购买喜欢的宝贝:
本文链接:https://sg.hqyman.cn/post/9539.html 非本站原创文章欢迎转载,原创文章需保留本站地址!
休息一下~~