ScriptAlias ​​заставляет запросы соответствовать слишком большому количеству блоков Location. Что происходит?

ScriptAlias ​​заставляет запросы соответствовать слишком большому количеству блоков Location. Что происходит?

Мы хотим ограничить доступ на нашем сервере разработки для тех пользователей, у которых есть действительный сертификат SSL Client. Мы используем Apache 2.2.16 на Debian 6.

Однако для некоторых разделов (в основном git-http, настройка с gitolite наhttps://my.server/git/) нам нужно исключение, поскольку многие клиенты git не поддерживают клиентские сертификаты SSL.

Мне удалось потребовать аутентификацию клиентского сертификата для сервера и добавить исключения для некоторых местоположений. Однако, похоже, это не работает для git.

Текущая конфигурация выглядит следующим образом:

SSLCACertificateFile ssl-certs/client-ca-certs.crt
<Location />
  SSLVerifyClient require
  SSLVerifyDepth 2
</Location>
# this works
<Location /foo>
  SSLVerifyClient none
</Location>
# this does not
<Location /git>
  SSLVerifyClient none
</Location>

Я также попробовал альтернативное решение с тем же результатом:

# require authentication everywhere except /git and /foo
<LocationMatch "^/(?!git|foo)">
  SSLVerifyClient require
  SSLVerifyDepth 2
</LocationMatch>

В обоих случаях пользователь без клиентского сертификата может получить полный доступ к my.server/foo/, но не к my.server/git/ (доступ запрещен, поскольку не предоставлен действительный клиентский сертификат). Если я полностью отключу аутентификацию SSL-сертификата клиента, my.server/git/ будет работать нормально.

Проблема ScriptAlias

Gitolite настроен с использованием директивы ScriptAlias. Я обнаружил, что проблема возникает с любым похожим ScriptAlias:

# Gitolite
ScriptAlias /git/ /path/to/gitolite-shell/
ScriptAlias /gitmob/ /path/to/gitolite-shell/
# My test
ScriptAlias /test/ /path/to/test/script/

Обратите внимание, что /path/to/test/script — это файл, а не каталог, то же самое касается и /path/to/gitolite-shell/.

Мой тестовый скрипт просто выводит среду на экран, все очень просто:

#!/usr/bin/perl

print "Content-type:text/plain\n\n";
print "TEST\n";
@keys = sort(keys %ENV);
foreach (@keys) {
    print "$_ => $ENV{$_}\n";
}

Кажется, если я пойдуhttps://my.server/test/someLocation, что применяются любые директивы SSLVerifyClient, которые находятся в блоках Location, соответствующих /test/someLocationили просто /someLocation.

Если у меня следующая конфигурация:

<LocationMatch "^/f">
        SSLVerifyClient require
        SSLVerifyDepth 2
</LocationMatch>

Затем для следующего URL-адреса требуется клиентский сертификат:https://my.server/test/foo. Однако следующий URL-адрес не соответствует:https://my.server/test/somethingElse/foo

Обратите внимание, что это, похоже, применимо только к конфигурации SSL. Следующее не оказывает никакого влияния наhttps://my.server/test/foo:

<LocationMatch "^/f">
        Order allow,deny
        Deny from all
</LocationMatch>

Однако он блокирует доступ кhttps://my.server/foo.

Это представляет собой серьезную проблему в случаях, когда у меня есть какой-то проект, запущенный вhttps://my.server/project(что требует авторизации SSL-сертификата клиента),идля этого проекта есть репозиторий githttps://my.server/git/projectкоторый не может требовать сертификат клиента SSL. Поскольку URL-адрес /git/project также сопоставляется с Locationблоками /project, такая конфигурация кажется невозможной, учитывая мои текущие выводы.

Вопрос: Почему это происходит и как решить мою проблему?

В конце концов, я хочу потребовать авторизацию сертификата SSL-клиента для всего сервера, за исключением /git и /someLocation, с минимально возможной конфигурацией (чтобы мне не приходилось изменять конфигурацию каждый раз, когда что-то новое развертывается или добавляется новый репозиторий git).

ОбновлятьДополнительная информация: Обратите внимание, что в некоторых случаяхhttps://my.server/projectна самом деле обратное проксирование, так что <Directory /path/to/project>директива невозможна. Если я хочу защитить это приложение с помощью сертификата клиента SSL, это должно быть обязательно с <Location /project>(или более общим <Location />) блоком.

Обновление 2Я только что проверил это в apache 2.4.3, с тем же результатом. Если это из-за какой-то ошибки, то она присутствует как минимум в двух версиях.


Примечание: я переписал свой вопрос (вместо того, чтобы просто добавить больше обновлений внизу), чтобы учесть мои новые выводы и, надеюсь, сделать его более понятным.

решение1

Согласно текущемуДокументация Apacheэто может быть проблемой:

В контексте каждого сервера он применяется к процессу аутентификации клиента, используемому в стандартном рукопожатии SSL при установлении соединения. В контексте каждого каталога он вызывает повторное согласование SSL с перенастроенным уровнем проверки клиента после прочтения HTTP-запроса, но до отправки HTTP-ответа.

Что насчет использования контекста <Directory> вместо <Location>. Одна запись для корневого уровня, а другая для пути Script-Alias: /path/to/gitolite-shell/

Обновлять:

Я нашел несколько советов по этому случаю ->Вопрос/ответ на Stackoverflow

Связанный контент