我在通过 SSL 证书对客户端进行身份验证时遇到问题,这似乎与我在整个网络中发现的许多问题类似 - 但不幸的是没有解决方案。
设置是:Debian Linux 上的 apache 2.2、mod_ssl、openssl。我有一个使用 Globalsign PersonalSign 证书进行身份验证的客户端。我已经设置了 SSLCACertificatePath,我认为是正确的,因为 apache debug 告诉我:
[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 根 CA它确实在 SSLCACertificatePath 中被发现,并且与该哈希值正确符号链接,并且在日志中先前提到已加载。
所以我陷入困境。有人有什么想法吗?
编辑:
如果我通过 openssl 命令行实用程序验证用户的证书,它会起作用:
# openssl verify -CApath conf/ssl.user.crt/ test.pem
test.pem: OK
(conf/ssl.用户.crt是我的 SSLCACertificatePath)
答案1
解决了。原来是权限问题:
我在一台干净的 Debian Squeeze 机器上设置了类似的设置,它从一开始就正常工作。调试输出的不同之处在于:
[debug] ssl_engine_kernel.c(1321): [client 80.252.98.156] Certificate Verification: depth: 2, subject: /C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA, issuer: /C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
[debug] ssl_engine_kernel.c(1321): [client 80.252.98.156] 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
[debug] ssl_engine_kernel.c(1321): [client 80.252.98.156] Certificate Verification: depth: 0, subject: /[email protected]/[email protected], issuer: /C=BE/O=GlobalSign nv-sa/CN=GlobalSign PersonalSign 1 CA - G2
从好的方面来看,vs:
[debug] ssl_engine_kernel.c(1321): [client 80.252.98.156] 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
[error] [client 80.252.98.156] Certificate Verification: Error (20): unable to get local issuer certificate
是‘坏’的一面。
这两种设置之间的主要区别在于 CA 证书所在的 apache 安装的 /conf 目录的权限。出于安全原因,我们将权限设置为 750,并且目录归 root 所有。将 CA 文件移动到可读的目录(或准确地说是路径中使用的“可执行文件”)使问题消失。
因此,虽然 mod_ssl 声称在服务器启动时读取证书,但它在运行时仍然需要访问散列文件(并且放弃了它的 root 权限)。