пятница, 1 октября 2010 г.

Subversion поверх HTTPS с авторизацией в LDAP - проблемы настройки искорости



Переезжаем на SVN. Всякие преимущества по сравнению с CVS расписывать не буду - в инете навалом.
Опишу несколько тонкостей и граблей, с которыми столкнулся.

Перво-наперво описание задачи.
Очевидные требования: криптование, централизованная авторизация.

После ряда размышлений остановился на связке SVN поверх HTTPS в связке с LDAP.

svn+ssh неудобно администрировать при большом количестве девелоперов и не-девелоперов, кому нужен доступ (анонимного доступа к репо нет)
Да и с LDAP там не так просто - на консоль сервера девелоперов пускать не стоит.

Первый этап - конфигурация Apache + SVN + LDAP. SSL коснемся отдельно - там закопаны здоровенные грабли. которые у меня отняли с неделю разборок :)

В настройку SVN over HTTP я сильно углубляться не буду - в инете полно инфы. Приведу лишь заведомо рабочие конфигурации (ну, как обычно :) )

Стандартный VirtualHost, для SVN+LDAP нужно добавить:

<VirtualHost *:80>
ServerName svn.example.com
DocumentRoot /svn
ErrorLog log/svn.error.log
CustomLog log/svn.access.log combined

LoadModule dav_svn_module modules/mod_dav_svn.so

RequestHeader edit Destination ^https http early

<Location />
DAV svn
SVNParentPath /svn/repositories
SVNListParentPath On
# Enable WebDAV automatic versioning
SVNAutoversioning On
SVNPathAuthz Off
# Repository Display Name
SVNReposName "Subversion Repository"
AuthzLDAPAuthoritative on
AuthType Basic
AuthName "SVN authorization"
AuthBasicProvider ldap
AuthLDAPURL "ldap://ldap.example.com:389/dc=example,dc=com?uid?sub?(objectClass=*)"
AuthLDAPGroupAttributeIsDN off
AuthLDAPGroupAttribute memberUid

Require ldap-group cn=svn,ou=groups,ou=Developers,dc=example,dc=com
Require ldap-group cn=svn_ro,ou=groups,ou=Developers,dc=example,dc=com
</Location>
include conf/svn/authorization.conf
</VirtualHost>


Комментарии по примеру этого конфига:

  • SSL под апачем в примере не приведен сознательно, подробности я рассмотрю ниже

  • строка конфига RequestHeader edit Destination ^https http early - эбход граблей, связанных с решением проблемы SSL (см. далее)

  • настройки LDAP, разумется, нужно адаптировать "под себя".

  • предлагаемая конфигурация не предусматривает ограничений доступа на уровне отдельных каталогов в SVN - только на уровне репозитариев. Это не значит, что так сделать невозможно, просто для введения ограничений на уровне каталогов конфигурация апача очень резко усложняется. Если для одного-двух репо это еще приемлемо, то в моем случае (несколько десятков репо) специального SVN админа решили все-таки не нанимать :) - неоправданно. лучше несколько потерять в функционале, тем более, что потеря не такая уж и критичная

  • отдельный инклуд conf/svn/authorization.conf сделан для удобства конфигурирования. Его содержимое приблизительно такое:

    <Location /svnrepo>
    <LimitExcept MERGE MKCOL POST PUT DELETE PATCH PROPPATCH>
    Require ldap-group cn=svn,ou=groups,ou=Developers,dc=example,dc=com
    Require ldap-group cn=svn_ro,ou=groups,ou=Developers,dc=example,dc=com
    </LimitExcept>
    <Limit MERGE MKCOL POST PUT DELETE PATCH PROPPATCH>
    Require ldap-group cn=svn,ou=groups,ou=Developers,dc=example,dc=com
    </Limit>
    </Location>

    Location ссылается на конкретный существующий репозитарий. Лимиты установлены для того, чтобы обеспечить два типа доступа к репозитарию: полный и read-only, что весьма удобно.

Итак, с первой частью разобрались - SVN over HTTP у нас работает. Когда же я подключил SSL в апаче (и оно все заработало) я получил от девелоперов массу жалоб. Скорость такой связки оказалась в полтора раза ниже, чем на других аналогичных репо в инете (например, гугль)! Ну И в разы ниже, чем доступ по HTTP. Под "скоростью" я понимаю время чекаута репозитария, который уже засинхронизирован. Т.е замерялось время где-то так:

$ svn co https://svn.example.com
$ time svn co https://svn.example.com

Время на второй чекаут при практически пустом репо (1-2 файла) достигало 11 секунд, когда должно составлять максимум 3-4.
Исследование показало, что основное время потребляется при обмене ключами. А, т.к. перед началом собственно передачи файлов svn передает несколько команд на сервер, это приводит к значительным задержкам.

Попытки оптимизировать апача ни к чему не привели :(

В результате мне надоело и я поставил перед апачем Nginx как проксик, навесив на него обязанности https сервера.
С вот таким конфигом:

server {
listen 443;
server_name svn.example.com;
error_log /var/log/nginx/svn_error_ssl.log;
access_log /var/log/nginx/svn_access_ssl.log main;
server_name_in_redirect off;

ssl on;
ssl_certificate /etc/nginx/cert/certificate.pem;
ssl_certificate_key /etc/nginx/cert/privkey.pem;

ssl_session_timeout 5m;

ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers !ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;

# output compression saves bandwidth
gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/plain text/html text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

# make sure gzip does not lose large gzipped js or css files
gzip_buffers 16 8k;

# Disable gzip for certain browsers.
gzip_disable “MSIE [1-6].(?!.*SV1)”;

location = /favicon.ico { }

location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://svn.local/;
proxy_redirect default;
proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;
proxy_no_cache $http_pragma $http_authorization;
}
}


В результате скорость значительно возросла и жалобы от девелоперов прекратились.

НО обращаю внимание на одну очень важную тонкость! В апаче обязательно нужно дописать директиву RequestHeader (см. выше), иначе при операции COPY мы получим HTTP error 502 ! Это связано с тем, что проксик не изменяет http заголовок Destination и, как результат, svn сервер ведет себя не совсем правильно.

Комментариев нет:

Отправить комментарий