我试图在nginx中启用客户端证书身份验证,其中证书已由中间CA签名 . 使用由自签名根CA签名的证书时,我能够正常工作;但是,当签名CA是中间CA时,这不起作用 .
我的简单服务器部分如下所示:
server {
listen 443;
server_name _;
ssl on;
ssl_certificate cert.pem;
ssl_certificate_key cert.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
ssl_client_certificate ca.pem;
ssl_verify_client on;
ssl_verify_depth 1;
location / {
root html;
index index.html index.htm;
}
}
对于ca.pem的内容,我尝试过只使用中间CA并连接中间CA证书和根CA证书,例如:
cp intermediate.crt ca.pem
cat root.crt >> ca.pem
我还验证了在使用相同的CA链时,从openssl的角度来看证书是有效的:
openssl verify -CAfile /etc/nginx/ca.pem certs/client.crt
certs/client.crt: OK
我已经尝试将ssl_verify_depth显式设置为1(如上所述)然后甚至为0(不确定该数字的确切含义),但仍然会得到相同的错误 .
我在中间CA的所有变体中得到的错误是“400 Bad Request”,更具体地说是“SSL证书错误”(不确定这意味着什么) .
也许nginx只是不支持中间证书的证书链?任何帮助非常感谢!
6 回答
Edit: I had also this "problem", solution and explanation is at the bottom of the text .
似乎nginx不支持中间证书 . 我的证书是自己创建的:(RootCA是自签名的,IntrermediateCA1是由RootCA签名的,等等)
我想在nginx“IntermediateCA1”中使用,只允许访问“Client1”证书的所有者 .
当我使用 IntermediateCA1 and RootCA 设置"ssl_client_certificate"文件并设置"ssl_verify_depth 2"(或更多)时,客户端可以使用证书 Client1 and Client2 (仅应该是Client1)登录到站点 . 同样的结果是当我将"ssl_client_certificate"文件与 only RootCA 放在一起时 - 两个客户端都可以登录 .
当我使用 only IntermediateCA1 设置"ssl_client_certificate"文件,并设置"ssl_verify_depth 1"(或"2"或更多 - 无论如何)时,登录是不可能的,我得到错误400.在调试模式下,我看到日志:
我觉得这是一个错误 . 在Ubuntu上测试,nginx 1.1.19和1.2.7-1~dotdeb.1,openssl 1.0.1 . 我看到nginx 1.3有更多关于使用客户端证书的选项,但我们没有看到解决这个问题的方法 .
目前,分离客户端1和2的唯一方法是创建两个自签名的RootCAs,但这只是解决方法 .
Edit 1: 我在这里报告了这个问题:http://trac.nginx.org/nginx/ticket/301
Edit 2" 好的,这不是错误,它是功能;)
我在这里得到回复:http://trac.nginx.org/nginx/ticket/301 It is working ,你必须只检查你的ssl_client_i_dn是什么( . 而不是发行人你也可以使用证书的主题,或你想要的http://wiki.nginx.org/HttpSslModule#Built-in_variables
[由我编辑,它在我的配置中正常工作]
你试过增加
ssl_verify_depth
指令吗? Docs说:但你的验证深度是1.你说:
所以,试试2或3 ..
PS: 在我发现提到此问题的任何地方,它被告知将中间CA证书与您的服务器证书组合在一起 . 按照验证的顺序将一个文件(如@vikas-nalwar suggested和你所做的那样)(但我不确定订单是否重要)并粗略地说明了捆绑中的证书数量
ssl_verify_depth
.我相信您希望在服务器端启用客户端验证 . 如果是这样的话,我不会看到你的链中有你的客户证书 . 请按完全相同的顺序尝试以下操作 . 使用certchain.pem .
当我与nginx和cloudflare搏斗时,
这些线为我做了诀窍:
optional_no_ca 的第二行是重要的部分
我不得不说用
nginx/1.13.2
为我工作正常,即我有一个根CA签署了两个中间CA.
两个中间体各签了一个客户
我连接了像
cat client-intermediate1.crt ca-client.crt > ca.chained1.crt
和cat client-intermediate2.crt ca-client.crt > ca.chained2.crt
以及cat ca.chained1.crt ca.chained2.crt > ca.multiple.intermediate.crt
这样的证书如果我只把ca.chained1.crt作为
ssl_client_certificate
那么只有client1.crt可以连接,同样对于ca.chained2.crt / client2.crt当我使用
ca.multiple.intermediate.crt
时,两个客户端都可以连接要撤消中间件,只需从ca.multiple.intermediate.crt中删除cert链
这是相关的配置 . 它还具有高安全性设置
如果要解析证书CN并将其传递给后端,则将此外部添加到
server {..
块然后在块中你可以使用它
另一种简单的方法是在单个文件中连接证书(包括域证书)并在您的服务器和nginx conf文件中使用它
始终记住首先使用服务器证书,然后只使用CA服务器证书
你可以在http://nginx.org/en/docs/http/configuring_https_servers.html#chains阅读更多相关信息