Мы хотим ограничить доступ к нашему серверу разработки для тех пользователей, у которых есть действующий сертификат клиента SSL. Мы запускаем 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 / будет работать нормально.
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), и для этого проекта есть репозиторий git по адресу https: //my.server/git/project который не может требовать сертификат клиента SSL. Поскольку URL-адрес / git / project также сопоставляется снова / project Location
блоков, такая конфигурация кажется невозможной с учетом моих текущих выводов.
Вопрос: Почему это происходит и как мне решить мою проблему?
В конце концов, я хочу потребовать авторизацию сертификата клиента SSL для всего сервера, за исключением / git и / someLocation, с минимально возможной конфигурацией (поэтому мне не нужно изменять конфигурацию каждый раз, когда развертывается что-то новое или новое добавлен репозиторий git).
Обновить Дополнительная информация: обратите внимание, что в некоторых случаях https: //my.server/project фактически проксируется обратным прокси, так что <Directory /path/to/project>
директива невозможна. Если я хочу защитить это приложение с помощью сертификата клиента SSL, это обязательно должно быть с <Location /project>
(или более общий <Location />
) блок.
Обновление 2 Я только что протестировал это в apache 2.4.3 с тем же результатом. Если это произошло из-за какой-то ошибки, она присутствует как минимум в двух версиях.
Примечание: я переписал свой вопрос (вместо того, чтобы просто добавлять обновления внизу), чтобы учесть мои новые результаты и, надеюсь, прояснить это.
Согласно нынешней Документация Apache это может быть проблемой:
В контексте сервера это применяется к процессу аутентификации клиента, используемому в стандартном квитировании SSL при установке соединения. В контексте каталога он вызывает повторное согласование SSL с перенастроенным уровнем проверки клиента после чтения HTTP-запроса, но до отправки HTTP-ответа.
Как насчет использования контекста <Directory> вместо <Location>. Одна запись для корневого уровня, а другая для пути Script-Alias: / path / to / gitolite-shell /
Обновить:
Я нашел несколько советов по этому поводу -> Вопрос / ответ на Stackoverflow