我正在尝试让nginx验证通过以下链发出的客户端证书,使用自签名root:Root CA =>签名CA =>从属CA =>客户证书。
我在服务器上安装了root_CA.crt,在客户端,证书与ssl_client_certificate /path/to/root_CA.crt;
ssl_verify_client on;
ssl_verify_depth 3;
连接在一起。我的nginx设置如下所示:
curl -k server.url:443 --cert cert-chain.pem
我尝试与curl: (35) error reading X.509 key or certificate file
建立联系,但却给了我错误--key client.key
。如果我使用400 Bad Request
尝试,那么它会给我openssl s_client
。我还尝试使用{{1}}进行测试,结果类似。
我已经验证了如果我没有中间CA,则nginx设置有效,即Root CA =>客户证书。如果我的中间CA证书安装在服务器上并且只有叶证书在客户端,它也可以工作。但是,在我们的示例中,无法提前在服务器上安装签名CA和从属CA证书。知道下一步该尝试什么吗?
答案 0 :(得分:1)
我发现curl没有正确发送中间证书,即使它们已包含在pem(或.p12)文件中。
您可以通过对流向服务器的流量(tcpdump -A ... dst端口443)进行数据包捕获来验证这一点。您将能够在捕获中看到证书主题的文本形式和问题。您将看到客户端证书(主题及其直接中间发行人),但没有进一步的链接。
尝试使用openssl s_client来验证:
openssl s_client -connect www.example.com:443 -cert client.crt -key client.key -CAFile cert-chain.pem
输入:
GET / HTTP/1.0<return>
<return>
答案 1 :(得分:0)
我最终使用了针对openssl构建的curl 7.52.1(即刚刚在debian stable中提供的curl版本)。
我需要将发行链的两个.cer组合成一个:
cat caroot.cer caissuing.cer > cachain.cer
(顺序很重要,根证书必须是第一个,然后是任何依赖早期证书的证书等)
和我的私人客户端密钥和签名的pem:
cat private.key private.pem > private-combined.pem
然后我可以使用:
访问服务器curl --cacert cachain.cer --cert-type pem --cert private-combined.pem
(我尝试过的其他所有组合都因curl,openssl或服务器的各种无用错误而失败。)