Под катом описан пример конфигурации связки mercurial+nginx и приведен скрипт автоматизации всего вышеперечисленного.
Автоматизация вышеперечисленных действий.
Для исключения перехвата данных передача ведется по протоколу HTTPS.
Для минимизации потребляемых ресурсов в роли прокси выступает Nginx.
Разграничение доступа произведено на уровне директивы location.
https://hg.expample.com/reponame — ссылка для доступа к репозиторию
hg.example.com — доменное имя сервера хранилища репозиториев
reponame — название необходимого репозитория
/home/repos — корневая папка для репозиториев
/etc/hg — корневая папка для конфигурационных файлов
Читающий(ая) сие имеет минимальные навыки администрирования Linux
-d — запуск сервера как демона
-A /var/log/hg_access.log — лог доступа к серверу
-p 8080 — номер порта на котором сервер ожидает запросов
-a 127.0.0.1 — ip адрес на котором запускается сервер
--pid-file /var/run/hgserver.pid — файл с идентификатором процесса сервера
--encoding utf8 — кодировка
--webdir-conf /etc/hg/web.config — конфигурационный файл сервера
proxy_pass — указываем куда пересылать запросы при удачной авторизации
auth_basic — используем HTTP Basic Authentication
auth_basic_user_file — указываем в каком файле находится база паролей
access_log и error_log — директивы логирования доступа к репозиторию
Создаем файлы авторизации для каждого из репозиториев командой htpasswd
(программа htpasswd входит в пакет apache, так что придется установить его командой emerge apache)
-с — создать новый файл базы паролей
/etc/hg/nginx/repo1.pass — название файла базы паролей
test1 — логин добавляемого юзера
testpass1 — пароль добавляемого юзера
Осталось инициализировать репозитории командой hg init
доступны по адресу
https://hg.example.com/repo1 и https://hg.example.com/repo2 соответственно.
С настроенным разделением уровней доступа.
На этом можно было и закончить статью, ибо для простой конфигурации, которую обновляют раз в 3-5 месяцев этого достаточно. Но что делать когда конфигурацию приходится менять часто? Правильный системный администратор незамедлительно начнет искать способ облегчить себе жизнь.
2. Делегировать почетную обязанность своему подчиненному.
3. Создать систему управления самолично.
К сожалению мне ни первый, ни второй вариант не подходили, так что пришлось пересиливать свою лень и делать самому.
Итогом стал скрипт полностью автоматизирующий процесс управления сервером репозиториев.
2. Запрет доступа к неактивным репозиториям.(при удалении из конфигурационного файла репозиторий не удаляется физически).
3. Регенерация паролей пользователей для авторизации Nginx.
4. Распределение доступа к репозиториям на уровне пользователя.
2. использование символа “#” для выделения комментариев
телу императора репозиторию имеет права rw по умолчанию
2. Не реализовано использование групп для ограничения доступа
3. Не реализован откат конфигурации при некорректном синтаксисе конфига (система впадет в коллапс)
4. При увеличении количества пользователей и репозиториев конфиг обильно теряет в наглядности
Задачи:
Создание хранилища репозиториев на базе системы контроля версий Mercurial с возможностью безопасной передачи данных и разделением уровней доступа.Автоматизация вышеперечисленных действий.
Решение:
Проксирование встроенного http сервера (hg serve) с разделением доступа на уровне прокси.Для исключения перехвата данных передача ведется по протоколу HTTPS.
Для минимизации потребляемых ресурсов в роли прокси выступает Nginx.
Разграничение доступа произведено на уровне директивы location.
Соглашения:
Дистрибутив Linux в котором все будет происходить — Gentoohttps://hg.expample.com/reponame — ссылка для доступа к репозиторию
hg.example.com — доменное имя сервера хранилища репозиториев
reponame — название необходимого репозитория
/home/repos — корневая папка для репозиториев
/etc/hg — корневая папка для конфигурационных файлов
Читающий(ая) сие имеет минимальные навыки администрирования Linux
Установка необходимых пакетов:
hg ~ # emerge mercurial<br>hg ~ # emerge nginx
Встроенный http сервер будем запускать командойhg ~ # /usr/bin/hg serve -d -A /var/log/hg_access.log -p 8080 -a 127.0.0.1 --pid-file /var/run/hgserver.pid --encoding utf8 --webdir-conf /etc/hg/web.config
Директивы запуска:-d — запуск сервера как демона
-A /var/log/hg_access.log — лог доступа к серверу
-p 8080 — номер порта на котором сервер ожидает запросов
-a 127.0.0.1 — ip адрес на котором запускается сервер
--pid-file /var/run/hgserver.pid — файл с идентификатором процесса сервера
--encoding utf8 — кодировка
--webdir-conf /etc/hg/web.config — конфигурационный файл сервера
hg ~ # cat /etc/hg/web.config<br>[web] //секция параметров веб сервера<br>allow_push = * //разрешаем всем “поднимать” изменения (контроль доступа идет на уровне прокси)<br>push_ssl = false //не используем ssl (шифрование идет на уровне прокси)<br>[paths] //секция “путей”<br>rep1=/home/repos/rep1 //выставляем соответствие: название - расположение для репозитория rep1<br>rep2=/home/repos/rep2 //выставляем соответствие: название - расположение для репозитория rep2<br>
Прописываем директиву Include в основной конфигурационный файл Nginxhg ~ # cat /etc/nginx/nginx.conf |grep -i include<br> include "/etc/hg/nginx.conf";
Пример конфигурационного файла /etc/hg/nginx.confhg ~ # cat /etc/hg/nginx.conf <br>server <br> {<br> listen 443;<br> server_name hg.example.com;<br> client_max_body_size 128M;<br> ssl on;<br> ssl_certificate /etc/ssl/nginx/nginx.pem;<br> ssl_certificate_key /etc/ssl/nginx/nginx.key;<br>location /repo1<br> {<br> proxy_pass http://127.0.0.1:8080;<br> auth_basic "Restricted";<br> auth_basic_user_file /etc/hg/nginx/repo1.pass;<br> access_log /var/log/nginx/repo1.hg.example.com.ssl_access_log main;<br> error_log /var/log/nginx/repo1.hg.example.com.ssl_error_log info;<br> }<br>location /repo2<br> {<br> proxy_pass http://127.0.0.1:8080;<br> auth_basic "Restricted";<br> auth_basic_user_file /etc/hg/nginx/repo2.pass;<br> access_log /var/log/nginx/repo2.hg.example.com.ssl_access_log main;<br> error_log /var/log/nginx/repo2.hg.example.com.ssl_error_log info;<br> }<br>}<br>
Рассмотрим секцию: location /repo1proxy_pass — указываем куда пересылать запросы при удачной авторизации
auth_basic — используем HTTP Basic Authentication
auth_basic_user_file — указываем в каком файле находится база паролей
access_log и error_log — директивы логирования доступа к репозиторию
Создаем файлы авторизации для каждого из репозиториев командой htpasswd
(программа htpasswd входит в пакет apache, так что придется установить его командой emerge apache)
hg ~ # htpasswd -bc /etc/hg/nginx/repo2.pass test2 testpass2<br>hg ~ # htpasswd -bc /etc/hg/nginx/repo1.pass test1 testpass1
-b — использовать пароль указанный в командной строке-с — создать новый файл базы паролей
/etc/hg/nginx/repo1.pass — название файла базы паролей
test1 — логин добавляемого юзера
testpass1 — пароль добавляемого юзера
Осталось инициализировать репозитории командой hg init
hg ~ # hg init /home/repos/repo1<br>hg ~ # hg init /home/repos/repo2
Запускаем Nginx командой hg ~ # /etc/init.d/nginx start
Теперь репозитории repo1 и repo2доступны по адресу
https://hg.example.com/repo1 и https://hg.example.com/repo2 соответственно.
С настроенным разделением уровней доступа.
На этом можно было и закончить статью, ибо для простой конфигурации, которую обновляют раз в 3-5 месяцев этого достаточно. Но что делать когда конфигурацию приходится менять часто? Правильный системный администратор незамедлительно начнет искать способ облегчить себе жизнь.
Вариантов решения проблемы как минимум три:
1. Использовать готовый продукт управления репозиториями.2. Делегировать почетную обязанность своему подчиненному.
3. Создать систему управления самолично.
К сожалению мне ни первый, ни второй вариант не подходили
Итогом стал скрипт полностью автоматизирующий процесс управления сервером репозиториев.
В котором было реализовано:
1. Создание(если необходимо) и предоставление доступа к репозиториям.2. Запрет доступа к неактивным репозиториям.(при удалении из конфигурационного файла репозиторий не удаляется физически).
3. Регенерация паролей пользователей для авторизации Nginx.
4. Распределение доступа к репозиториям на уровне пользователя.
Синтаксис конфигурационного файла допускает:
1. использование пустых строк для визуального разделения секций2. использование символа “#” для выделения комментариев
Файл конфигурации состоит из трех секций.
[users] - секция описывающая пары: логин-пароль.разделителем служит занк “=”<br>user1=pass1<br>user2=pass2<br>user3=pass3<br>[repos] - секция описывающая доступные репозитории<br>repo1<br>repo2<br>repo3<br>[access] - секция описывающая права доступа к репозиториям, разделителем служит символ “,”<br>repo1 = user1 , user2,user3 - к репозиторию имеют доступ user1,user2,user3<br>repo2 = user1,user2 - к репозитроию имеют доступ только user1 и user2<br>repo3 = user3 - доступ к репозиторию только для пользователя user3<br>
Листинг скрипта /usr/local/sbin/hgmkrep.shТак же выкладываю линк на рабочий скрипт и пример конфига: hgmkrep.tar.gz
- #!/bin/bash
- tmphtpass="/var/tmp/htpass" #определяем временный файл базы паролей
- repohome="/home/repos/" #определяем корневую папку для репозиториев
- hgservepid="/var/run/hgserver.pid" #pid hg serve
- hgaccesslog="/var/log/hg_access.log" #access лог файл для hg server
- domain="exapmple.com" #tld имя сервера
- confdir="/etc/hg/" #определяем корневую папку для конфигов
- confile=${confdir}"repo.cfg" #основной конфиг файл /etc/hg/repo.cfg
- webconfig=${confdir}"web.config" #конфиг для hg server /etc/hg/web.config
- nginxconfig=${confdir}"nginx.conf" #конфиг для nginx /etc/hg/nginx.conf
- nginxauthdir=${confdir}"nginx/" #папка баз паролей для доступа к репозиториям
- [ -s ${confile} ] || echo "where is config file?" #проверяем наличие основного конфига
- [ -s ${confile} ] || exit 0 # огорчаемся, если нет основного конфига
- #парсим секцию [repos] на предмет репозиториев
- repos=`cat ${confile}|sed '/^$/d'|sed '/^#/d'|sed 's/\ //g'|awk '/\[repos\]/{
- is_repos=1;
- while (is_repos==1)
- {if (getline <= 0 || index($0,"[")==1)
- {is_repos=0;}
- else
- {print $0;}}}'`
- #Проверяем наличие папок с репозиториями и при необходимости создаем
- for i in ${repos}
- do;[ -d ${repohome}${i} ] || /usr/bin/hg init ${repohome}${i};done
- #генерируем конфиг для hg server
- echo "[web]
- allow_push = *
- push_ssl = false
- [paths]" > ${webconfig}
- #разрещаем доступ только к активным репозиториям
- for i in ${repos}
- do;echo ${i}=${repohome}${i} >> ${webconfig};done
- #перезагружаем hg serve
- [ -a ${hgservepid} ] && /bin/kill `/bin/cat ${hgservepid}` && rm ${hgservepid}
- /usr/bin/hg serve -d -A ${hgaccesslog} -p 8080 -a 127.0.0.1 --pid-file ${hgservepid} --encoding utf8 --webdir-conf ${webconfig}
- #создаем конфиг для nginx
- echo "server
- {
- listen 443;
- server_name hg."${domain}";
- client_max_body_size 128M;
- ssl on;
- ssl_certificate /etc/ssl/nginx/nginx.pem;
- ssl_certificate_key /etc/ssl/nginx/nginx.key;" > ${nginxconfig}
- #создаем lacation для активных репозиториев
- for i in ${repos}
- do
- echo "location /"${i}"
- {
- proxy_pass http://127.0.0.1:8080;
- auth_basic \"Restricted\";
- auth_basic_user_file "${nginxauthdir}${i}".pass;
- access_log /var/log/nginx/"${i}".hg."${domain}".ssl_access_log main;
- error_log /var/log/nginx/"${i}".hg."${domain}".ssl_error_log info;
- }" >> ${nginxconfig}
- done
- echo "}" >> ${nginxconfig}
- #создаем (обнуляем на всякий случай) временную базу паролей
- cat /dev/null > ${tmphtpass}
- #парсим секцию основного конфига [users]
- #генеририруем пароли для все активных пользователей
- cat ${confile}|sed '/^$/d'|sed '/^#/d'|sed 's/\ //g'|awk -v passfile=$tmphtpass '/\[users\]/{
- is_users=1;
- while (is_users==1)
- {if (getline <= 0 || index($0,"[")==1)
- {is_users=0;}
- else
- {split($0,userpass,"=");system("htpasswd -b "passfile" "userpass[1]" "userpass[2]);}}}'
- #парсим секцию [access] основного конфига
- #и получаем список привилегий вида repo=user1,user2
- access=`cat ${confile}|sed '/^$/d'|sed '/^#/d'|sed 's/\ //g'|awk '/\[access\]/{
- is_access=1;while (is_access==1)
- {if (getline <= 0 || index($0,"[")==1)
- {is_access=0;}
- else
- {print $0;}}}'`
- #проверяем есть ли папка для хранения баз паролей
- [ -d ${nginxauthdir} ] || mkdir -p ${nginxauthdir}
- #удаляем старые файлы баз паролей
- find ${nginxauthdir} -type f -name *.pass -delete
- #для каждого репозитория из секции [access] генерируем личную базу паролей
- for i in ${access}
- do;echo ${i}|sed 's/,/\|/g'|awk -v tmphtpass=${tmphtpass} -v nginxauthdir=${nginxauthdir} \
- 'BEGIN{FS="="}{system("cat "tmphtpass" |egrep \""$2"\" > "nginxauthdir""$1".pass")}'done
- #перезапускаем nginx
- /etc/init.d/nginx restart
- #удаляем временный файл базы паролей
- rm ${tmphtpass}
Существующие недостатки:
1. Отсутствие разграничения для чтения и записи, каждый пользователь допущенный к2. Не реализовано использование групп для ограничения доступа
3. Не реализован откат конфигурации при некорректном синтаксисе конфига (система впадет в коллапс)
4. При увеличении количества пользователей и репозиториев конфиг обильно теряет в наглядности