nginx tlsv1 警报未知 ca:SSL 警报编号 48

nginx tlsv1 警报未知 ca:SSL 警报编号 48

我目前正在尝试将 nginx 设置为需要证书认证的网站的代理。以下 curl 命令运行良好:

curl --cacert ca-cert.pem -v --key client.key --cert client.pem https://example.com:443

但是,以下 nginx 配置似乎被服务器拒绝:

server {
        listen      80;

        location / {
            proxy_pass                      https://example.com;
            proxy_set_header                Host example.com;
            proxy_ssl_certificate           /etc/nginx/client.pem;
            proxy_ssl_certificate_key       /etc/nginx/client.key;
            proxy_ssl_trusted_certificate   /etc/nginx/ca-cert.pem;
            proxy_ssl_verify                off;
        }
    }

nginx 日志中的完整错误是:

2021/03/08 20:43:06 [error] 29#29: *1 SSL_do_handshake() failed (SSL: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:SSL alert number 48) while SSL handshaking to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "https://x.x.x.x:443/", host: "localhost:80"

有人知道发生了什么吗? nginx 配置不是等同于 curl 命令吗?

答案1

...ssl3_read_bytes:tlsv1 警报未知 ca

由于缺少中间证书,上游服务器无法验证发送客户端证书。因此,它会将问题原因作为警报发送回 nginx。修复方法可能是按client.pem正确的顺序添加必要的中间证书(即首先添加叶证书,然后添加已签名的叶证书等)。

但是为什么它能与 curl 配合使用呢:根据 curl 使用的 TLS 堆栈,也可能取决于 curl 的版本,它会自动将给出的证书与--cert给出的匹配中间证书相结合--cacert,并将完整链作为客户端证书的一部分发送到服务器。如果这样做,那么服务器就可以成功验证客户端证书。

答案2

https://example.com如果 http 服务器为多个(“虚拟”)主机提供服务并且即使在 SSL 握手期间未指定任何主机也会做出答复,则可能会有差异。

现代的卷曲版本默认使用发送服务器名称指示(SNI, 然而nginx需要明确启用它。

proxy_ssl_server_name on;添加到 nginx conf后尝试相同操作。

或者查看上游 http 服务器的服务器日志 - 他们会注意到默认主机的连接(而不是的连接example.com)。

答案3

此错误意味着 nginx 无法验证上游服务器的 TLS服务器使用您在 中提供的 CA 证书proxy_ssl_trusted_certificate。检查您是否确实提供了签署服务器证书的 CA 证书。

答案4

我遇到了同样的问题。我通过使用链式证书而不是主证书解决了这个问题。您可以在以下网址免费创建链式证书https://tools.keycdn.com/certificate-chain

相关内容