1

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.)

T2PS
  • 113
  • 3

1 Answers1

1

You can use mod_ssl with basic auth to allow only who have presented a valid certificate. You need to modify the LimitExcept part like this:

<LimitExcept GET>
    AuthType Basic
    AuthName "no-GET thingy"
    Require ssl-verify-client
</LimitExcept>

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:

<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>
Lacek
  • 6,585
  • 22
  • 28
  • This works in terms of requiring a certificate, is there a way of including the checks of certificate properties as well? – T2PS Oct 25 '21 at 06:00
  • 1
    I have added an example of checking client certificate properties. – Lacek Oct 25 '21 at 07:51