Ссылка на оригинал: http://ru.gentoo-wiki.com/HOWTO Subversion сервер при помощи Apache2 и WebDav
C версии: 1.5
Данное HOWTO является вольным переводом оригинальной английской статьи. Также в статью добавленно некоторое количество отсебятины по поводу и без (надеюсь автор оригинала не знает русского и не увидит как я испохабил его несчастную статью).
Данная статья посвещена настройке сервера Subversion под Apache с применением WebDav и только ей. Информацию по клиенту и настройке автономного сервера можно найти по ссылке en:HOWTO Subversion
Предупреждение: Данная статья предусматривает, что читатель - разумный человек и не будет вешать репозиторий не на ssl хост, и вообще заботится о безопасности. |
FIXME: Хорошо бы описать в чем плюсы WebDav подхода и в чем минусы |
Существует известная проблема при больших коммитах (commit, оффициальный перевод - "фиксация изменений", на мой взгляд длинновато) связанная с использованием апачевого (от Apache) "worker" MPM. Рекомендуется просто отключить этот MPM и скомпилировать Apache с "prefork" MPM. Для этого просто добавьте новую (или поменяйте существующую, если таковая уже есть) строчку в package.use (в случае использования Gentoo, естественно):
Файл: /etc/portage/package.use |
www-servers/apache -mpm-worker mpm-prefork |
После чего перекомпилируйте Апач: emerge -aDNtuv apache
Более того, пожалуйста убедитесь, что subversion скомпилированна с (use flag) apache2 и без nowebdav юзами (от use flags).
Для использования WebDav и Subversion модулей их, как ни странно, необходимо включить. Делается это при помощи передачи соответсвующих опций (далее - дефайнов, от Define) Апачу при загрузке. Также, для аутентификации, вам возможно понадобится SSL (если вам так не кажется, советую подумать еще раз). Добавте следующую строчку после уже существующей APACHE2_OPTS строчки. (-D SVN_AUTHZ необходимо для использования авторизации, см. ниже)
Файл: /etc/conf.d/apache2 |
APACHE2_OPTS="$APACHE2_OPTS -D SVN -D SVN_AUTHZ -D DAV -D SSL" |
Необходимо, чтобы Апач имел права на запись на папку репозитория(иев), с которым(и) он должен работать. Это можно сделать двумя способами:
Сменой пользователя/группы папки репозитория:
Воспользуйтесь командой chown apache:apache /путь/к/репозиторию/ -R
Добавлением пользователя apache (или того, под которым ваш Апач бегает) в группу svnusers:
Для начала надо таковую группу создать: groupadd svnusers
Теперь надо добавить пользователя apache в новосозданную группу: usermod -G svnusers -a apache
Ну а теперь надо поменять группу папки репозитория на новосозданную: chgrp svnusers /var/svn/repos/test -R
Осталось всего ничего - сделать то, ради чего все это было нужно - дать доступ на запись группе svnusers: chmod g+w /var/svn/repos/test -R
Лично я, переводчик, рекомендую воспользоваться комбинацией этих способов, из соображений, что права на запись могут понадобится не только Апачу, а включать страждущего пользователя в группу apache тоже как-то нехорошо, т.к. это даст доступ не только к репозиториям. Для упрощения этой задачи мною был написан следующий скрипт:
Файл: create_repository.sh |
#!/bin/sh DIR_MODE=770 FILE_MODE=660 SVN_ROOT="/var/svn" SVN_USER="apache" SVN_GROUP="svn" NAME=${1:?"Usage: create_repository.sh <repository name>"} REPO_DIR="${SVN_ROOT}/${NAME}" svnadmin create "${REPO_DIR}" chown "${SVN_USER}:${SVN_GROUP}" -R "${REPO_DIR}" find "${REPO_DIR}" -type d -exec chmod ${DIR_MODE} {} + find "${REPO_DIR}" -type f -exec chmod ${FILE_MODE} {} + # vim: nobackup |
Вместе с subversion устанавливается файл /etc/apache2/modules.d/47_mod_dav_svn.conf (в случае включенного юза apache2), в котором и содержится практически работающий конфиг (от config - настройка).
Инструкция
<Location /svn> DAV svn
сообщает Апачу о том, что все запросы, чей путь начинается с /svn необходимо обрабатывать при помощи WebDav модуля (Dav svn директива).
Если вам достаточно только одного репозитория то используйте директиву
SVNPath /путь/к/репозиторию
В противном случе, для многочисленных репозиториев, необходимо использовать следующую директиву:
SVNParentPath /путь/к/папке/с/репозиториями
В этом случае все подпапки папки, указанной в SVNParentPath директиве, будут рассматриватся как репозитории Subversion (Даже если они таковыми не являются).
Также существует возможность заставить Апач формировать список репозиториев/содержимого в них, в случае захода с обычного брузера. Для этого существует магическая опция SVNListParentPath (Правда данная опция доступна только с subversion версии 1.3, но для настоящего гентушника это все равно уже антиквариат), которую необходимо установить в on:
SVNListParentPath on
ВАЖНО: При использовании SVNListParentPath может так случится, что вы получите 403 Forbidden, а не список репозиториев (Более подробно данный природный феномен описан здесь). Как вариант избавления, вы можете добавить в описание блока Location заключительный слэш.
<Location /svn/>
В таком случае, вам наверняка также захочется, чтобы Апач также отлавливал и просто путь /svn . Для этого можно воспользоватся магической опцией RedirectMatch (добавив ее куда-нибудь вовне блока Location), как показанно в нижеприведенном заклинании.
RedirectMatch ^(/svn)$ $1/
Дабы избежать ппроблем, вроде описанной тут: Resource cannot be created at the destination..., будет полезно добавить в конфиг директиву:
SVNAutoVersioning On
На данный момент мы, чисто теоретически, имеем работающий Апач с подключенным Сабвершеном (от Subversion). Однако любая подозрительная личность может сделать с нашим репозиторием что захочет, что естественно не входит в наши планы.
Добавление следующих строчек в /etc/apache2/modules.d/47_mod_dav_svn.conf включит базовую аутентификацию Апача
Файл: /etc/apache2/modules.d/47_mod_dav_svn.conf |
AuthType Basic AuthName "Subversion repository" AuthUserFile /var/svn/conf/svnusers Require valid-user # Тип встроенной аутентификации "Basic" посылает пароли открытым текстом, что есть небезопасно. Чтобы избежать ситуации кражи пароля необходимо добавить следующую директиву, которая будет требовать подключения с ssl SSLRequireSSL |
Примечание: Как несложно догадатся, для того чтобы можно было требовать ssl, его неплохо было бы включить. Как это сделать было описано выше. |
Дополнение: Однако намного более завлекательным вариантом является принудительный редирект на ssl хост, т.к. не вводит среднестатистического пользователя в ступор при виде непонятной ошибки на иноземном языке
Начало общефилософского лирического отступления
Также положительным побочным действием предложенного решения является то, что если у вас стандартный ssl порт уже занят, то таким образом можно ликвидировать проблему с запоминанием номера порта, просто заходя на http, а Апач вас уже перешлет на правильный порт (при условии, что вы ему скажите это делать, естественно - болезненной самостоятельностью юниксовые сервера, по счастью, не обладают (хотя периодически и кажется, что они проявляют признаки очень вредного интеллекта, подкидывая все новые и новые гадости)))
Конец лирическому отступлению
Файл: /etc/apache2/modules.d/47_mod_dav_svn.conf |
<Location /svn> [...] RewriteEngine On RewriteCond %{HTTPS} !on RewriteRule ^/(.*) https://%{SERVER_NAME}%{REQUEST_URI} [R] |
Возможность: Чтобы
ограничить доступ только по ssl, недостаточно
директивы SSLRequireSSL в 47_mod_dav_svn.conf.
Для этого необходимо перенести все
директивы из 47_mod_dav_svn.conf
в файл с дефолтным (от default - по умолчанию)
виртуальным хостом для ssl -
XX_mod_ssl_default-vhost.conf. Также
необходимо так поменять номер этого
виртуального хоста так чтобы он грузился
после mod_dav (все файлы в папке
/etc/apache2/conf/modules.d загружаются
в алфавитном порядке). Впрочем это
необходимо только тем у кого настолько
древний Апач (или настолько новый, кто
знает - постоянно туда-сюда эти хосты
путешествуют. По моему мнению, их вообще
выкинуть можно), что дефолтный хост
лежит все еще в modules.d -
их уже месяцов пять как переместили в
vhosts.d. Остальным беспокоится
не зачем - vhosts.d загружаются
после modules.d
Небольшая оптимизация: Однако вместо того чтобы перемещать директивы из файла 47_mod_dav_svn.conf внутрь виртуального ssl-хоста, можно попросту проинклюдить (от include - включать (в себя)) туда целиком файл, предварительно поменяв ему расширение на что-нибуть отличное от .conf, либо вынеся вовне {{filename|modules.d}, дабы самостоятельно Апач его не разыскал. Делается это при помощи магической директивы Include с указанием абсолютного пути до желаемого файла
Начало лирического отступления о культурных особенностях индейцев Вообще-то можно указать и относительный, но стоит учитывать, что Апач - индеец и имеет несколько свои представления о том что такое "относительный путь". Для него это путь относительно истинного пути - путь ServerRoot'а - т.е. по умолчанию откуда-то от /usr/lib/apache2
Конец лирическому отступлению
Оптимизация побольше и по-глобальнее: По-умолчанию Апач грузит все конфиги в папке {{filename|modules.d} по маске {{filename|modules.d/*.conf}, так что можно немного переписать систему инклюдов, дабы разделить конфиги на обычные и продвинутые-ssl-ные. Для этого достаточно переименовать полюбившийся конфиг, в нашем случае - 47_mod_dav_svn.conf, в что-нибудь с расширением отличным от .conf (либо, как уже было предложено выше, создав отдельную папку для подобных продвинутых конфигов), к примеру в 47_mod_dav_svn.ssl-conf. Тогда достаточно будет указать в httpd.conf (или любом другом глобальном конфиге - к примеру в modules.d/40_mod_ssl.conf), внутри соответствующего блока <IfModule ssl_module>/<IfDefine SSL> следующие строчки:
# Загрузить модули зависщие от ssl Include /etc/apache2/modules.d/*.ssl-conf # либо /etc/apache2/modules.ssl.d/*.conf
Анонимный доступ: Хорошо, мы добились того, что теперь при каждом запросе к subversion будет спрашиваться пароль, однако вам может захотеться, чтобы анонимные пользователи могли читать ваш труд, а то зачем все это надо? В таком случае директиву Require valid-user стоит поместить в блок <LimitExcept ...> указав в качестве параметра список операций, которые, по вашему мнению, всякие подозрительные личности без особой опасности могут производить на вашем репозитории:
[...] AuthType Basic [...] # Для любых операций, кроме нижеперечисленных, спрашивать пароль. <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept>
В любом случае, для правильной работы subversion клиента с ssl в дефолтный ssl-хост XX_mod_ssl_default-vhost.conf, либо в 40_mod_ssl.conf, необходимо добавить следующую строчку ( подробности - тут )
BrowserMatch "SVN" redirect-carefully
Упомянутый выше файл /var/svn/conf/svnusers и содержит имена и зашифрованные пароли пользователей.
Чтобы создать этот файл/добавить в него новую запись воспользуйтесь коммандой htpasswd2.
Для создания файла с первым пользователем:
htpasswd2 -c /var/svn/conf/svnusers <имя первого пользователя>
и для добавления последующих:
htpasswd2 /var/svn/conf/svnusers <имя последующего пользователя>
Если управление аж двумя различными файлами с паролями (системного и Апачевого) для вас слишком утомительно, то специально для вас был придуман модуль mod_auth_pam, который использует PAM для аутентификации пользователей. Если у вас нет еще этого модуля - emerge mod_auth_pam
Предупреждение: Да будет вам известно, что mod_auth_pam представляет из себя потенциальную уязвимость: системный пользователь 'apache' (или тот под которым запущен ваш сервер) получит доступ на чтение к /etc/shadow. Это означает, что в случае взлома Апача, злоумышленник получит доступ к файлу /etc/shadow, и сможет натравить на него программу по взлому паролей (дальнейшая судьба системы будет зависить от того, заметите ли вы взлом и примите меры раньше, чем злоумышленник получит пароль рута). |
После сборки mod_auth_pam необходимо внести несколько изменений (суперпользователем) в ваши конфигурационные файлы. Для начала надо выдать пользователю 'apache' доступ на чтение /etc/shadow:
groupadd shadow
gpasswd -a apache shadow
chgrp shadow /etc/shadow
chmod g+r /etc/shadow
Предупреждение: Если у вас есть веб-сервер на котором работают посторонние люди, и он работает под тем же пользователем 'apache', то эти самые посторонние люди без всякого взлома смогут прочесть ваш /etc/shadow, и это уже действительно опасно!. |
После чего внесите следующие изменения в /etc/apache2/modules.d/47_mod_dav_svn.conf: Вовнутрь блока <Location /svn> впишите:
Файл: /etc/apache2/modules.d/47_mod_dav_svn.conf |
<IfModule mod_auth_sys_group.c> AuthPAM_Enabled on AuthType Basic AuthName "Subversion Repository" SSLRequireSSL Require group subversion </IfModule> |
ВАЖНО: В отличие от стандартной ('basic') аутентификации, описанной выше, убедитесь что вы не указали директивы
AuthUserFile /var/svn/conf/svnusers
Впрочем существует возможность оставить стандартную аутентификацию как запасную на случай если PAM модуль по каким-то причинам не сработает. Для этого обратите внимание на файл /etc/apache2/modules.d/10_mod_auth_pam.conf
ВАЖНО: Как уже упоминалось выше базовый тип встроенной аутентификации (AuthType Basic) передает пароли открытым текстом и для обеспечения минимальной безопасности необходимо ограничить аутентификацию только по ссл, при помощи директивы SSLRequireSSL
Ну а для того, чтобы все, в пределах этого параграфа, проделанное имело смысл, необходимо включить mod_auth_pam, добавив -D AUTH_PAM в APACHE2_OPTS в /etc/conf.d/apache2
Для того, чтобы настроить авторизацию в SVN через LDAP или Active Directory, следуйте следующим инструкциям.
В /etc/conf.d/apache2 добавляем -D LDAP и -D AUTH_LDAP
APACHE2_OPTS="-D SSL -D PHP4 -D DAV -D DAV_FS -D SVN -D DAV_SVN -D LDAP -D AUTH_LDAP"
вот пример моей рабочей конфигурации Apache для авторизации через Active Directory: (нужно изменить путь к ldap на тот, что вы хотите использовать)
<IfDefine SVN> <Location /svn/repo> DAV svn SVNPath /var/svn/repo AuthType Basic Options Indexes FollowSymLinks AllowOverride None order allow,deny allow from all AuthName "Authorize Me" AuthLDAPURL ldap://domain.com:389/OU=IT,OU=MainOffice,OU=Locations,OU=Corporate,DC=domainname,DC=com?samAccountName?sub?(objectCategory=person) AuthLDAPBindDN "CN=webuser,OU=Resources,OU=Corporate,OU=AOM,DC=domain,DC=com" AuthLDAPBindPassword xxxxxxxxxxx Require valid-user </Location> </IfDefine>
Для того, чтобы разрешить доступ
только ограниченному списку пользователей:
<Location "/useraccess"> AuthName "user permissions" require user larry bill sam </Location>
Для того, чтобы разрешить доступ
только ограниченному списку групп:
<Location "/group"> AuthName "group permissions" require group cn=Group,cn=Users,dc=domainname,dc=com </Location>
В случае возникновения проблем с запросами к LDAP, запустите следующую команду на вашем Windows-сервере:
ldifde -f mydomain.ldif -s 127.0.0.1
Она сбросит все содержимое LDAP в указанный файл.
Если обычной авторизации недостаточно, можно расширить ее списками доступа. Имеется в виду что базовая аутентификация уже настроена и мы будем раздавать или запрещать доступ отдельным пользователям. Управлять списком можно через специальный файл, SVNAccessFile:
Файл: SVNAccessFile |
AuthzSVNAccessFile /var/svn/conf/svnpolicy |
Директива, указанная выше включает возможность создания списков доступа (ACL) для работы с репозиториями subversion через apache.
Правила авторизации для определенного репозитория задаются примерно так:
Файл: SVNAccessFile |
[test:/trunk] testuser1 = rw testuser2 = * = r |
Описанное выше правило разрешает производить пользователю testuser1 запись (commit, copy и т.д.) в репозиторий test (папка /trunk). Пользователь же testuser2 не имеет доступа к репозиторию. Остальные пользователи (маска *) имеют доступ только для чтения (могут производить checkout).
Для того, чтобы apache был в курсе наших опытов, нам нужно подредактировать /etc/conf.d/apache2:
Файл: /etc/conf.d/apache2 |
APACHE2_OPTS="... -D SVN_AUTHZ" |
И напоследок, несколько
замечаний по работе с правилами доступа:
будьте осторожны с пробелами - внутри
скобок не должно быть ни одного; при
использовании только одного репозитория,
его название можно не указывать,
достаточно указать только папку.
В последней ревизии репозитория можно полазать в любимом браузере. Удовольствия это много недоставит - выглядит все это дело не очень красиво. Чтобы это исправить, добавьте директиву
SVNIndexXSLT /svnindex.xsl
внутри тега <Location /svn> и укажите свой xsl-файл. Если же с xml вы знакомы недостаточно хорошо, попробуйте xsl и css -файлы, входящие в стандартный пакет subversion в папке /usr/share/doc/subversion-<версия_пакета>.
Некоторые браузеры (например, Opera), вместо нормального отображения XSL-файла, могут показывать пустую страницу. Чтобы этого избежать, можно пропустить XSL через xsltproc, чтобы он преобразовал это дело в обычный html. Для этого необходимо установить пакет xsltproc:
emerge libxslt
И добавить следующее в файл настроек apache:
BrowserMatch "Opera" xsltfilter ExtFilterDefine xslt mode=output enableenv=xsltfilter \ intype=text/xml outtype=text/html \ cmd="/usr/bin/xsltproc /var/www/svnindex.xsl -"
И добавить следующее внутрь тега <Location /svn>:
SetOutputFilter xslt AddDefaultCharset utf-8