5

For security reasons, the authentication for a web application should be migrated to SSL client certificates. It should be possible to log in with either username/password or SSL. In addition, users from the intranet should be allowed to use the App without additional authentication.

We have tried to implement this scenario according to the official documentation, but without success.

Here is our current config

<Directory /opt/app/system/html>
    RedirectMatch permanent ^/$ /exec/login.pl
    Options -Indexes +FollowSymLinks
    SSLVerifyClient optional
    SSLVerifyDepth  2
    SSLRequire      %{SSL_CLIENT_I_DN_O} eq "Company_O"
    SSLOptions      +FakeBasicAuth

    Satisfy     any

    AuthType Basic
    AuthName "Zugriffsschutz"
    AuthBasicProvider file
    AuthUserFile /etc/apache2/htaccess/iapp.passwd
    require valid-user

    Order allow,deny
    Allow from 10.20.0.0/255.255.0.0
    Allow from 10.144.100
</Directory>

With this configuration, a client certificate is not even requested. If we remove the basic auth configuration, the SSL client authentication works well.

2 Answers 2

9

The question is three months old so my answer may not be needed by the OP but it may help anyone wanting this configuration.

The question is tagged apache-2.4 but the configuration looks like one which is appropriate for 2.2. This isn't entirely surprising as many examples in the Apache 2.4 documentation seem themselves not to be appropriate to 2.4.

I had such a configuration working in 2.2 (except for the "Allow from " which didn't work) and had to rewrite it for 2.4. I found that it needed some elements which weren't immediately apparent in the documentation.

I offer no warranty for this; it's based on my configuration file with no testing. +StrictRequire may not be needed in SSLOptions - I haven't tried without it, but it does work this way.

For that matter, the SSLOptions line may not be required at all - the +FakeBasicAuth option probably isn't being used. In the configuration I have here, as soon as Company_O is found in the certificate, access will be granted. As I understand it, +FakeBasicAuth is used with Require valid-user (alone) and access is granted if the DN from the certificate is found in the user list defined in AuthUserFile, along with an appropriate password. My system doesn't work that way, and I suspect that the OP didn't want to do that either.

<Directory /opt/app/system/html>
    RedirectMatch permanent ^/$ /exec/login.pl
    Options -Indexes +FollowSymLinks

    # Anything which matches a Require rule will let us in

    # Make server ask for client certificate, but not insist on it
    SSLVerifyClient optional
    SSLVerifyDepth  2
    SSLOptions      +FakeBasicAuth +StrictRequire

    # Client with appropriate client certificate is OK
    <RequireAll>
        Require ssl-verify-client
        # Correction: eq is integer comparison, string comparison requires ==
        # Require expr %{SSL_CLIENT_I_DN_O} eq "Company_O"
        Require expr %{SSL_CLIENT_I_DN_O} == "Company_O"
    </RequireAll>

    # Set up basic (username/password) authentication
    AuthType Basic
    AuthName "Zugriffsschutz"
    AuthBasicProvider file
    AuthUserFile /etc/apache2/htaccess/iapp.passwd

    # User which is acceptable to basic authentication is OK
    Require valid-user

    # Access from these addresses is OK
    Require ip 10.20.0.0/255.255.0.0
    Require ip 10.144.100
</Directory>

I do have

<Directory />
    ...
    Require all denied
    ...
</Directory>

in a different configuration file - it could be that that is an important part of the recipe.

What took me a while to get this working was that it seemed that the Require expr %{SSL_CLIENT bit would work on its own but eventually I realised that Require ssl-verify-client was also required (see http://httpd.apache.org/docs/2.4/mod/mod_ssl.html#authzproviders)

2
  • The above example helped me greatly but I could not understand why I could authenticate with any text matching for Require expr %{SSL_CLIENT_I_DN_O} eq "...". Turns out that you must NOT use eq in this scenario as it is integer equality, which is always true with strings. Instead use == as the operator (string equality).
    – Scott
    Jan 19, 2020 at 15:37
  • Thanks @Scott! That's apparently something I never tested. I have updated my own configuration and the answer above with your correction. Feb 4, 2020 at 21:12
0

I found @yitzchok-lavi answer very useful, but if (like me) you want to avoid the basic authentication popup yo appear for clients outside your network and without a client certificate, the Require valid-user directive needs to be inside the RequireAll section. Also, the OP question suggests this was already present somewhere ese in their config, but for completeness if someone stumbles on this question, also the SSLCACertificateFile directive is necessary (to define which CA client certs will be verified against).

The configuration snippet I use:

<Directory /opt/app/system/html>
    RedirectMatch permanent ^/$ /exec/login.pl
    Options -Indexes +FollowSymLinks

    # Anything which matches a Require rule will let us in

    # Make server ask for client certificate, but not insist on it
    SSLVerifyClient optional
    SSLVerifyDepth  2
    SSLOptions      +FakeBasicAuth +StrictRequire
    # client certs will be verified against this CA
    SSLCACertificateFile /etc/apache2/ssl/iapp-ca.pem

    # Client with appropriate client certificate is OK
    <RequireAll>
        Require ssl-verify-client
        Require expr %{SSL_CLIENT_I_DN_O} == "Company_O"
        # User which is acceptable to basic authentication is OK
        Require valid-user
    </RequireAll>

    # Set up basic (username/password) authentication
    AuthType Basic
    AuthName "Zugriffsschutz"
    AuthBasicProvider file
    AuthUserFile /etc/apache2/htaccess/iapp.passwd

    # Access from these addresses is OK
    Require ip 10.20.0.0/255.255.0.0
    Require ip 10.144.100
</Directory>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .