Это старая версия документа.


Сервер git



или рассказ о том, как сделать из Keenetic Giga git-сервер (dropbear+gitosis+gitlist+(lighttpd+php)), как настроить клиент под Windows, и прочее, прочее…


Введение

1) Эксперименты проводились на сервере с уже установленным lighttpd + php (fastcgi) + apc.

2) Клиентская машина - под Windows XP, поэтому примеры соответствующие. Для linux все значительно проще.

3) Использовался HDD под NTFS, серьезных проблем с правами не возникало. Если HDD размечен под ext - в каких-то случаях я мог забыть про необходимость установки прав доступа.

4) При выполнении инструкций обозначения «myserver.ru «и «port» заменяем на свои.

5) На кинетике один пользователь - «root» (не считая «nobody»). Это усложняет задачу.

6) Поскольку нет полноценного ssh, а только dropbear, для создания нескольких пользователей git придется применять разнообразные трюки.


Работаем по SSH с сервером

1) Если не поставили web-сервер на lighttpd и php - ставим (ищем инструкции на этом интернет-ресурсе). Затем ставим git, python, для php нужен php5-mod-ctype

opkg install git
opkg install python
opkg install php5-mod-ctype

Зачем нам еще и web-сервер с php ? Для того, чтобы добавить web-интерфейс к git, облегчив доступ к репозиторию на чтение.

2) Создаем папку для хранения скриптов gitosis и переходим в нее, выполняем

cd /media/DISK_A1/system
mkdir src
cd src

3) Возьмем setuptools для python по ссылке https://pypi.python.org/pypi/setuptools#downloads

Нужен файл setuptools-0.6c11-py2.7.egg, положим его в каталог src, запустим на выполнение.

4) Получим исходные коды последней версии gitosis из официального хранилища проекта (оставаясь в каталоге src), перейдём в папку с ними и установим.

git clone git://github.com/tv42/gitosis.git
cd gitosis
python setup.py install

Зачем нужен gitosis ? Он: - позволяет делать полноценный многопользовательский доступ, - не требует висящего демона и просто настраивается, - на сервере только один пользователь, - упрощается администрирование git-сервера с клиентской машины (достаточно внести изменения в административном репозитории, выполнить commit + push, после чего все изменения оказываются на сервере).

5) Удалим ненужные файлы и вернемся в домашний каталог

rm -rf /media/DISK_A1/system/src
cd ~

Переходим на клиентскую машину

1) Нам понадобится PuTTY, поскольку нужны PAgeant и PLink. Качаем http://the.earth.li/~sgtatham/putty/latest/x86/putty-0.62-installer.exe

Запускаем инсталляцию, путь - «C:\PuTTY» (иначе могут быть проблемы), ставим «птичку» на пункте «Associate .PPK files…»

2) Установим git и создадим ключи авторизации (или возьмем имеющиеся; для генерации ключей под Windows PuttyGen не годится).

Качаем с http://code.google.com/p/msysgit/downloads/list инсталляционный файл MSysGit: Git-1.8.1.2-preview20130201.exe, устанавливаем в «C:\Git» (иначе будут проблемы).

При инсталляции выбираем «Windows Explorer Integration→Simple Comtext Menu». Затем «Run from the Windows command prompt».

3) Глупые инсталляторы не добавляют пути. Проверяем наличие и добавляем:

C:\Git\cmd (этот наверняка будет)
C:\Git\bin
C:\PuTTY

Проверяем и добавляем переменную окружения

GIT_SSH=C:\PuTTY\plink.exe

Если работали, например, из Far, не забываем его перезапустить.

4) Выполняем генерацию ключей. Переходим в каталог C:\Git\bin, запускаем

ssh-keygen -t dsa -C root

В команде используем тип dsa, поскольку нужна только идентификация пользователей, шифрование не нужно. Отвечаем на вопрос об имени файла, на остальное давим Enter. Создаются два файла (root.pub и root - публичный и приватный ключи соответственно). Эта пара будет использоваться только для root и автоматического доступа по ssh к серверу.

