为了简短介绍,我试图找出 nginx 中 SSL 握手错误的含义和原因。具体来说,是关于密钥共享的部分,因为搜索错误没有找到任何结果。
SSL_do_handshake() failed (SSL: error:141F7065:SSL routines:final_key_share:no suitable key share) while SSL handshaking.
让我进一步解释一下我的情况:我正在尝试Collabora 在线开发版 (CODE)连接到我的Nextcloud在我的 Arch Linux 系统上设置。两者都在同一台服务器上运行,nginx 是 Collabora 的代理。我的 Nextcloud 服务器运行良好,我提供的所有其他网站和服务也都运行良好,所有东西都通过 SSL。然而,在将 CODE 连接到我的 Nextcloud 安装后已经遇到问题,我终于让它出现了,尽管它说无法连接到我的文档。
对于故障排除,应该注意的是,Collabora 的套件直接基于LibreOffice 在线因此其代码库的许多部分都是匹配的。经过几个小时寻找解决方案和排除 nginx 和 loolwsd 中不同配置设置的故障后,我发现 LibreOffice Online 的Web 服务守护进程无法连接 Nextcloud 提供的 WOPI 存储 URI。
Cannot get file info from WOPI storage uri [Nextcloud URL with privilege key].
Error: SSL Exception: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure | wsd/Storage.cpp:531
从 cURL 连接到 URL 会产生正确的有效负载,这意味着 Nextcloud 服务器正在按预期工作。
另一端的 nginx 在处理请求时产生此错误。
SSL_do_handshake() failed (SSL: error:141F7065:SSL routines:final_key_share:no suitable key share) while SSL handshaking.
我之前认为这可能与密码有关,因为在我看来 loolwsd 使用一套过时的密码但该错误信息指向不同的方向。
nginx 下的两个域都使用相同的 SSL 参数。
# General SSL configuration.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384";
ssl_ecdh_curve secp384r1;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
# DNS resolver configuration. Use Google DNS.
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Security headers.
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
# Diffie-Hellman key. Generate using: openssl dhparam -out dhparam.pem 4096
ssl_dhparam /etc/ssl/certs/dhparam.pem;
服务器上使用的 OpenSSL 版本是 1.1.1
我现在的主要问题是“没有合适的密钥共享”具体是什么意思,以及其原因是什么?
答案1
此错误特定于 OpenSSL 1.1.1 实现的 TLSv1.3,意味着客户端和服务器之间未找到通用密钥交换机制。最有可能的原因是:
ssl_ecdh_curve secp384r1;
它将可用的 EC 曲线限制为 secp384r1,而客户端明确使用 prime256v1。
尝试注释掉ssl_ecdh_curve
。默认是auto
,这是 OpenSSL 库定义的合理曲线列表。
或者,如果您想明确一点,请列出prime256v1
和secp384r1
:
ssl_ecdh_curve secp384r1:prime256v1;
这将允许该客户端连接。