一 HTTPS握手机制
关注点: 'SSL/TLS握手'的细节与nginx'配置指令'的关系
核心: 讲解'客户端(下游)'与作为'server'端的nginx之间的'握手'
最佳实践: 建议在'http块'中通过'include ssl.conf'把共工部分抽离处理
'ssl/tls报错'原因:可能是'客户端'或'服务端(openssl库处理)'的原因
案例: '单向'和'双向认证'怎么配置?
① ngx_http_ssl_module模块
(1)HTTPS单向认证涉及的指令
② ssl
解读: 让'nginx'支持'https'
高版本使用ssl指令提示信息
新版本推荐listen指令
1) 'http1.2' --> listen 443 ssl http2
2) 'http1.1' --> listen 443 ssl
③ ssl_certificate
说明: 配置'数字证书',一般是'代理CA'颁发的数字证书
了解: '数字证书'的内容 -->'服务端的公钥'、'证书的有效期'、'证书的颁发机构'等
补充: 了解证书的'格式' --> 常见是'pem、crt、p12'
附加1: 了解'nginx版本'与'openssl版本'的适配问题、'nginx高版本'支持'变量形式'
附加2: file的'相对(nginx.conf所在的路径)'和'绝对'路径
将中间CA的证书合并到主证书中
④ ssl_certificate_key
说明: 一般是'CA机构'颁发的'私钥文件','不能'泄露
注意: 文件'权限',保证'nginx的master进程'能够读取
补充: 私钥是'解用公钥加密的对称(会话)密钥'的,进而通过'会话密钥'来解'加密的data数据'
⑤ ssl_ciphers
常见'报错'场景: 浏览器支持的加密套件'nginx并没有'配置,,所以握手失败
细节:多个算法用':'分隔,'ALL'表示全部算法,'!'表示'不启用'该算法,'+'将该算法排到最后面去
1)不同'ssl/tls'版本支持的'加密套件'不同,'加密套件的安全性'也不同
2)加密套件一般'由多个'组成,在'双方协商'的'时候'会选取'server端'匹配上的'第一个'加密套件
默认值的含义、官网参考
openssl ciphers使用案例
浏览器支持的加密套件 nginx并没有配置 所以握手失败,导致SSL握手报错
源码: openssl的加密套件在's3_lib.c'的'ssl3_ciphers数组'中定义
重点: openssl ciphers -v 'nginx中ssl_ciphers指令的配置值'
类似: openssl ciphers 'MD5' -v|column -t
场景: 查看nginx中到底支持'哪些'加密套件
--> 备注:'不准确',因为'nginx'和'操作系统'使用openssl版本可能'不一致'
查看openssl支持加密方式
最佳实践: 'HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4:!RSA'
细节点: 没有'CBC'、'RSA'、'CAMELLIA'
注意: nginx要配置合适的'ssl版本协议'
++++++++++++++ "查看服务端支持的加密套件" ++++++++++++++
1) nmap --script ssl-cert,ssl-enum-ciphers -p 'port' 'ip|域名'
2) openssl s_client -connect 'ip|域名:port'
细节点: 必须显示指定'port'
⑥ ssl_password_file
entropy_avail熵不足(小于1000)导致证书加解密失败,需要通过haveged程序补充熵池
1)如果'私钥'之前加密过,需要指定'私钥'的解密'密码';如果没有'加密',则不需要配置该指令
备注:为了'自动(非交互)'的执行
2)解'私钥'的密码不建议是'明文'的
3)生产建议: 在'reload'的时候,通过'工具'动态生成'解密证书'的'密码'
4)细节点:如果'所有域名证书的私钥'密码都一样,建议在'http块'配置;个性化的话在'server'配置
备注: 一般在'ssl'目录下放置'crt、passwd、key'后缀文件,前缀为'域名'
nginx多个server怎么配置ssl_nginx多密码SSL证书管理
⑦ ssl_protocols
1)ssl_protocols'不具有兼容性',要支持'多个协议'需要'全部'写上
举例: 如果'client'说自己支持'TLSv1.2',但是'nginx'没有配置'TLSv1.2'则'协商不通过'
2)支持的'加密套件'也与'ssl/tls'版本有关
3)如何支持'TLSv1.3'? -->'nginx和openssl'的版本
备注: 主流的是'TLSv1.2'
说明: TLS v1.0'以上'的版本是比较'安全'的,最好是'弃用SSLv3以下'的版本
(2)HTTPS双向认证的指令
双向认证中'server到client'认证目的: 服务端只允许'特定的客户'才能访问
场景: 一般'client证书'是由'自定的CA证书'签发的
① ssl_verify_client
作用: 检验'client端'证书,是一个'开关'选项
特点: 常用'on'代表'强制'启用客户端认证;非法客户端'无证书、证书不可信'都会返回'400'
细节: 如果是'浏览器'必须提前导入'证书'、如果是'命令行工具(curl)'携带参数
curl命令进行单向和双向认证
浏览器如何导入客户端证书
② ssl_trusted_certificate
③ ssl_verify_depth
解读:
1)验证'客户端证书'的'有效性和合法性','目标是'需要层层'回溯到CA根证书'
2)但是回溯'多少次'由ssl_verify_depth决定
细节
1)当'ssl_verify_depth 1'时,回溯层数为0,即'任何中间证书'都不会通过验证,除非是'根'证书
2)如果'中间证书的深度'要'小于'ssl_verify_depth的值,才会'验证'通过
ssl_verify_depth
④ ssl_client_certificate
1)ssl_client_certificate就是'客户端证书的CA证书'了,代表'此CA签发'的证书都是'可信'的
+++++++ 'ssl_trusted_certificate' 和 'ssl_client_certificate'对比 +++++++
1)这两个配置'效果都是一样'的
2)唯一的'区别'是 ssl_client_certificate 会将'信任的 CA 列表'发送给'客户端'
3)二者是'效率'和'安全性'的对比
4)'ssl_client_certificate'优先级更高
备注1: 客户端如果'有很多证书',让客户端'一个一个去尝试'哪一个能建连是没有'意义并且很浪费'的
备注2: 'ssl_trusted_certificate'更安全,避免了'CA根证书'的泄露
⑤ ssl_crl
细节:
1)ssl_crl这个配置,代表Nginx会读取一个'CRL(Certificate Revoke List)文件'
2) 之前说过,可能会有收回用户权限的需求,因此我们必须有吊销证书的功能
3) 产生一个CRL文件'让Nginx知道'哪些证书被吊销了即可
注意:
1) Nginx配置都是'静态'的,读取配置文件之后都会'加载到内存'中,即使文件内容变化也不会重新读取
2) 因此当CRL文件发生变更之后,Nginx并'不能意识'到有新的证书被吊销了
3) 所以必须使用reload指令让Nginx'重新读取'配置文件:
--> service nginx reload或nginx -s reload
(3)TLS/SSL优化握手性能
① ssl_session_cache
作用: 开启了TLS'缓存复用'
机制: 在缓存中查找对应的'Session ID',如果存在则'接受并恢复'会话,返回'相同'的Session ID
优化的地方: 减少'TLS'握手,少了一次'RTT'的往返时间
nginx开启SSL会话复用,能提升多少性能?
② ssl_session_timeout
③ ssl_session_tickets ssl_session_ticket_key
说明: 使用'会话票证'tickets复用session
(4)不太常用的指令
① ssl_reject_handshake
1)自 '1.19.4 起',nginx 支持 ssl_reject_handshake 参数
2)设置为'on',当客户端'传过来的SNI'与'已配置的 server name'都不匹配时,会'拒绝' SSL 握手
3)访问'客户端(浏览器)'会报 SSL_ERROR_UNRECOGNIZED_NAME_ALERT
应用场景 nginx设置严格域名校验
② ssl_prefer_server_ciphers
1)ssl_prefer_server_ciphers 'on|off' 作用, 是否'由服务器决定'采用'哪种'加密算法
备注: 默认是'off',推荐设置为'on'
特点:决定使用'交集中'客户端的第一个加密套件,还是'服务端'加密套件'列表'的第一个,推荐服务端
2)如果ssl协议'支持tlsv1 tls1.1'这种'老'协议,设置为 'on' ,并配合ssl_ciphers使用
3)如果ssl协议'只支持tlsv1.2 tlsv1.3''新'协议,设置为 off ,因为新协议'不再采纳'此参数
4)当为on时,在使用'SSLv3和TLS协议'时,服务器加密算法将'优于'客户端加密算法
③ ssl_crl
常见: 有人'泄露'证书的私钥,'CA机构会吊销证书',使证书在'到期日期之前'无效
生效: 'reload | restart'才能让nginx'重新加载CRL',这样'被吊销的证书'将无法访问网站了
SSL证书吊销列表 CRL
④ ssl_buffer_size
⑤ ssl_conf_command
SSL_CONF_cmd查找
⑥ ssl_ocsp ssl_ocsp_cache ssl_ocsp_responder
说明: '了解'即可
什么是OCSP OCSP的调试
⑦ ssl_stapling ssl_stapling_file ssl_stapling_responder ssl_stapling_verify
OCSP stapling配置
⑧ ssl_early_data
说明: 是'TLSv1.3'的特性
⑨ ssl_ecdh_curve
⑩ HSTS强制浏览器使用https
(5)ssl模块提供的ssl/tls握手相关变量 重点
1) '重点'掌握'$ssl_cipher'、'$ssl_ciphers'、'$ssl_protocol'、'$ssl_server_name'
'$ssl_ciphers': '查看客户端支持的加密套件',一般是'Chrome浏览器'
'$ssl_server_name':与'SNI'强相关
'$ssl_cipher': '客户端和服务端'最终协商的'加密套件'
2) 免去'tcpdump'部分抓包分析的痛苦
3) 注意'ssl变量'使用的'注意'事项 --> "nginx和openssl"的版本
4) 学会从'ssl相关的变量'挖掘'隐含'信息
5) 需求:session有没有复用? --> "两个综合判断"
$ssl_session_id
$ssl_session_reused
(6)案例讲解
(7)errors 重点
二 nginx ssl握手报错 汇总
① 排查思路
② 客户端不支持SNI导致报错
③ 双向认证校验客户端证书的CA配置错误
关键字: 'certificate not trusted'
④ 不支持客户端的加密套件
关键字:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:'no shared cipher'
说明:nginx作为服务端'没有'客户端支持的'加密算法套件',导致'SSL'握手报错
⑤ 相关参考
关键字:ssl3_'get_client_key_exchange':EC lib) while SSL handshaking
⑥ 证书格式有误
⑦ 握手超时
关键字: (110:'Connection timed out') while SSL handshaking)
⑧ 证书编码格式
关键字:'no start line'
证书的顺序
⑨ 私钥长度太短
关键字: SSL_CTX_use_certificate:ee 'key too small'
⑩ 证书格式不对有空格
关键字1:nginx: [emerg] SSL_CTX_use_PrivateKey_file(".key") failed
关键字2:x509 certificate routines:X509_check_private_key:'key values mismatch'
⑪ 后续案例补充
++++++++++"分割线[SSL问题]"++++++++++
"SSL_do_handshake() failed" SSL'握手失败'
'SSL_write() failed (SSL:) while sending to client'
'ngx_slab_alloc() failed: no memory in SSL session shared cache'
ssl_session_cache'大小不够'等原因造成
'could not add new SSL session to the session cache while SSL handshaking'
'wrong version number'
'upstream SSL certificate does not match'
'certificate signature failure'
'SSL routines:ssl3_read_bytes:ccs received early' while SSL handshaking
ssl3_get_client_hello:no shared cipher --> "服务端没有支持的加密套件"
重点: 'ssl'的报错还是从'握手阶段和原理'理解、'偶发'还是'必显'
git的certificate verify failed哪
nginx-https安全最佳实践
服务器选择算法原则