Создаем (аналогичным способом) еще пары ключей: - gitadmin (для администратора git) - gituser1 (первый пользователь) - gituser2 (второй пользователь) и т.д. Разумеется, для gitadmin и gituser* можно дать иные имена, но так нам будет в дальнейшем проще.

Теперь надо преобразовать приватные ключи в формат, который понимает PAgeant: - запускаем PuTTYGen, - нажимаем «Load», - выбираем «All Files», - разыскиваем и загружаем файл приватного ключа (root, gitadmin, gituser1, gituser2 …), - в комментарии пишем то же, что указывали для ssh-keygen в ключе »-C», - ставим «птичку» на «SSH-2 DSA» - passphrase игнорируем - нажимаем «Save Private Key» - задаем то же самое имя файла, что загружали, с расширением ».ppk» Все файлы сохраняем на локальном компьютере в надежном месте.

Публичные ключи root.pub, gitafmin.pub, gituser1.pub, gituser2.pub копируем на сервер в /media/DISK_A1/system/root (они нам сейчас понадобятся).

5) В каталоге (на клиенте), где лежат ключи, выполняем команду

pageant root.ppk

Теперь у нас работает агент идентификации, в трее виден значок, можем добавлять ключи и прочее. PAgeant можно запускать при старте Windows с указанием ключа в качестве параметра.

6) С сервером надо соединиться первый раз - чтобы PLink его «запомнил» (такая вот «фича»).

plink -P port root

Соглашаемся сохранить ключ в кэше (если спросит), вводим пароль root и после того, как видим приглашение ash, выполняем «exit».


Идем на сервер

1) Инициализируем административный репозиторий, а также ставим публичный ключ gitadmin.pub (обратите внимание - вовсе не root.pub), для чего выполняем

cd ~
gitosis-init < gitadmin.pub

В результате в /media/DISK_A1/system/root должны образоваться подкаталоги gitosis, repositories, repositories/gitosis-admin.git и др.

2) Вносим исправления в /media/DISK_A1/system/root/repositories/gitosis-admin.git/hooks/post-update Из-за ограничений на environment в dropbear добавляем пути в PATH после команды «set -e»:

PATH=$PATH:/media/DISK_A1/system/bin:/media/DISK_A1/system/usr/bin:/media/DISK_A1/system/usr/libexec/git-core

Также надо задать правильные права (из-за особенностей python; для NTFS не обязательно)

chmod 755 /media/DISK_A1/system/root/repositories/gitosis-admin.git/hooks/post-update

3) Поставим gitlist, чтобы можно было работать с репозиторием через web-интерфейс (а конкретно - получать файлы проектов). Скачаем с gitlist.org (я качал версию 0.3 по ссылке https://s3.amazonaws.com/gitlist/gitlist-0.3.tar.gz). Установим в www/gitlist (абсолютный путь у меня /media/DISK_A1/system/www/gitlist) и изменим config.ini под свои пути:

client = '/media/DISK_A1/system/usr/bin/git' ; Your git executable path
repositories = '/media/DISK_A1/system/root/repositories/' ; Path to your repositories

4) Добавим в конфигурацию /lighttpd.conf строки

url.rewrite-once = (
    "^/gitlist/web/.+" => "$0",
    "^/gitlist/favicon\.ico$" => "$0",
    "^/gitlist(/[^\?]*)(\?.*)?" => "/gitlist/index.php$1$2"
)

5) Создадим хранилища c именами «project1», «project2». Перейдем в /root/repositories. Создадим каталог project1.git, перейдем в него и выполним команду создания пустого репозитория

cd ~/repositories
mkdir project1.git
cd project1.git
git --bare init

Затем выполним то же самое для project2.git.

Лично я рекомендую создавать новые репозитории на сервере именно так.

6) Добавим пользователей для dropbear.

