nginx做代理https遇到SSL_do_handshake()握手失败

这个问题真的时,困扰我一段时间了,反向代理时,设置了

proxy_ssl_protocols XXXX;
#proxy_ssl_ciphers   ECC-SM4-SM3;
proxy_ssl_session_reuse off;

一开始的时候由于看到了这个:

proxy_ssl_session_reuse指令配置,当下一次nginx转发一个连接到后端服务器时,会话参数会被重复使用,从而更快的建立安全连接。

乍一看,好像说的挺对,就是节省时间了,然后就配置成了on,结果呢,只能成功访问一次,在次访问的时候,就报错了,抓包看的话,会发现在SSL握手中,SSL协议的版本,已经不是上面使用proxy_ssl_protocols 设置的协议了,当然握手失败了,

另外一种说法是:

根据反馈是短时间内连续性请求则会返回502错误,查询资料发现nginx默认会尝试重新使用SSL上游的SSL会话。

改成 proxy_ssl_session_reuse off;  问题解决。

<think>好的,用户现在问的是关于Nginx的错误信息:[crit] 1169590#1169590: *9313999 SSL_do_handshake() failed (SSL: error:0A00006C:SSL routines::bad key share) while SSL handshaking。首先,我需要理解这个错误的背景和可能的原因。 用户之前询问的是jstat -gc的输出解释,现在转到了NginxSSL握手问题,说明用户可能是在处理不同的系统问题,或者他们的工作涉及Java应用和Web服务器配置。这种情况下,用户可能是运维人员或者开发人员,需要同时处理JVM调优和服务器配置问题。 首先,分析错误信息本身。错误代码是SSL: error:0A00006C,对应的描述是bad key share。根据OpenSSL的错误代码,这个错误通常发生在SSL/TLS握手过程中,客户端和服务器之间在密钥交换(Key Share)阶段未能达成一致。可能的原因包括不支持的椭圆曲线(ECDHE)、协议版本不匹配、或者加密套件配置问题。 接下来,我需要考虑用户可能的场景。用户可能在配置或升级Nginx服务器时遇到了这个问题,尤其是在调整SSL/TLS设置后。比如,启用了较新的TLS版本(如TLS 1.3),或者更改了加密套件,导致与某些客户端(尤其是旧版本的浏览器或设备)不兼容。 用户的需求不仅仅是了解错误的原因,更需要解决这个问题的方法。因此,回答需要包括错误的原因分析、解决步骤以及预防措施。同时,用户可能需要具体的配置示例和命令,以便快速应用。 需要检查的几个方面: 1. TLS协议版本:是否服务器配置了过高的TLS版本,而客户端不支持? 2. 椭圆曲线(Curves):服务器支持的曲线是否与客户端不匹配? 3. 加密套件:是否配置了不兼容的加密套件? 4. OpenSSL版本:是否使用了较旧的版本,导致不支持某些特性? 此外,用户可能需要验证配置的方法,例如使用openssl s_client命令测试,或者检查NginxSSL配置是否正确。 在回答中,需要分步骤解释每个可能的原因和对应的解决方案,同时给出具体的配置示例,如如何调整Nginxssl_ecdh_curve参数,如何更新OpenSSL,以及如何测试配置等。此外,提醒用户检查客户端兼容性,特别是在支持旧设备时可能需要平衡安全性和兼容性。 最后,确保回答结构清晰,逐步引导用户排查问题,并提供预防措施,避免未来出现类似问题。同时,考虑到用户可能有不同的环境(如不同的操作系统、OpenSSL版本),需要给出通用的解决方法和针对不同情况的建议。</think>以下是关于Nginx报错 `[crit] SSL_do_handshake() failed (SSL: error:0A00006C:SSL routines::bad key share)` 的详细分析和解决方案: --- ### **1. 错误背景** 此错误发生在 **SSL/TLS握手阶段**,核心原因是 **客户端与服务器在密钥交换(Key Share)阶段未能协商成功**。具体表现为: - 客户端支持的密钥交换参数(如椭圆曲线、Diffie-Hellman参数)与服务器配置不兼容。 - 常见于TLS 1.3协议场景,因TLS 1.3对密钥交换算法要求更严格。 --- ### **2. 常见原因** #### **(1) 椭圆曲线(ECDHE)不匹配** - **服务器配置的椭圆曲线**(如 `prime256v1`、`secp384r1`)未被客户端支持。 - 例如:旧版客户端(如Android 4.x)可能不支持较新的曲线(如 `X25519`)。 #### **(2) TLS协议版本限制** - 客户端仅支持旧版协议(如TLS 1.2),而服务器强制使用TLS 1.3。 - 或服务器禁用了客户端所需的协议版本。 #### **(3) 加密套件(Cipher Suites)不兼容** - 服务器配置的加密套件列表未包含客户端支持的选项。 #### **(4) OpenSSL版本问题** - 旧版OpenSSL(如1.1.0)可能对TLS 1.3的支持不完善,导致密钥交换失败。 --- ### **3. 解决方案** #### **步骤1:检查并更新服务器支持的椭圆曲线** - 在Nginx配置中显式指定兼容的椭圆曲线,例如: ```nginx ssl_ecdh_curve prime256v1:secp384r1; # 兼容性更强的曲线 ``` - **避免使用非常规曲线**(如 `X25519`),除非确认所有客户端支持。 - 通过以下命令查看当前支持的曲线: ```bash openssl ecparam -list_curves ``` #### **步骤2:调整TLS协议版本** - 允许同时支持TLS 1.2和TLS 1.3: ```nginx ssl_protocols TLSv1.2 TLSv1.3; ``` - 若需兼容旧客户端,可暂时禁用TLS 1.3: ```nginx ssl_protocols TLSv1.2; ``` #### **步骤3:优化加密套件配置** - 使用广泛兼容的加密套件组合: ```nginx ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256; ``` #### **步骤4:升级OpenSSL** - 若使用旧版OpenSSL(<1.1.1),建议升级到最新稳定版: ```bash # Ubuntu/Debian sudo apt update && sudo apt upgrade openssl # CentOS/RHEL sudo yum update openssl ``` #### **步骤5:验证配置** - 使用 `openssl s_client` 测试握手: ```bash openssl s_client -connect your_domain:443 -tls1_3 # 测试TLS 1.3 openssl s_client -connect your_domain:443 -tls1_2 # 测试TLS 1.2 ``` - 若输出包含 `SSL handshake has read N bytes and written M bytes` 且无错误,则配置成功。 --- ### **4. 预防措施** 1. **平衡安全与兼容性**:在安全需求允许的情况下,保留对旧协议/算法的支持。 2. **监控客户端类型**:通过日志分析主要客户端的TLS支持情况,针对性优化配置。 3. **定期更新软件**:保持Nginx、OpenSSL等组件为最新版本。 --- ### **示例场景** **问题**:某用户升级Nginx后,Android 4.x设备无法访问网站,报错 `bad key share`。 **原因**:服务器启用了TLS 1.3和 `X25519` 曲线,但Android 4.x不支持。 **解决**:在Nginx中禁用TLS 1.3,并指定 `prime256v1` 曲线: ```nginx ssl_protocols TLSv1.2; ssl_ecdh_curve prime256v1; ``` --- ### **总结** 此错误通常由 **密钥交换参数不兼容** 引发,需通过调整椭圆曲线、协议版本或加密套件解决。建议优先保证广泛兼容性,再逐步提升安全性配置。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值