在Apache中仅针对特定的客户端证书执行客户端validation

我想让我的Apache Web服务器只接受SSL连接,如果客户端呈现给自己一个特定的SSL客户端证书。 换句话说,只有一个客户端是允许的,它必须使用特定的客户端证书(我也有)。

这个客户端证书(我们称之为“MyClientCertificate”)是一个由CA发出的正常的PEM证书(我们称之为“MyCA”),我也有证书。

这就是我为此configuration了Apache虚拟主机(我仅报告与SSL客户端validation相关的选项):

SSLVerifyClient require SSLCACertificatePath /etc/ssl/certs SSLCACertificateFile /etc/ssl/client/MyClientCertificate.pem SSLCADNRequestFile /etc/ssl/client/MyClientCertificate.pem SSLVerifyDepth 1 

选项的解释(或者我的意图至less…):

  • 与“SSLVerifyClient要求”我强制Apache始终执行客户端validation,并拒绝连接,如果它失败
  • / etc / ssl / certs包含MyCA的PEM证书(正确地安装在系统中,具有所需的散列+符号链接过程),只要所有其他知名CA的Apache可以识别
  • 使用SSLCACertificateFile我将MyClientCertificate证书添加到/ etc / ssl / certs中的CA证书列表中,作为一个受信任的证书本身,以及SSLCADNRequestFile我说我的服务器应该只请求该证书(并且只有这个证书)到客户端,而不是SSLCACertificatePath + SSLCACertificateFile中的所有CA证书列表
  • 与“SSLVerifyDepth 1”我说,允许的客户端证书是由服务器所识别的CA(在SSLCACertificatePath中)签名的,

这似乎工作:Apache要求客户端证书,拒绝连接,如果没有提供指定的客户端证书,并接受它,如果是。 然而,最近客户端(这是我的供应商)已经决定改变它的客户端证书,用一个新的(我们称之为MyNewClientCertificate.pem),用2048位encryption而不是旧的1024位深度。 问题是这样的:

  • 供应商表示已更改其客户端证书,并且正在使用新证书进行身份validation
  • 供应商肯定地说它只是提供新的证书,而不是新的和旧的证书
  • 我还没有改变我的Apacheconfiguration(因此,我的Apache仍然被configuration为请求旧的证书)
  • 但我的Apache正在接受供应商客户端连接没有任何问题! 我会期望它开始失败,直到我改变它的configuration,以取代MyClientCertificate.pem引用与MyNewClientCertificate.pem

新的证书由旧的证书发出。 供应商build议我的Apacheconfiguration可能会接受来自客户端的所有连接,这些客户端提供由该CA发出的证书,而不是在客户端证书本身上执行匹配。

如果是这样的话,我在configuration中做错了什么? 我应该将SSLVerifyDepth降低到0吗? (但是这不是说证书必须是自签名的吗?)还是我必须改变SSLCACertificateFile / SSLCADNRequestFile指令中的内容?

由于这个系统正在生产中,我不具备执行所有我能想到的testing的能力,但是我应该尽量做出有针对性的改变,以便尽快得到正确的结果。 这就是为什么我会很感激这个话题的任何帮助。

您可以通过使用SSLRequire指令来匹配特定的客户端证书,以匹配完整的Subject DN或客户端证书中的CN部分:

 SSLRequire %{SSL_CLIENT_S_DN} eq "C=AU, ST=Some-State, L=Springfield, O=ServerFault.com, OU=Moderators, CN=HBruijn/[email protected]" SSLRequire %{SSL_CLIENT_S_DN_CN} eq "HBruijn/[email protected]" 

使用openssl x509 -in client.crt -text显示主题string。

更完整的configuration将是:

 SSLVerifyClient none SSLCACertificateFile conf/ssl.crt/ca.crt SSLCACertificatePath conf/ssl.crt <Directory /usr/local/apache2/htdocs/secure/area> SSLVerifyClient require SSLVerifyDepth 5 SSLOptions +FakeBasicAuth SSLRequireSSL SSLRequire %{SSL_CLIENT_S_DN_CN} eq "HBruijn/[email protected]" </Directory>