You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Nginx代理自签名证书上游服务器出现SSL握手错误求助

解决Nginx代理旧服务器时的SSL握手错误(dh key too small)

我之前处理过一模一样的问题,你遇到的这个dh key too small错误,本质上不是证书信任的问题(哪怕你已经开了proxy_ssl_verify off),而是上游旧服务器使用的DH密钥长度不符合现代安全标准,Nginx依赖的OpenSSL默认会拒绝这种弱密钥的握手请求。

先拆解下日志里的错误信息:

2018/05/02 11:31:39 [crit] 3500#2284: *1 SSL_do_handshake() failed (SSL: error:14082174:SSL routines:ssl3_check_cert_and_algorithm:dh key too small) while SSL handshaking to upstream, client: 127.0.0.1, server: , request: "GET /ping HTTP/1...

这个错误明确指向了DH密钥长度不足,现代OpenSSL默认要求DH密钥至少2048位,而你的旧服务器可能用了1024位甚至更小的密钥,所以握手直接失败了。

解决方案:调整Nginx代理的SSL策略

最稳妥的方式是在你的代理location块里添加针对性的SSL参数,绕开DH密钥交换的限制,同时兼容旧服务器的TLS版本:

修改后的完整Nginx配置

server {
    listen 8009;
    location / {
        proxy_ssl_verify off;
        proxy_ssl_session_reuse off;
        # 新增以下两行解决DH密钥过小问题
        proxy_ssl_ciphers 'DEFAULT:!DH';
        proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        proxy_pass https://192.168.10.20:8009/;
    }
}

参数解释:

  • proxy_ssl_ciphers 'DEFAULT:!DH':禁用DH密钥交换算法,改用RSA等其他密钥交换方式,这样就避开了DH密钥过小的问题。
  • proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2:明确指定兼容的TLS版本,因为旧服务器大概率不支持TLS 1.3,而Nginx默认可能已经禁用了老版本的TLS,手动指定后能确保握手成功。

备选方案(不推荐全局修改)

如果上面的配置没生效,你也可以尝试在Nginx的全局http块里调整SSL策略,但这样会影响所有站点的安全级别,所以仅作为最后手段:

http {
    # ... 其他全局配置
    ssl_ciphers 'DEFAULT:!DH';
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}

额外提醒

虽然这个配置能解决当前的握手问题,但自签名证书+弱DH密钥本身存在严重的安全风险。如果条件允许,建议尽快升级旧服务器的SSL配置:

  • 生成至少2048位的DH密钥(推荐4096位)
  • 替换为可信证书机构颁发的证书,或者至少确保自签名证书的密钥长度符合安全标准

内容的提问来源于stack exchange,提问作者Venkatesh Nannan

火山引擎 最新活动