一 nginx作为客户端与上游的SSL/TLS握手
理解上: nginx作为'客户端',此时类似'浏览器'的角色,发请求建立连接
nginx作为server端与下游进行SSL/TLS握手
① nginx与后端选择什么样的协议
1)如果'nginx与上游'是局域网内,一般通过'http'建立请求,不需要进行'tls'加密
2)nginx与上游需要'ssl/tls握手'场景 --> '正向代理
备注: 一般上游服务是'走公网的合作方'的服务,且对'安全级别'要求较高 -->'CDN'之类的
nginx作为反向代理,当后端为https时的一些细节和原理
(1)nginx作为客户端转发https请求时
① proxy_ssl_ciphers
说明: nginx作为'客户端'自己支持的'加密套件'
备注: 通过'nginx -V'观察'openssl'版本,默认nginx使用'openssl'库提供的'加密套件'
② proxy_ssl_server_name
思考:一个ip绑定'多个域名'很常见,为什么'使用off','默认不启用 SNI'呢?
补充: 只有sslv3和tls1.0'以后'才支持'SNI'
+++++++++++++ "设置off 没有启动SNI现象" +++++++++++++
现象:由于没启用SNI,TLS握手的时候,'上游服务器不知道'用那个域名的证书便使用了'默认'证书返回
说明:当'on'时,在ssl握手时默认'$proxy_host'传给上游服务器,以便'上游服务器'知道用哪个证书
SNI的理解
③ proxy_ssl_certificate
说明: nginx作为客户端自己的'客户端证书'
④ proxy_ssl_certificate_key
说明: nginx作为'客户端'自己的'私钥'
⑤ proxy_ssl_password_file
⑥ proxy_ssl_protocols
说明: nginx作为'客户端',发起请求进行'SSL'握手的'TLS'版本
⑦ proxy_ssl_session_reuse
nginx作为客户端校验上游服务器的证书
说明: nginx一般'不校验'上游'证书'的有效性
① proxy_ssl_verify
1)'proxy_ssl_server_name off没有启用SNI',导致TLS握手时候'上游'可能返回一个'默认'证书
2) 虽然'证书返回的不对',但'请求不受影响',HTTPS请求上游时'默认不验证'上游服务器返回的证书
② proxy_ssl_verify_depth
相关参考
③ proxy_ssl_certificate
④ proxy_ssl_trusted_certificate
说明: 用这个'签发证书的CA'去校验'上游'服务器返回的'证书'是否是该'CA'签发的
⑤ proxy_ssl_name
1)'proxy_ssl_server_name on 启用SNI',默认使TLS与'上游'握手时候插入一个'SNI'
2)默认值是'$proxy_host',可以自定义'插入的SNI'
配置CDN的回源SNI
(3)小结
二 nginx作为客户端与上游ssl握手报错汇总
(1)案例1
根因: nginx作为客户端没有开启'SNI',导致与'上游'ssl'握手失败'
① 客户端现象
② nginx记录日志
细节: nginx如果作为'代理服务器'在向'上游'转发请求时报错,'access和error'都有日志记录
access.log:主要表现'upstream_addr是-'表示'没有选中'server,同时status状态码'502'
error.log:
关键字: 'SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version'
③ 根因分析
④ 解决策略
server {
server_name www.wzj.com;
resolver 8.8.8.8 valid=60s;
set $name www.wzj.com;
proxy_pass https://${name};
# 开启'SNI',发送'Client Hello',插入'proxy_ssl_name'指令的值,默认是'$proxy_host'
proxy_ssl_server_name on;
}
(2)案例2
场景: nginx作为'反向代理'的时候,后端只支持http协议,但是却配置了https
根因: 上游不支持'https',但是nginx在'proxy_pass'中配置了'https'协议
关键字:'unknown protocol'
(3)案例3
① 上游没有返回Server Hello
案例解读
1)现象: 三次'握手'成功后,nginx发送了'Client hello'报文,但'上游'却没有回Server hello
'表现'形式: curl -kv https://www.wzj.com
2)最终导致'超时',连接'断开'
解读: 三次握手成功了说明'网络、防火墙'是没有问题的,一般是通信链路中间有'代理'服务做转换导致
http和https配置相同端口导致
(4)案例4
关键字: 'wrong version number'
关联'指令': proxy_ssl_session_reuse on