我遇到了通过 ssl 证书对客户端进行身份验证的问题,这似乎与我在整个网络中发现的许多问题类似 - 不幸的是没有解决方案。
设置是:Debian Linux 上的 apache 2.2、mod_ssl、openssl。我有一个使用 Globalsign PersonalSign 证书进行身份验证的客户端。我已经设置了 SSLCACertificatePath 我认为是正确的,因为 apache 调试告诉我:
[Thu May 10 15:31:35 2012] [debug] ssl_engine_init.c(1196): CA certificate: /C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
[Thu May 10 15:31:35 2012] [debug] ssl_engine_init.c(1196): CA certificate: /C=BE/O=GlobalSign nv-sa/CN=GlobalSign PersonalSign 1 CA - G2
[Thu May 10 15:31:35 2012] [debug] ssl_engine_init.c(1196): CA certificate: /C=BE/O=GlobalSign nv-sa/CN=GlobalSign PersonalSign 1 CA - G2
[Thu May 10 15:31:35 2012] [debug] ssl_engine_init.c(1196): CA certificate: /C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
我不知道为什么两个证书都出现在这个列表中两次。哈希通过 c_rehash 实用程序正确链接。
现在客户端进行身份验证(我从调试日志中复制了我认为相关的条目):
Certificate Verification: depth: 1, subject: /C=BE/O=GlobalSign nv-sa/CN=GlobalSign PersonalSign 1 CA - G2, issuer: /C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
Certificate Verification: Error (20): unable to get local issuer certificate
OpenSSL: Write: SSLv3 read client certificate B
OpenSSL: Exit: error in SSLv3 read client certificate B
Re-negotiation handshake failed: Not accepted by client!?
据我有限的理解,这意味着他未能获得中间GlobalSign PersonalSign 1 CA - G2证书的颁发者证书。事实上,该证书的 issuer_hash 与GlobalSign Root CA的哈希相匹配,该哈希确实在 SSLCACertificatePath 中找到,并与该哈希正确地进行了符号链接,并且在加载的日志中前面提到过。
所以我卡住了。有什么想法吗?
编辑:
如果我通过 openssl 命令行实用程序验证用户的证书,它会起作用:
# openssl verify -CApath conf/ssl.user.crt/ test.pem
test.pem: OK
(conf/ssl.user.crt是我的 SSLCACertificatePath)
解决了。原来是权限问题:
我在一台干净的 Debian Squeeze 机器上设置了类似的设置,它从一开始就运行良好。调试输出的区别是:
在“好的”方面,对比:
在“坏”的一面。
两种设置之间的主要区别在于 CA 证书所在的 apache 安装的 /conf 目录的权限。出于安全原因,我们将权限设置为 750 并将目录归 root 所有。将 CA 文件移动到可读目录(或准确地说是“可执行”以在路径中使用)使问题消失。
因此,尽管 mod_ssl 声称在服务器启动时读取证书,但它仍然需要在运行时访问散列文件(并且已经放弃了它的根权限)。