Apache 2、SSL 和客户端证书

Posted

技术标签:

【中文标题】Apache 2、SSL 和客户端证书【英文标题】:Apache 2, SSL, and Client Certificates 【发布时间】:2013-06-20 01:12:09 【问题描述】:

我已经设置了许多使用 SSL 的虚拟主机。一切正常。然后我需要将 SSL 客户端身份验证添加到其中之一(我们称之为 SVN 主机)。为 SVN 主机启用客户端证书后,主机停止工作,改为使用默认虚拟主机(这意味着将提供不匹配的服务器证书,因此既不能访问安全主机,也不能进行客户端身份验证工作)。

这是我正在使用的虚拟主机配置:

<VirtualHost *:443>

ServerName  svn.anydomain.com

SSLEngine on
SSLOptions +StrictRequire
SSLProtocol -all +TLSv1
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!SSLv3:RC4+RSA:+HIGH:+MEDIUM

SSLCertificateFile /etc/certs/svn.crt
SSLCertificateKeyFile /etc/certs/svn.key
SSLCertificateChainFile /etc/certs/starcom/sub.class1.server.ca.pem
SSLCACertificateFile /etc/certs/cacert.crt
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown

SSLVerifyClient require
SSLVerifyDepth 2
SSLUserName SSL_CLIENT_S_DN_CN

<Location /path0>
    DAV svn
    SSLRequireSSL
    SVNPath /var/svn/path0
    #Require valid-user
</Location>

<Location /path1>
    DAV svn
    SSLRequireSSL
    SVNPath /var/svn/path1
    #Require valid-user
</Location>

</VirtualHost>

另外,我似乎只在 Mac OS X 上遇到了这个问题。我可以毫不费力地从 Windows 8 访问主机。基本上,在我的 Mac 上,我只能使用 curl 中的这些选项(有时,不一致)

curl -v -v -v -1 -k --cacert Documents/Certs/CACert.pem --cert Documents/Certs/ClientCert.pem  https://svn.anydomain.com/path1

这反而会失败(注意 SSLv3 而不是 TLSv1 的 -3 而不是 -1)

curl -v -v -v -3 -k --cacert Documents/Certs/CACert.pem --cert Documents/Certs/ClientCert.pem  https://svn.anydomain.com/path1

并返回默认虚拟主机的证书。这种行为(错误的虚拟主机)是我在我的 Mac(Safari、Eclipse+Subversive、Cornerstone 等)上对该域的任何访问所获得的。

有什么想法吗?

【问题讨论】:

【参考方案1】:

在你的 apache 配置文件中确保你已经添加了:

NameVirtualHost *:443

见http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI

确保 NameVirtualHost 位于任何使用该 IP 和端口的 &lt;VirtualHost ...&gt; 之前。如果您忘记/放错了NameVirtualHost 行或浏览器不支持 SNI,Apache 将选择第一个可用的 vHost。

【讨论】:

谢谢。我的配置已按照您的描述进行设置。有趣的是,如果我删除“SSLVerifyClient 要求”指令,一切正常。实际上只有那个指令使我的配置失败:-( 听起来问题与您的客户端本身有关,而不是 Apache 配置。 Safari 和 Cornerstone 都使用 OSX 钥匙串,请确保您的客户端证书和钥匙串在钥匙串管理器中可用(仔细检查客户端证书本身是否具有私钥)。 Eclipse+Subversive需要手动设置,说明在底部:svn.cacert.org/CAcert/Sysadm/client-certificate-guide.rst【参考方案2】:

您是否在 httpd.conf 中调高了日志级别?尝试启用调试消息并使用 tail -f 运行 error_log 以查看是否出现任何有趣的内容。

SSL 客户端身份验证的一个常见问题是 SSLVerifyDepth 参数。 SSLVerifyDepth 数字至少需要与客户端证书链中的证书数量一样大。 示例:SSLVerifyDepth 10

深度实际上是中间证书颁发者的最大数量,即验证客户端证书时允许遵循的最大 CA 证书数量。深度 0 表示仅接受自签名客户端证书,默认深度 1 表示客户端证书可以自签名或必须由服务器直接知道的 CA 签名(即 CA 的证书是SSLCACertificatePath 下)等http://www.modssl.org/docs/2.6/ssl_reference.html

【讨论】:

以上是关于Apache 2、SSL 和客户端证书的主要内容,如果未能解决你的问题,请参考以下文章

Apache 不会请求我的 SSL 客户端证书

HTTPS_SSL apache认证配置的步骤以及原理说明

nginx和iis下的SSL双向认证教程【ca 自签 ssl证书】

Linux apache自建证书搭建https

java 使用apache httpClient客户端将发布数据发送到https而不使用ssl证书验证

求助delphi实现ssl验证客户端证书