【问题标题】:400 Bad Request: The SSL certificate error400 错误请求:S​​SL 证书错误
【发布时间】:2015-02-12 14:20:51
【问题描述】:

当我尝试使用此命令获取包含客户端密钥和证书的页面时出现此错误:

curl -v -s --key /home/dmitry/Downloads/client_cert/client.mysite.key --cert /home/dmitry/Downloads/client_cert/client.mysite.crt https://mysite.com/api/login/

这是我在 nginx 日志中看到的内容:

2014/12/08 06:30:55 [crit] 13087#0: *404 SSL_do_handshake() failed (SSL: error:14094085:SSL routines:SSL3_READ_BYTES:ccs received early) while SSL handshaking, client: xxx.xxx.xxx.xxx, server: 0.0.0.0:443

这是我的 nginx.conf 的一部分:

server {
    listen  443 ssl;

    ssl_certificate     /home/mysite/conf/dev/ssl/com.mysite.crt;
    ssl_certificate_key /home/mysite/conf/dev/ssl/com.mysite.key;
    ssl_client_certificate /home/mysite/conf/dev/ssl/com.mysite.crt;
    ssl_verify_client optional; 
    ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    server_name   mysite.com www.mysite.com;
    access_log    /home/mysite/logs/nginx_access.log;
    error_log     /home/mysite/logs/nginx_error.log;

    location /api/{
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;

        proxy_set_header SSL-client-serial $ssl_client_serial;
        proxy_set_header SSL-client-dn $ssl_client_s_dn;
        proxy_set_header SSL-client-verify $ssl_client_verify;

        if ($ssl_client_verify != SUCCESS) {
            return 403;
            break;
        }
    }
}

这是我用来创建客户端证书的命令:

openssl req -out client.mysite.csr -new -newkey rsa:2048 -nodes -keyout client.mysite.key
openssl x509 -req -days 3650 -in client.mysite.csr -CA com.mysite.crt -CAkey com.mysite.key -set_serial 01 -out client.mysite.crt

这里可能有什么问题?我应该使用其他证书作为我的客户端证书而不是服务器证书的 CA 吗?

更新:

当我这样做时

openssl verify -CAfile com.mysite.crt client.mysite.crt

我明白了:

error 20 at 0 depth lookup:unable to get local issuer certificate

【问题讨论】:

标签: ssl nginx openssl


【解决方案1】:

首先,在nginx.conf启用调试日志:

error_log  logs/error.log debug;

然后重启 nginx。然后重复请求并检查日志文件。找到verify:0的第一行:

2019/12/05 22:34:50 [debug] 5980#9776: *17 verify:0, error:20, depth:0, subject:"/CN=...", issuer:"/CN=..."

你在这里看到error:20。错误代码来自 OpenSSL。 Here可以通过代码找到常量名,here可以通过常量名找到对应的描述。

您也可以使用openssl 命令行工具验证证书:

openssl verify -CAfile ca.crt client.crt

要在服务器看到它时验证它,ca.crt 必须是 nginx.conf 中的 ssl_client_certificatessl_trusted_certificate 指令中列出的文件。

要自行验证证书,ca.crt 必须是用于签署 client.crt 的证书。如果它是自签名的,它将是 client.crt 本身(client.crt 将连续两次)。

如果您专门收到error 20 并且您的客户端证书是自签名的,您可能遇到过this bug。要修复它,您应该从证书中完全删除 keyUsage 或将 keyCertSign 添加到列表中。要验证您是否偶然发现它,请检查以下命令输出的 X509v3 extensions: 部分中是否列出了 Key Usage:

openssl x509 -in client.crt -text -noout

【讨论】:

    【解决方案2】:

    我用来签署另一个证书的证书不是 CA,所以它根本无法验证,这就是为什么我从 openssl verify 命令收到此错误:

    error 20 at 0 depth lookup:unable to get local issuer certificate
    

    如果您不是 CA,那么显然您无能为力。

    【讨论】:

      【解决方案3】:

      ccs 提前收到

      看起来像是 CVE-2014-0224 修复的后果。由于补丁 seems to be available 检查您的系统是最新的或向您的分销商报告错误。

      如果您要添加有关您正在运行的服务器系统的信息,尤其是哪个操作系统、哪个版本的 OpenSSL 以及哪些补丁,可能会获得更多详细信息。

      【讨论】:

      • Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-24-generic x86_64) 和 OpenSSL 1.0.1f 2014 年 1 月 6 日。我从标准 ubuntu 存储库安装了 openssl。
      • 问题是否仅限于 curl 或者您是否也遇到其他客户端(例如 openssl s_client、wget)的相同问题?如果只是 curl:您正在运行哪个版本 (curl -V)。你能做一个最小的设置来重现问题或创建一个用于wireshark的数据包捕获吗?
      • 不,当我尝试从 android 移动应用程序访问 url 时,我也遇到了同样的错误。
      • 如果您需要更多帮助,请创建一种重现问题的方法。否则至少我将无法更详细地查看它。
      • 我更新了问题。客户端证书有问题
      【解决方案4】:

      就我而言,我错误地从具有较旧证书的数字海洋网站下载了“cloudflare.crt”文件,这浪费了我很多时间。 正如他们的教程在谷歌搜索中显示的那样。

      wrong certificate from digital ocean

      link to correct certificate

      【讨论】:

        【解决方案5】:

        我有一个很好的工作方式。首先在创建指向域之前,即

        server_name api.example.com;
           location / {
                proxy_pass "http://example.com:9191";
            }
        
        
        
         
        

        在您的 cpanel 中创建一个 api.domain.com 的子域,然后现在在此处找到您的 crt 文件

        /var/cpanel/ssl/apache_tls/api.domain.com

        你会发现组合文件现在完成了把组合文件,即

        ssl_certificate /var/cpanel/ssl/apache_tls/api.domain.com/combined;

        然后ssl你会在cpanel ssl/tsl->install ssl下找到它

        您可以通过 google 找到您的 ssl 文件所在的位置

        您的最终 ssl 配置将是这样的

        server {
            listen 443 ssl http2;
            listen [::]:443 ssl http2;
        
            server_name api.example.com;
        
            location / {
                proxy_pass "http://example.com:9191";
            }
        
            location /socket.io/ {
        
                proxy_pass "http://example.com:9191";
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_read_timeout 86400;
        
            }
            location /engine.io/ {
        
                proxy_pass "http://example.com:9191";
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_read_timeout 86400;
        
            }
        
            ssl_certificate /var/cpanel/ssl/apache_tls/api.domain.com/combined;
            ssl_certificate_key /var/cpanel/ssl/system/certs/crashgame/private.key;
        }
        

        请将您的私钥放在您可以找到的路径中

        【讨论】:

          猜你喜欢
          • 2017-08-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-05
          • 2018-06-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多