4

We use Apache 2.4.10 on a Debian Server. Requests are redirected from an Apache Proxy Server (same system and version) who acts as balancer (only the one balance member at the moment).

The access to the related single virtual host is generally restricted via AuthType Basic. Just one folder containing public documents should be accessable without authentication.

I tested multiple ways (new apache 2.4 syntax) to accomplish that - but no matter, which method i tried, i always stucked at the same issue: any comparison with the REQUEST_URI does not work as expected - with or without a regular expression. It seems as if the REQUEST_URI had an invalid value at the time when a comparison takes place.

I tried i.a. the following alternatives:

A)

<VirtualHost *:80>

ServerName domain.name
DocumentRoot /var/www/domain.name
DirectoryIndex index.php

<Directory "/var/www/domain.name/">

    AuthType Basic
    AuthName "Restricted"
    AuthBasicProvider file
    AuthUserFile /path/to/user/file

    <RequireAny>
        Require method OPTIONS
        Require expr %{REQUEST_URI} =~ m#^/docs#
        Require valid-user
    </RequireAny>

    Options +ExecCGI +FollowSymLinks
    AllowOverride All

</Directory>

CustomLog "/var/log/apache2/test_log" "%t REQUEST_URI:%{REQUEST_URI}e"

</VirtualHost>

B)

<VirtualHost *:80>

ServerName domain.name
DocumentRoot /var/www/domain.name
DirectoryIndex index.php

<Directory "/var/www/domain.name/">

    AuthType Basic
    AuthName "Restricted"
    AuthBasicProvider file
    AuthUserFile /path/to/user/file

    <RequireAny>
        Require method OPTIONS
        Require valid-user
    </RequireAny>

    Options +ExecCGI +FollowSymLinks
    AllowOverride All

</Directory>

<LocationMatch "^/docs">
    AuthType None
    Require all granted
</LocationMatch>

CustomLog "/var/log/apache2/test_log" "%t REQUEST_URI:%{REQUEST_URI}e"

</VirtualHost>

C)

<VirtualHost *:80>

ServerName domain.name
DocumentRoot /var/www/domain.name
DirectoryIndex index.php

<Directory "/var/www/domain.name/">

    SetEnvIf Request_URI /docs noAuth=1

    AuthType Basic
    AuthName "Restricted Files"
    AuthBasicProvider file
    AuthUserFile /path/to/user/file

    <RequireAny>
        Require method OPTIONS
        Require env noauth
        Require valid-user
    </RequireAny>

    Options +ExecCGI +FollowSymLinks
    AllowOverride All

</Directory>

CustomLog "/var/log/apache2/test_log" "%t REQUEST_URI:%{REQUEST_URI}e"

</VirtualHost>

Every alternative seems to stuck at the same issue. The comparison with the REQUEST_URI failes or does not work properly.

An example: When i change line 16 in example A to

Require expr %{REQUEST_URI} =~ m#^/[a-z]#

(as a test) then it works (access granted without credentials).

When i change [a-z] to e.g. [d-i], it still works, but when i change [a-z] to e.g. [d-g], it does not work anymore and the user/pass dialogue appears.

The exact same behaviour appears, when i change the regular expression in the LocationMatch directive in example B accordingly.

Another hint:

Using <Location /docs> instead of <LocationMatch... (see example B) does also not work. But <Location /> works.

And:

The log-output is always identical:

When access is granted without credentials the value of the REQUEST_URI is the same as the path part of the requested URL (e.g. /docs).

But when the user/pass-dialogue appears, the value is a dash ("-") this seems to be default value that apache uses for empty or not available values.

And:

The problem does persist, even when i access the server directly (without the proxy) or when i use e.g. wget to make a request to localhost on the server.

Does anyone have an idea whats going on here!?...

lsblsb
  • 1,292
  • 12
  • 19
  • Logging %{REQUEST_URI}e is misleading, it's not reading from the same source as %{REQUEST_URI} in an expression. The former requires that httpd have gotten far enough to copy data to environment variables. – covener Feb 04 '17 at 14:19
  • I will have a look later today, but mod_log_debug would be more helpful. It takes expressions as its value argument and can show you the value at different phases. Perhaps some module is changing r->uri along the way and this will give a hint. – covener Feb 04 '17 at 14:21
  • ok, i'll check mod_log_debug meanwhile... – lsblsb Feb 06 '17 at 15:37
  • mod_log_debug does not output anything to any log. tested at different positions - no success. – lsblsb Feb 06 '17 at 15:58

2 Answers2

3

I finally found a workaround by myself. I use version A) - but with the environment variable THE_REQUEST instead of REQUEST_URI. Fortunately it works!

The adjusted version of A) - for GET requests only:

<VirtualHost *:80>

ServerName domain.name
DocumentRoot /var/www/domain.name
DirectoryIndex index.php

<Directory "/var/www/domain.name/">

AuthType Basic
AuthName "Restricted"
AuthBasicProvider file
AuthUserFile /path/to/user/file

<RequireAny>
    Require method OPTIONS
    Require expr %{THE_REQUEST} =~ m#GET\s+\/docs\/[^\/]+\s+HTTP#
    Require valid-user
</RequireAny>

Options +ExecCGI +FollowSymLinks
AllowOverride All

</Directory>

</VirtualHost>
lsblsb
  • 1,292
  • 12
  • 19
  • I guess the problem is somehow related to mod_rewrite.. the REQUEST_URI seems to have changed at the time matching happens. – staabm Jun 06 '17 at 15:35
0

Instead of using Location, you can use another directory.

<VirtualHost *:80>
    ServerName domain.name
    DocumentRoot /var/www/domain.name
    DirectoryIndex index.php
    <Directory "/var/www/domain.name/">
        AuthType Basic
        AuthName "Restricted"
        AuthBasicProvider file
        AuthUserFile /path/to/user/file
        <RequireAny>
            Require method OPTIONS
            Require valid-user
        </RequireAny>
        Options +ExecCGI +FollowSymLinks
        AllowOverride All
    </Directory>
    **<Directory "/var/www/domain.name/docs/">
        AuthType None
        Require all granted
    </Directory>**
    CustomLog "/var/log/apache2/test_log" "%t REQUEST_URI:%{REQUEST_URI}e"
</VirtualHost>

The same can be accomplished through the use of .htaccess. A related question has been answered in How to remove .htaccess password protection from a subdirectory

Community
  • 1
  • 1
Alexios Tsiaparas
  • 880
  • 10
  • 17
  • I know. I also tried it via directory. But it did not work - at least without a .htaccess file (which i don't want to use in this case). But maybe I should give it a try again. But it is just a workaround and doesn't solve the problem. – lsblsb Feb 13 '17 at 17:08
  • If you raise the level of apache2 logging, you may see that the REQUEST_URI is going through multiple passes, and changing in between passes, due to rewrite actions. This may cause your regex test to be valid for the original REQUEST_URI but to fail for the rewritten one in the end. – presterjohn Jul 19 '22 at 02:58