Apache 2.4: AuthType Basic и REQUEST_URI - сравнения (с регулярным выражением или без него) не работают должным образом
Мы используем Apache 2.4.10 на сервере Debian. Запросы перенаправляются с прокси-сервера Apache (той же системы и версии), который выступает в качестве балансировщика (только один участник баланса на данный момент).
Доступ к связанному одиночному виртуальному хосту обычно ограничен через AuthType Basic. Только одна папка, содержащая публичные документы, должна быть доступна без аутентификации.
Для этого я протестировал несколько способов (новый синтаксис apache 2.4), но независимо от того, какой метод я использовал, я всегда придерживался одной и той же проблемы: любое сравнение с REQUEST_URI не работает должным образом - с регулярным выражением или без него. Кажется, что REQUEST_URI имел недопустимое значение во время сравнения.
Я попробовал следующие варианты:
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>
Кажется, что каждая альтернатива застревает в той же самой проблеме. Сравнение с REQUEST_URI не выполняется или не работает должным образом.
Пример: когда я меняю строку 16 в примере А на
Require expr %{REQUEST_URI} =~ m#^/[a-z]#
(как тест), затем он работает (доступ предоставляется без учетных данных).
Когда я изменюсь [a-z]
например [d-i]
, это все еще работает, но когда я изменяюсь [a-z]
например [d-g]
, это больше не работает, и появляется диалог пользователя / прохода.
Точно такое же поведение появляется, когда я изменяю регулярное выражение в директиве LocationMatch в примере B соответственно.
Еще один намек:
С помощью <Location /docs>
вместо <LocationMatch...
(см. пример B) также не работает. Но <Location />
работает.
А также:
Лог-выход всегда идентичен:
Когда доступ предоставляется без учетных данных, значение REQUEST_URI совпадает с частью пути запрошенного URL (например, / docs).
Но когда появляется user / pass-dialog, значением является тире ("-"), это значение по умолчанию, которое apache использует для пустых или недоступных значений.
А также:
Проблема сохраняется, даже когда я обращаюсь к серверу напрямую (без прокси) или когда я использую, например, wget, чтобы сделать запрос к localhost на сервере.
У кого-нибудь есть идея, что здесь происходит?
2 ответа
Я наконец нашел обходной путь самостоятельно. Я использую версию A) - но с переменной окружения THE_REQUEST
вместо REQUEST_URI
, К счастью, это работает!
Скорректированная версия A) - только для запросов GET:
<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>
Вместо использования Location вы можете использовать другой каталог.
<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>
То же самое можно сделать с помощью.htaccess. Ответ на соответствующий вопрос дан в разделе Как удалить защиту паролем.htaccess из подкаталога.