如何解决 Nginx SSL 握手失败?

如何解决 Nginx SSL 握手失败?

我正在尝试在 Ubuntu 16.04 上为 nginx 配置 HTTPS。我已经使用语句进行了设置listen 443 ssl,并告诉它在哪里可以找到证书和私钥文件。之后,我使用 重新启动了服务器sudo service nginx restart

现在当我curl https://my_ip_address,我收到以下消息:

curl: (35) gnutls_handshake() failed: Handshake failed

我已经检查了我所知道的两个日志文件/var/log/nginx/access.log/var/log/nginx/error.log;但它没有显示任何来自请求的痕迹。

我的问题:SSL 握手失败时会记录任何内容吗?如果有,记录在哪里?一般来说,如何解决此类问题,即在 HTTP 请求发送到服务器或由服务器提取之前 SSL 协议中存在错误?

编辑:我通过从我的配置中删除以下几行来使其工作:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

更新:该ssl_ecdh_curve secp384r1;行似乎是导致问题的原因。没有它,一切都正常,但有了它,SSL 握手就会失败。奇怪的是,错误消息是“没有共享密码”。我不确定它是做什么的,所以我把它删掉了。我还删除了 ssl_stapling 的内容,因为我不知道它是做什么用的,而且它自己也创建了错误消息

答案1

正如@Paul所说,解决方案是提高日志级别。我更改了文件中的一行nginx.conf,因此现在内容如下:

error_log  /var/log/nginx/error.log debug;

现在日志级别更高了,它会记录 SSL 握手错误:

2016/09/19 22:38:08 [info] 10114#10114: *2 SSL_do_handshake() failed (SSL: error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher) while SSL handshaking, client: 108.162.242.24, server: 0.0.0.0:443

答案2

实际上你已经使用了选项ssl_ecdh_曲线配置Diffie Hellman 密钥交换在 Nginx 中,但您没有提供参数文件。因此您必须使用选项ssl_dh参数并且必须使用 openssl 创建一个文件。

创建文件:

openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

在 Nginx 中使用文件和上面的 Diffie Hellman 配置:

ssl_dhparam                     /etc/ssl/certs/dhparam.pem;
ssl_ecdh_curve                  secp384r1;

答案3

您可以检查您的 nginx 服务器配置,有一行配置是:ssl_ciphers,默认值是:ssl_ciphers HIGH:!aNULL:!MD5;(http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers),但有时并非所料,就我而言,nginx-ingress-controller 默认值小于默认配置,并且 nginx 调试日志显示错误为:没有共享密码。当我在配置文件中添加一些密码并重新加载 nginx 时,该问题得到解决。您可以参考此配置模板:https://mozilla.github.io/server-side-tls/ssl-config-generator/

相关内容