我们有一个在 HTTP 上运行的内部服务,并在其前面放置了一个 Apache 2.4 实例 (Debian Bullseye) 作为 HTTPS 的代理。Apache 和 HTTPS 已启动并运行,但还有一个额外的要求是客户端证书 - 具体来说,GET 和 HEAD 请求可以匿名进行,但所有其他方法都必须提供符合特定条件的有效客户端证书。
我们构建的软件针对 IIS,因此 Apache 对我们来说是一个未知数(最初的实施者已经离开)。我们尝试调整我们继承的配置,将配置的站点部分(省略证书文件路径指令)设置为:
SSLVerifyClient optional
SSLVerifyDepth 10
ProxyPass /internal http://<internalIP>:/internal
ProxyPassReverse /internal http://<internalIP>:/internal
SSLOptions +StdEnvVars
<Location /internal>
Order deny,allow
Allow from all
<LimitExcept GET>
SSLRequire ( %{SSL_CLIENT_S_DN_O} eq "(org)" and %{SSL_CLIENT_S_DN_OU} eq "(unit)" and %{SSL_CLIENT_S_CN} eq "(name)" )
</LimitExcept>
</Location>
我们还没有尝试使用客户端证书(例如 POST)进行此操作,因为https://<proxy>/internal
现在简单的 GET 会失败并出现 403 错误,并且 errors.log 消息为:
AH02229:访问代理:http://{internalIP} / internal 失败,原因:未满足 SSL 要求表达式
乍一看,这似乎SSLRequire
也适用于 GET 检查,与 正好相反<LimitExcept>
。
SSLRequire
是否有一些指令组合我们可以用来获得所需的行为?(理想情况下,也可以摆脱现在显然已被弃用的指令。)
答案1
您可以使用mod_ssl
基本身份验证来仅允许出示有效证书的人。您需要修改LimitExcept
以下部分:
<LimitExcept GET>
AuthType Basic
AuthName "no-GET thingy"
Require ssl-verify-client
</LimitExcept>
您可以使用任意数量和组合的Require
语句,因此如果您也想检查证书属性,您可以执行以下操作:
<LimitExcept GET>
AuthType Basic
AuthName "no-GET thingy"
<RequireAll>
Require ssl-verify-client
Require expr "'%{SSL_CLIENT_S_DN_O}' == 'org'"
Require expr "'%{SSL_CLIENT_S_DN_OUT}' == 'theOU'"
Require expr "'%{SSL_CLIENT_S_DN_CN}' != 'notThisUser'"
</RequireAll>
</LimitExcept>