跳到主要内容
ecdsa.com
nginx其他工具

错误信息

400 No required SSL certificate was sent

也可能输出为

  • client sent no required SSL certificate while reading client request headers

页面标题是“400 No required SSL certificate was sent”;如果证书未通过验证,nginx 显示的则是“400 The SSL certificate error”。这条日志以 info 级别写入,因此在默认的 error_log 级别下看不到。

nginx — ssl_verify_client on, request without a client certificate

含义

nginx 配置了双向 TLS(ssl_verify_client on),而这个请求所用的 TLS 连接中,客户端没有出示证书。nginx 不会让握手失败,而是完成握手,然后对每个请求都返回这个 HTTP 400 页面,并以 info 级别记录“client sent no required SSL certificate”。问题要在客户端解决:客户端必须出示由 ssl_client_certificate 中的 CA 签发的证书。

原因

修复方法

  1. 1.

    出示客户端证书

    把证书和密钥提供给客户端;对于浏览器以及 Windows/macOS 的密钥库,把它们打包成 PKCS#12,再导入该文件。

    bash
    curl --cert client.pem --key client.key https://mtls.example.com/
    # Browsers: import the client certificate with its key as PKCS#12
    openssl pkcs12 -export -in client.pem -inkey client.key -out client.p12
  2. 2.

    代理到 mTLS 服务:配置上游证书

    如果 nginx 本身就是 mTLS 服务的客户端,就由 proxy_ssl_certificate 和 proxy_ssl_certificate_key 在上游连接上提供证书。

    text
    # nginx proxying to an mTLS upstream: present the client certificate on the upstream connection
    location / {
        proxy_pass https://mtls.example.com;
        proxy_ssl_certificate     /etc/nginx/tls/client.pem;
        proxy_ssl_certificate_key /etc/nginx/tls/client.key;
        proxy_ssl_server_name     on;
    }
  3. 3.

    只在需要的地方要求证书

    使用 ssl_verify_client optional,再在每个 location 中检查 $ssl_client_verify,健康检查和公开路径无需证书也能访问。

    text
    # Require the certificate only where needed
    ssl_verify_client optional;
    location /api/ {
        if ($ssl_client_verify != SUCCESS) { return 403; }
    }

相关错误

浏览完整的签名错误库