JkEnvVar SSL_CLIENT_CERT 在“SSLVerifyClient 需要”时不起作用(在目录级别设置)

Posted

技术标签:

【中文标题】JkEnvVar SSL_CLIENT_CERT 在“SSLVerifyClient 需要”时不起作用(在目录级别设置)【英文标题】:JkEnvVar SSL_CLIENT_CERT doesn't work when "SSLVerifyClient require" (setup on a directory-level) 【发布时间】:2011-07-11 06:31:36 【问题描述】:

[我的环境是这样的:Apache/2.2.17 (Win32) mod_ssl/2.2.17 OpenSSL/0.9.8o php/5.2.9-2 mod_jk/1.2.31 (尽管我们在具有类似 apache/mod_jk/tomcat 规格的 Ubuntu 10.04.2 LTS 下得到相同的行为)]

我已经设置了一个用于提供 https 服务的虚拟主机,并且我希望在那里有两种类型的目录/应用程序:一种通过“普通”https 提供服务,另一种通过客户端身份验证提供服务(使用客户端证书)。

当“SSLVerifyClient 要求”放在虚拟主机级别时,相关的 JkEnvVar SSL_CLIENT_CERT 会正确地将信息传播到 tomcat。当它被放置在目录级别(在虚拟主机内)时,它不会。 有什么线索吗??

我的 httpd.conf 包含以下几行:

...
JkWorkersFile conf/workers.properties
JkShmFile     "C:/Program Files/Apache Software Foundation/Apache2.2/logs/mod_jk.shm"
JkLogFile     "C:/Program Files/Apache Software Foundation/Apache2.2/logs/mod_jk.log"
JkLogLevel    debug
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

Include conf/extra/httpd-ssl.conf
...

其中 conf/workers.properties 如下:

worker.list=worker1
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009

并且 conf/extra/httpd-ssl.conf 包含以下几行:

Listen 443

AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl    .crl

SSLPassPhraseDialog  builtin

SSLSessionCache        "shmcb:C:/Program Files/Apache Software Foundation/Apache2.2/logs/ssl_scache(512000)"
SSLSessionCacheTimeout  300

SSLMutex default

<VirtualHost _default_:443>
    DocumentRoot "C:/https"
    ServerName www.webrep.local
    ServerAdmin webmaster@webrep.local
ErrorLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/https-error.log"
TransferLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/https-access.log"

SSLEngine on

SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile "C:/Program Files/Apache Software Foundation/Apache2.2/conf/ssl/my-server.cert"
SSLCertificateKeyFile "C:/Program Files/Apache Software Foundation/Apache2.2/conf/ssl/my-server.key"

SSLCACertificateFile "C:/Program Files/Apache Software Foundation/Apache2.2/conf/ssl/ca/myCA.pem"

SSLOptions +StdEnvVars +ExportCertData
Alias /examples/oneway/ "C:/https/oneway/"
<Directory "C:/https/oneway">
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

Alias /examples/twoway/ "C:/https/twoway/"
<Directory "C:/https/twoway">
    SSLVerifyClient require
    SSLVerifyDepth  10
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

BrowserMatch ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

CustomLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/ssl_request.log" \
          "%t %h %SSL_PROTOCOLx %SSL_CIPHERx \"%r\" %b"

JkMount  /examples/oneway/servlets/* worker1
JkMount  /examples/twoway/servlets/* worker1
JkExtractSSL Off
JkEnvVar SSL_CLIENT_S_DN
JkEnvVar SSL_CLIENT_CERT

</VirtualHost>                                  

在 Tomcat 上,我刚刚添加了一个简单的 servlet 输出:

request.getAttribute("SSL_CLIENT_CERT")

下:

C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\examples\WEB-INF\classes

【问题讨论】:

【参考方案1】:

看来问题不在于JkEnvVar,显然是当JkMount 和+Alias 引用同一个URL 时,JkMount 优先,并且里面的指令永远不会生效(例如,尝试限制访问整个带有“全部拒绝”的 dir - 它永远不会生效;servlets/jsps 可以正常访问)。

两种解决方案:

1) 使用指令来控制对将在 Tomcat 中运行的代码的访问(即通过 JkMount 映射到 Tomcat)。 2) 使用 'SetHandler jakarta-servlet' 而不是 JkMount(更多信息请参见http://tomcat.apache.org/connectors-doc/reference/apache.html 的结尾)。这在里面有效。有人告诉我它也可以在里面工作,但我还没有检查过。

希望这可以节省我们为解决此问题而花费的大量时间...

【讨论】:

我发现当 JkMount 和 都引用同一个 URL 时,两者似乎都可以工作。在我的配置中,我在 VirtualHost :443 中有一个 Location ,它会提升 SSL 栏(需要客户端身份验证),还有一个用于相同 URL 的 JkMount,两者都可以工作。

以上是关于JkEnvVar SSL_CLIENT_CERT 在“SSLVerifyClient 需要”时不起作用(在目录级别设置)的主要内容,如果未能解决你的问题,请参考以下文章

阅读客户端证书的主题

我用nginx集群tomcat的时候,如果要做ssl,是否只要在nginx上面做就可以了