我最终在这里写下这篇文章,因为我在 apache、SSL/TLS 和客户端证书认证方面遇到了很多困难,这些认证应该使用证书的序列号来限制对特定 API 调用的访问。
最好用一些细节来解释:
用户必须能够访问:
https://{主机}/apiv3xx/s?test没有任何问题和限制,但对于以下网址:
https:// {主机} / apiv3xx / x?action = login&user = blablabla需要客户端证书才能执行调用。我想实施以下解决方案:
<Location /apiv3xx>
SetEnv api 1
SSLOptions +StdEnvVars -ExportCertData
SSLVerifyClient optional
SSLVerifyDepth 10
</Location>
另外还有一些重写规则来控制逻辑:
RewriteCond %{REQUEST_URI} ^/apiv3xx/ [NC]
RewriteCond %{QUERY_STRING} action=log([^&]*)?(?=&|$) [NC,OR]
RewriteCond %{QUERY_STRING} action=adm([^&]*)?(?=&|$) [NC,OR]
RewriteCond %{QUERY_STRING} action=ctc([^&]*)?(?=&|$) [NC]
RewriteCond %{SSL:SSL_CLIENT_M_SERIAL} !(01000000000140AAD72ACCXXXXXX|02000000000140BAD37F1XXXXXXX)
RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
RewriteRule (.*) - [F,L]
所以...我现在的问题很简单:我没有从请求中收到任何序列号,并且从逻辑上讲,条件不满足。
我在网上搜索了好几天的解决方案,却只找到了这个老问题文章(我最终从中推断出我的解决方案)但它似乎没用。
答案1
使用 WireShark 记录 SSL 会话,然后检查 SSL ALERT 协议。这将帮助您了解协商。在 apache 服务器上启用 SSL 调试。检查 apache 服务器是否正在请求客户端重新协商会话以及客户端是否正在发送证书。如果需要,如果您有服务器的 RSA 密钥和证书,您还可以解密会话。
另外,在客户端上,您必须使服务器值得信任。否则客户端将不会发送证书。
另请注意,由于重新协商错误,SSL/TLS 协议已更改。使用不同版本协议的客户端和服务器不兼容。请参阅:CVE-2009-3555
您可能需要启用:
SSLOptions +OptRenegotiate