HOWTO Subversion сервер при помощи Apache2 и WebDav

Материал из Gentoo Linux Wiki

Перейти к: навигация, поиск
Вернуться в раздел руководства

Содержание

[править] О чем эта статья

Данное HOWTO является вольным переводом оригинальной английской статьи. Также в статью добавленно некоторое количество отсебятины по поводу и без (надеюсь автор оригинала не знает русского и не увидит как я испохабил его несчастную статью).

Данная статья посвещена настройке сервера Subversion под Apache с применением WebDav и только ей. Информацию по клиенту и настройке автономного сервера можно найти по ссылке en:HOWTO Subversion

Предупреждение: Данная статья предусматривает, что читатель - разумный человек и не будет вешать репозиторий не на ssl хост, и вообще заботится о безопасности.
FIXME: Хорошо бы описать в чем плюсы WebDav подхода и в чем минусы

[править] Настройка WebDav глобально, безотносительно в virtual-хостам

[править] Apache. Компиляция без Worker MPM

Существует известная проблема при больших коммитах (commit, оффициальный перевод - "фиксация изменений", на мой взгляд длинновато) связанная с использованием апачевого (от Apache) "worker" MPM. Рекомендуется просто отключить этот MPM и скомпилировать Apache с "prefork" MPM. Для этого просто добавьте новую (или поменяйте существующую, если таковая уже есть) строчку в package.use (в случае использования Gentoo, естественно):

Файл: /etc/make.conf
APACHE2_MPMS="prefork"

После чего перекомпилируйте Апач: emerge -aDNtuv apache

Более того, пожалуйста убедитесь, что subversion скомпилированна с (use flag) apache2 и без nowebdav юзами (от use flags).

[править] Включение SVN и WebDav модулей в Apache

Для использования 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"

[править] Создание репозиториев приметительно к данной конфигурации

Необходимо, чтобы Апач имел права на запись на папку репозитория(иев), с которым(и) он должен работать. Это можно сделать двумя способами:

  • Сменой пользователя/группы папки репозитория:
    1. Воспользуйтесь коммандой chown apache:apache /путь/к/репозиторию/ -R
  • Добавлением пользователя apache (или того, под которым ваш Апач бегает) в группу svnusers:
    1. Для начала надо таковую группу создать: groupadd svnusers
    2. Теперь надо добавить пользователя apache в новосозданную группу: usermod -G svnusers -a apache
    3. Ну а теперь надо поменять группу папки репозитория на новосозданную: chgrp svnusers /var/svn/repos/test -R
    4. Осталось всего ничего - сделать то, ради чего все это было нужно - дать доступ на запись группе 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 <имя последующего пользователя>


[править] Основанная на PAM

Если управление аж двумя различными файлами с паролями (системного и Апачевого) для вас слишком утомительно, то специально для вас был придуман модуль mod_auth_pam, который использует PAM для аутентификации пользователей. Если у вас нет еще этого модуля - emerge mod_auth_pam

Предупреждение: Да будет вам известно, что mod_auth_pam представляет из себя потенциальную уязвимость: системный пользователь 'apache' (или тот под которым запущен ваш сервер) получит доступ на чтение к /etc/shadow. Это означает, что в случае взлома Апача, злоумышленник получит доступ к файлу /etc/shadow, и сможет натравить на него программу по взлому паролей (дальнейшая судьба системы будет зависить от того, заметите ли вы взлом и примите меры раньше, чем злоумышленник получит пароль рута).

После сборки mod_auth_pam необходимо внести несколько изменений (суперпользователем) в ваши конфигурационные файлы. Для начала надо выдать пользователю 'apache' доступ на чтение /etc/shadow:

  1. groupadd shadow
  2. gpasswd -a apache shadow
  3. chgrp shadow /etc/shadow
  4. 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

[править] Active Directory/LDAP

Для того, чтобы настроить авторизацию в 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

[править] Полезные ссылки

Личные инструменты
На других языках