gitosis-admin считает, что ключи хранятся в ~/.ssh/authorized_keys, но dropbear хранит ключи в /etc/dropbear/authorized_keys (здесь и далее перед /etc, /root и т.п. в тексте не буду приводить полные абсолютные пути). Поэтому те ключи, которые будет добавлять gitosis-admin, придется вручную добавлять в /etc/dropbear/authorized_keys (автоматизировать эту процедуру будем позже).

Начнем с ключа root.pub. Если нет файла /etc/dropbear/authorized_keys - создаем. Добавляем в одну строку содержимое ключа root.pub (перевод строки после ключа обязателен), содержимое файла будет примерно такое

ssh-dss <значение ключа> root

Потом добавляем gitadmin.pub, gituser1.pub, gituser2.pub и вносим необходимые исправления для gitosis:

command="/media/DISK_A1/system/etc/dropbear/dropbear-gitosis gitadmin" ssh-dss <значение ключа> gitadmin
command="/media/DISK_A1/system/etc/dropbear/dropbear-gitosis gituser1" ssh-dss <значение ключа> gituser1
command="/media/DISK_A1/system/etc/dropbear/dropbear-gitosis gituser2" ssh-dss <значение ключа> gituser2

Теперь создадим файл «dropbear-gitosis» со следующим содержимым

#!/bin/sh
 
MOUNT="/media/DISK_A1/system"
PATH=$PATH:$MOUNT/bin:$MOUNT/sbin:$MOUNT/usr/bin:$MOUNT/usr/sbin:$MOUNT/usr/libexec/git-core
 
gitosis-serve $1 $2 $3 $4 $5

и дадим ему права на выполнение (для NTFS не требуется)

Если диск размечен в ext - убеждаемся, что права на /etc/dropbear и файл authorized_keys - 600. Если нет - ставим

chmod 600 /media/DISK_A1/system/etc/dropbear
chmod 600 /media/DISK_A1/system/etc/dropbear/authorized_keys

7) Поиграем с правами нужных dropbear каталогов и файлов. Это необходимо для NTFS, а также для дальнейшей автоматизации работы связки dropbear и gitosis, поэтому делаем в любом случае.

Завершим работу dropbear

/media/DISK_A1/system/etc/init.d/S10dropbear stop

иначе есть риск потерять изменения в файле !

Дальнейшие изменения делаем по ftp с клиента.


Перейдем на клиентскую машину

1) Продолжение игр с правами и подготовка к автоматизации работы связки dropbear-gitosis.

dropbear требует права 600 для /etc/dropbear и authorized_keys в нем… Поскольку для NTFS права на отдельные каталоги и файлы выставить невозможно, применим трюк.

Сначала переименуем /etc/dropbear в /etc/dropbear.init

Затем внесем изменения в /etc/init.d/S10dropbear, добавив после

start() {

следующие команды

cp -r -f $MOUNT/etc/dropbear.init /tmp/dropbear
chmod 600 /tmp/dropbear
chmod 600 /tmp/dropbear/authorized_keys
ln -s /tmp/dropbear $MOUNT/etc/dropbear

и после

stop() {

добавим

rm $MOUNT/etc/dropbear
rm -r /tmp/dropbear

после чего сохраним файл и перезапустим роутер. Ждем, пока произойдет загрузка.

2) Проверим работу с сервером по ssh. Проверим, запущен ли PAgeant и с каким ключом (должен быть только root.ppk). Выполним

ssh -p port root@myserver.ru "echo $PATH"

Это желательно выполнить при первом совединении с сервером, ответив ответить на вопросы. Такая «фича» ssh - он должен «запомнить» сервер.

3) Убедимся, что можем попасть на сервер через ssh, используя PuTTY. Запускаем PuTTY, настраиваем:

- Host Name (or IP address) - myserver.ru или IP - Port - порт - Window→Translation→Remote character set - UTF-8 - в окошке «Saved Sessions» задаем имя нашей сессии сохраняем ее - нажимаем «Open»

