We have an internal service running on HTTP with an Apache 2.4 instance (Debian Bullseye) put in front of it as a proxy for HTTPS. Apache and HTTPS are up and running, but an additional requirement is for client certificates -- specifically, GET and HEAD requests may proceed anonymously, but all other methods must present a valid client certificate matching certain conditions.
The software we build targets IIS, so Apache is something of an unknown quantity for us (the original implementer has since departed). Our attempts to adapt the configuration we've inherited has the site portion of the config (omitting the certificate file path directives) as:
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>
We haven't yet tried this with a client certificate for eg. POST because a simple GET to https://<proxy>/internal
now fails with a 403, and errors.log message:
AH02229: access to proxy:http://{internalIP}/internal failed, reason: SSL requirement expression not fulfilled
At first glance this looks like the SSLRequire
check is being applied to GET as well, contrary to the <LimitExcept>
.
Is there a combination of directives we can use to get the desired behaviour? (Ideally one that moves away from the apparently now-deprecated SSLRequire
as well.)
You can use
mod_ssl
with basic auth to allow only who have presented a valid certificate. You need to modify theLimitExcept
part like this:You can use any number and combination of
Require
statements, so if you want to check the certificate properties as well, you can do something like this: