赞
踩
关于nginx的搭建配置具体参考笔者之前的一篇文章:实时流媒体服务器搭建试验(nginx+rtmp)_如何在线测试流媒体rtmp搭建成功了吗-CSDN博客中的前半部分;唯一变化的是编译参数(添加stream模块并添加其对应ssl模块):
- ./configure --prefix=/usr/local/nginx --with-http_stub_status_module \
- --with-http_ssl_module --with-stream --with-stream_ssl_module \
- --with-stream_realip_module --with-openssl=../openssl-1.0.1f --without-http_gzip_module
在配置文件nginx.conf中增加stream模块的配置,具体如下:
- # lijd add 2023-11-4
- stream {
- upstream backend {
- server 192.168.97.50:54321;
- }
-
- server {
- listen 12345 ssl;
-
- proxy_connect_timeout 60s;
- proxy_timeout 60s;
- proxy_pass backend;
- }
- }
- # lijd add end
说明:真是的tcp服务器为:192.168.97.50,端口:54321;nginx代理服务器地址为:192.168.97.51,端口:12345。实验结果截图如下:
当本地客户端(192.168.80.67)连接代理服务器192.168.97.51的12345端口时,nginx的代理进程会与真实的后台服务器(192.168.97.50)的54321端口创建一个tcp连接,如下图:
客户端与服务器之间的通信成功连接并发送数据,演示如下图:
首先通过系统自带的openssl生成一套自己的CA跟服务器证书、客户端证书,具体命令如下:
- ==============================生成CA相关内容===============================
- # 为CA生成私钥
- openssl genrsa -out private/ca.prikey 2048
-
- # 为CA机构生成公钥
- openssl rsa -in ca.prikey -pubout -out ca.pubkey
-
- # 为CA生成自签名证书
- openssl req -new -x509 -days 3650 -key private/ca.prikey -out ca.cert
-
- ===========================生成服务器证书相关内容============================
- # 生成服务器私钥
- openssl genrsa -out server/ser.prikey 2048
-
- # 生成服务器证书申请文件
- openssl req -new -key server/ser.prikey -out server/ser.csr
-
- # 生成由CA签名过的服务器证书
- openssl x509 -req -days 365 -in server/ser.csr -CA ca.cert -CAkey private/ca.prikey -CAcreateserial -out server/ser.cert
-
- ===========================生成客户端证书相关内容============================
- # 生成客户端私钥
- openssl genrsa -out client/cli.prikey 2048
-
- # 生成客户端证书申请文件
- openssl req -new -key client/cli.prikey -out client/cli.csr
-
- # 生成由CA签名过的客户端证书
- openssl x509 -req -days 365 -in client/cli.csr -CA ca.cert -CAkey private/ca.prikey -CAcreateserial -out client/cli.cert
-
- # 生成客户端集成证书,包括公钥和私钥,用于浏览器访问场景
- openssl pkcs12 -export -in client/cli.cert -inkey client/cli.prikey -out client/certificate.p12
生成的所有证书如下:
实验的环境跟上面的tcp代理配置实验相同,nginx.conf的配置文件添加SSL的一些基本配置,具体如下:
- # lijd add 2023-11-4
- stream {
- upstream backend {
- server 192.168.97.50:54321;
- }
-
- server {
- listen 12345;
-
- proxy_connect_timeout 60s;
- proxy_timeout 60s;
- proxy_pass backend;
-
- # 设置nginx代理与真实服务器连接是否为SSL协议加密
- proxy_ssl off;
-
- # 设置使用的SSL协议版本
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv2;
- ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
-
- # 设置服务端使用的密码套件
- ssl_certificate /lijd/CA/server/ser.cert;
- ssl_certificate_key /lijd/CA/server/ser.prikey;
-
- ssl_session_cache shared:SSL:10m; # SSL TCP会话缓存设置共享内存区域名为
-
- # SSL,区域大小为10MB
- ssl_session_timeout 10m; # SSL TCP会话缓存超时时间为10分钟
-
- # 开启客户端认证
- #ssl_verify_client on;
- #ssl_client_certificate /lijd/CA/ca.cert;
- }
- }
- # lijd add end
注意:proxy_ssl参数开关表示:nginx代理与后台真是的tcp服务器直接是否需要SSL加密。
由于实验需要tcp客户端通道加密,支持tcp客户端TLS加密工具比较难找到,因此用单纯的tcp协议认证测试相对麻烦。笔者在这里想了一个办法:由于http、https协议是基于tcp协议之上的协议,利用浏览器的https的请求特性,模拟一个tcp加密客户端;此时后台的真实服务器用系统自带的IIS服务(http服务器)充当一个tcp服务端。后台的真实服务器如下:
通过nginx代理的tcp服务去访问后台服务器浏览器页面如下:
可以看到浏览器能通过nginx代理访问到真实的后台服务器并收到网页回复数据。通过抓两条链路的数据包分析如下:
1、浏览器(充当tcp客户端)与nginx代理之间的加密链路抓包分析如下:
2、nginx与后台真实服务器之间的纯tcp链路抓包分析如下:
双向认证需要nginx代理配置开启客户端认证。nginx.conf的配置将下面两行注释放开:
- ssl_verify_client on;
- ssl_client_certificate /lijd/CA/ca.cert;
重启nginx代理后,再通过浏览器访问页面就打不开了,如下图:
双向认证服务端需要认证客户端的证书信息,此时浏览器需要导入客户端集成证书certificate.p12,导入时需要密码,导入成功后如下图:
再次通过浏览器访问页面如下图:
点击确认之后成功访问到页面。由于客户端与nginx直接变成双向认证,nginx与真实服务器之间连接还是纯裸的tcp连接与单向认证时的情况相同,这里就抓一下客户端与nginx之间的数据包,如下图:
至此,通过nginx代理TLS加密通道实验已经完结。本章主要讨论的是如下图结构:
有兴趣的同学可以研究一下nginx代理与客户端、服务器双向都为TLS加密通道。此时nginx的配置中proxy_ssl参数需要设置成on(默认为on,实验时在这卡了半天),这时就需要后台TCP服务器支持TLS加密。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。