Если все правильно сделали - должны войти только по логину root, без необходимости ввода пароля. Если это не так - возможно, в S10dropbear потребуется добавить ключик запуска dropbear »-g» (информацию ищите на этом ресурсе). Если все нормально - закрываем сессию.

Теперь в PAgeant удаляем ключ root.ppk, добавляем gitadmin.ppk. Снова запускаем PuTTY и открываем сессию (уже от gitadmin).

Если все правильно сделали - войти не сможем. Увидим сообщение об ошибке и окно сессии закроется.

4) Выполним команды глобальных настроек git (вместо «My Name» и «myemail@mailserver.ru» подставьте свое):

git config --global user.name "My Name"
git config --global user.email "myemail@mailserver.ru"

В том числе определим режим операций, выполнив команду

git config --global push.default simple

5) Клонируем на клиента gitosis-admin.git

Создадим каталог, где будут располагаться репозитории (в том числе административный gitosis-admin), перейдем в него и выполним команду

git clone ssh://root@myserver.ru:port/gitosis-admin.git

Обратите внимание: пользователь указан root, а ключ (загружен в PAgeant) используется от gitadmin.

Если при выполнении команды у Вас спросят запросит пароль root, значит, что-то не так сделано с ключами, PLink, PAgeant, ssh, dropbear или неизвестно с чем)) Все перепроверяем.

После клонирования, перейдя в каталог административного репозитория gitosis-admin, обнаружим там файл gitosis.conf, подкаталог keydir с файлом ключей, и скрытый подкаталог .git

6) Вносим изменения в конфигурацию, см. файл gitosis.conf

[gitosis]
loglevel = DEBUG

[group gitosis-admin]
...

Добавляем пользователей (дописываем в конце файла), например таких:

[group users1]
members = gitadmin gituser1
writable = project1

[group users2]
members = gitadmin gituser1 gituser2
writable = project2

То есть создаем две группы пользователей. Над проектом project1 работают gitadmin и gituser1, а над project2 - gitadmin, gituser1 и gituser2.

В строке members указывается какие пользователи будут иметь доступ к хранилищу (project1, project2) на чтение (readonly) и запись (writable). Название группы (users) нигде не используется, так что может быть абсолютно любым (но уникальным в этом файле).

Теперь ключи gituser1.pub, gituser2.pub переписываем в подкаталог keydir административного проекта (там уже есть gitadmin.pub - он взят с сервера).

Переходим в gitosis-admin и сообщаем git о добавлении файлов

git add .

Если увидите сообщение «fatal: LF would be replaced by CRLF in <file>», то это из-за автоматического проеобразования. Его можно отключить (и заодно Symlinks) в глобальных настройках

git config --global core.autocrlf false
git config --global core.symlinks false

Применяем изменения

git commit -a -m "Allow gitadmin write access to test"
git push

Пути, порт и др. указывать не надо, git всё запомнил.

Если на сервере взглянем на содержимое файла /root/.ssh/authorized_keys, то обнаружим публичные ключи новых пользователей. gitosis.conf тоже изменится.

7) Создадим на клиентской машине репозиторий project1 - в том же каталоге, где располагается gitosis-admin, то есть создадим каталог project1 на том же уровне.

Инициализируем новый репозиторий

git init

В каталоге project1, создадим какой-то файлик командами

echo start project1 > readme
git add .

И затем

git commit -a -m "start test project1"
git push --set-upstream ssh://root@myserver.ru:port/project1.git master

Затем внесем любые изменения в readme project1, выполним

git commit -a -m "start test 2 project1"
git push

Обращаю внимание - git все запомнил, никаких лишних опций теперь использовать не надо.

Повторим операции для project2.

8) Проверка и настройка gitlist

Проверям работоспособность gitlist, набрав в браузере url

http://myserver.ru/gitlist/

или (на случай, если не проводили настройки lighttpd или ошиблись в них)

http://myserver.ru/gitlist/index.php

Если все правильно сделали, попадем на стартовую страничку gitlist с проектом gitosis-admin.git, project1.git и project2.git.

Посмотрев Commits для gitosis-admin.git, project1.git и project2.git, увидим, что делали.

Однако, мы доступились через web-интерфейс к gitosis-admin.git, но зачем нам открывать административный репозиторий ?

Закроем, добавив в config.ini (по ftp или перейдя на сервер) после комментария

; You can hide repositories from GitList, just copy this for each repository you want to hide

строку

hidden[] = '/media/DISK_A1/system/root/repositories/gitosis-admin.git'

После этого административный репозиторий будет скрыт в gitlist.


Перейдем на сервер

1) Теперь настала пора автоматизировать работу связки dropbear-gitosis.

Сначала удалим из файла /etc/dropbear.init/authorized_keys все ключи, не имеющие отношения к root. Если Вы не отступали от инструкций, в файле должна остаться только одна первая строчка.

Теперь заменяем содержимое файла /etc/dropbear/dropbear-gitosis на нижеприведенное

#!/bin/sh
 
MOUNT="/media/DISK_A1/system"
PATH=$PATH:$MOUNT/bin:$MOUNT/sbin:$MOUNT/usr/bin:$MOUNT/usr/sbin:$MOUNT/usr/libexec/git-core
 
if [ $# -ne 0 ]
then
    gitosis-serve $1 $2 $3 $4 $5
fi
 
KEYSFILE="authorized_keys"
KEYSDBINIT=$MOUNT/etc/dropbear.init/$KEYSFILE
KEYSGITINIT=$MOUNT"/root/.ssh/"$KEYSFILE
KEYSDB=/tmp/dropbear/$KEYSFILE
KEYSDBTMP=$(mktemp)
 
echo '### autogenerated by dropbear-gitosis, DO NOT EDIT' > $KEYSDBTMP
 
cat $KEYSDBINIT >> $KEYSDBTMP
 
echo '### strings below regenerated from autogenerated gitosis authorized_key file' >> $KEYSDBTMP
 
cat $KEYSGITINIT >> $KEYSDBTMP
sed -i 's/gitosis-serve/\/tmp\/dropbear\/dropbear-gitosis/g' $KEYSDBTMP
sed -i 's/,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty//g' $KEYSDBTMP
 
mv $KEYSDBTMP $KEYSDB
chmod 600 $KEYSDB

2) Теперь снова надо внести изменения в /etc/init.d/S10dropbear, для этого завершим работу dropbear

/media/DISK_A1/system/etc/init.d/S10dropbear stop

Перейдем на клиентскую машину

1) Итак, окончательные изменения в /etc/init.d/S10dropbear вносим по ftp, добавив после команды (которую ранее добавляли)

ln -s /tmp/dropbear $MOUNT/etc/dropbear

еще одну команду

$MOUNT/etc/dropbear.init/dropbear-gitosis

Сохраним файл и перезапустим роутер. Ждем, пока произойдет загрузка. Проверяем все с «чистого листа» ))

Если все работает - см. ниже:


Известные проблемы и их решение

1) Попытка создания проектов с большими файлами или с большим количеством файлов вызывает сетевую ошибку

FATAL ERROR: Network error: Software caused connection abort
fatal: The remote hang up unexpectedly
fatal: recursion detected in die handler

При этом в журнале есть записи такого вида

6 апр 13:01:44	dropbear[24035]	Exit (root): Received data after eof

Пока причины не выяснены. Вероятно, это проблемы OpenWRT или недостатка ресурсов.

Попробуйте добавлять файлы по одному, и большие тексты программ (от 50К или числом строк от 1000) разбейте на модули небольшого размера.


Выводы

1) На кинетике создан (почти) полноценный многопользовательский git-сервер с возможностью удаленного администрирования (gitosis), а также web-интерфейсом для чтения проектов (gitlist).

2) Под логином root возможность работы с git-сервером отключена, но git (и gitosis) на сервере работают из-под root.

3) Проблемы безопасности (возможность работы пользователей git-сервера под root) решены при организации работы связки dropbear-gitosis.

Успешных коммитов !