Rambler's Top100
ГлавнаяО себеФоткиРазбиралкиМарафон
Карта

Делаем CVS'у chroot!

(Настройка CVS-сервера.)

Вольный перевод:
Олег Токарев (
otokarev@ngs.ru)
август 2003

Отмазка: Эта статья основана на материалах, изложенных в "Chrooted SSH CVS server HOW-TO - DRAFT version", и является всего лишь ее вольным переводом. Автор ставил и настраивал все ниже описанное на персональном компьютере под управлением операционной системы Red Hat Linux 9 и вообще-то не гарантирует, что, даже если Вы проделаете все точно также, у Вас что-то заработает.

  1. Идея.
  2. Создание учетных записей (accounts).
  3. Создание дерева директорий.
  4. Установка програмного обеспечения (компиляция cvs, smrsh, run-cvs, и их установка).
  5. Перенос и настройка репозитория.
  6. Сетевая безопасность, доступ клиентов к репозиторию.
  7. Возможные неполадки.

Идея

Необходимо настроить работу CVS-сервера, который бы обеспечивал:

  • Доступ многих удаленных пользователей к одному репозиторию
  • Эффективное разделение доступа пользователей к модулям репозитория
  • Защиту данных пересылаемых от/к репозиторию
  • Защиту конфигурационных файлов CVS от неавторизованных пользователей
  • Защиту данных компьютера не имеющих отношение к CVS-репозиторию

Идея для решения подобной задачи была целиком почерпнута из работы "Chrooted SSH CVS server HOW-TO - DRAFT version", которая имеет в качестве своей основы статью "Chrooted tunnelled read-write CVS server", и, если коротко, заключается в следующем:

  1. Каждому пользователю и группе репозитория выделяется учетная запись в файлах /etc/passwd и /etc/group.
  2. В качестве командного интерпретатора для пользователей репозитория используется smrsh - командный интерпретатор sendmail'а, который ограничивает круг исполняемых команд только теми, что находятся в специальной директории, указываемой пр компиляции.
  3. Единственной доступной для пользователя к исполнению командой является одноименная "обертка" для cvs с установленным битом SUID, которая при запуске меняет корневую директорию на директорию для данного репозитория и в новом окружении (chroot-окружение) запускает команду cvs с передачей ей параметров. Таким образом, в директории, куда производится перенос корневого каталога, должна существовать директория bin/ со всеми необходимыми исполняемыми файлами и директория etc/ со всеми файлами необходимыми для авторизации доступа к репозиторию (passwd и group). Причем, все исполняемые файлы должны быть получены путем статической компиляции, поскольку в новом окружении все динамически подгружаемые библиотеки станут недоступными.
  4. Собственно, устанавливается сам репозиторий.
  5. Сетевая безопасность обеспечивается путем запрета для всех удаленных клиентов доступа к машине-серверу посредством отличного от SSH протокола (firewall, отсутствие поддержки других протоколов).

К дополнительным бонусам метода можно отнести его автоматическую расширяемость на несколько chrooted-репозиториев. Для этого необходимо проделать необходимое количество раз все манипуляции описанные ниже для каждого проекта, который мы хотим поместить в отдельное chrooted-окружение.

К очевидным минусам данного подхода можно отнести:

  • "Засорение" системных файлов /etc/passwd и /etc/group записями пользователей и групп репозиториев.
  • Для работы с несколькими репозиториями на одном хосте необходимо иметь для каждого из них по отдельному неперекрывающемуся набору групп и пользователей.

[Up] [Top]

Создание учетных записей (accounts)

Для работы с репозиторием используются следующие группы:

  • Группа администраторов cvs-admin, пользователи которой имеют возможность изменять конфигурационные файлы CVS-сервера.
  • Группа cvs-devel, пользователи которой имеют право записи в cvs-locks и history. "Обычные" пользователи, которым необходим доступ к файлам репозитория (не защищенным иным образом) хотя бы на чтение, должны быть членами этой группы.
  • Остальные группы создаются по мере необходимости, чтобы ограничить доступ к определенным модулям репозитория. Пользователи этих групп также являются членами cvs-devel.

Добавим записи для групп cvs-admin и cvs-devel и пользователя cvs-admin в /etc/passwd и /etc/group. в passwd:
cvs-admin:x:1000:1000:CVS <poject name> Admin:<base>/home/cvs-admin:<base>/<project>/bin/smrsh
Замечание:Смысл используемых здесь абсолютных путей станет понятен чуть позже.
в group:
cvs-admin:x:1000:
cvs-devel:x:1001:

И домашние директории для них (они необходимы для SSH):
% mkdir -p <base>/home/cvs-devel
% mkdir -p <base>/home/cvs-admin
% chown cvs-devel.cvs-devel <base>/home/cvs-devel
% chown cvs-admin.cvs-admin <base>/home/cvs-admin

Скопируем только что созданные учетные записи из системных passwd и group в соответствующие файлы директории <base>/<project>/chrooted-cvs/etc/. Заменив домашние директории на /tmp. Вот, что получится в passwd:
cvs-admin:x:1000:1000:CVS <poject name> Admin:/tmp:<base>/<project>/bin/smrsh
cvs-devel:x:1001:1001:CVS <poject name> User :/tmp:<base>/<project>/bin/smrsh

Чтобы создать произвольного пользователя репозитория, к примеру foo, поступаем аналогичным путем, не забывая добавить его в группу cvs-devel:


cvs-devel:x:1001:foo
в соответствующих файлах group.

[Up] [Top]

Создаем дерево директорий

Пусть у нас есть два пользователя репозиторием: dev1 и dev2, и парочка проектов: proj1 и proj2, тогда согласно идеи предложенной в "Chrooted SSH CVS server HOW-TO - DRAFT version" надо получить что-то вроде:

.../home/dev1/                                домашняя директория разработчика 1
.../home/dev2/                                домашняя директория разработчика 2
.../proj1/                                    домашняя директория проекта 1 
.../proj1/bin/                                директория для бинарников
.../proj1/smrsh                               специальный командный интерпретатор
.../proj1/smrsh.bin/                          директория для разрешенных команд
.../proj1/smrsh.bin/cvs                       обертка для CVS
.../proj1/chrooted-cvs/                       корневой каталог для подсистемы проекта 1
.../proj1/chrooted-cvs/bin/                   допустимые к исполнению команды: только cvs
.../proj1/chrooted-cvs/bin/cvs                статически скомпилированный cvs
.../proj1/chrooted-cvs/dev/                   
.../proj1/chrooted-cvs/dev/null               необходимо для нормального функционирования
.../proj1/chrooted-cvs/etc/
.../proj1/chrooted-cvs/etc/passwd             часть passwd-файла с юзерами для cvs
.../proj1/chrooted-cvs/etc/group              часть group-файла с группами для cvs
.../proj1/chrooted-cvs/cvs/proj1              базовая директория для проекта 1
.../proj1/chrooted-cvs/cvs/proj1/CVSROOT/     настройки CVS проекта 1
.../proj1/chrooted-cvs/cvs/proj1/module1/     модуль 1 для проекта 1
.../proj1/chrooted-cvs/cvs/proj1/module2/     модуль 2 для проекта 1
.../proj1/chrooted-cvs/cvs-locks/             директория для lock-файлов репозитория
.../proj1/chrooted-cvs/tmp/                   директория для временных файлов

.../proj2/                                    домашняя директория проекта 2

...                                           ну и так далее


Это можно сделать, например, с помощью ниже указанного скрипта:
#!/bin/bash
BASE=<base>
PROJECT=<project>
ADMIN=cvs-adm

# create the place where regular home-directories
# of standard CVS users will be (this step will be needed the first time
# only, as all home dirs are in the same place)
mkdir -p ${BASE}/home
chown 0.0 ${BASE}/home
# create the chroot environment for ${PROJECT}
mkdir -p ${BASE}/${PROJECT}/{bin,chrooted-cvs,smrsh.bin}
mkdir -p ${BASE}/${PROJECT}/chrooted-cvs/{bin,cvs,cvs-locks,dev,etc,tmp}
chown 0.0 ${BASE}/${PROJECT}/chrooted-cvs/{bin,dev,etc,home,tmp}
chmod 1777 ${BASE}/${PROJECT}/chrooted-cvs/tmp
# the cvs administrator owns the CVS root
chown ${ADMIN}.${ADMIN} ${BASE}/${PROJECT}/chrooted-cvs/cvs
chmod 770 ${BASE}/${PROJECT}/chrooted-cvs/cvs
chown 0.0 ${BASE}/${PROJECT}/chrooted-cvs/cvs-locks
chmod 666 ${BASE}/${PROJECT}/chrooted-cvs/cvs-locks
# create the /dev/null device under the chroot space
mknod ${BASE}/${PROJECT}/chrooted-cvs/dev/null c 1 3
chown 0.0 ${BASE}/${PROJECT}/chrooted-cvs/dev/null
chmod 666 ${BASE}/${PROJECT}/chrooted-cvs/dev/null

где <base> - директория, в которой будет содержаться описанная выше структура, а <project> - имя директории для отдельного проекта.

[Up] [Top]

Установка програмного обеспечения

Компиляция CVS

Закачиваем исходники CVS c www.cvshome.org.
% tar xjf cvs-1.11.6.tar.bz2
% cd cvs-1.11.6
% ./configure --disable-client
% make

Далее, чтобы получить статическую версию CVS, найдем, в том что выдал нам на терминал make, самый последний вызов компилятора: "gcc -g -O2 -o cvs add.o admin.o anno(...чего-то там еще)". Добавим в эту команду ключик "-static" и исполним заново:
% cd src
% gcc -g -O2 -static -o cvs add.o admin.o anno(...чего-то там еще)

Теперь у нас в текущей директории лежит статическая версия CVS.

Компиляция smrsh

Теперь, что касается smrsh. Его исходники можно скачать с www.sendmail.org в составе пакета sendmail. Далее некие магические действия (такие какими они были в моем случае):
% tar xzf sendmail.8.12.9.tar.gz
% cd sendmail-8.12.9/smrsh
% ./Build

Наблюдаем процесс компиляции каких-то полезных библиотек и нужного нам приложения smrsh. Смотрим в то, что вывелось в терминал, по его завершению и определяем: где собирался smrsh, и при помощи какой команды. Вот, что выяснил я:
<skipped>
Making in ><skipped>sendmail-8.12.9/obj.Linux.2.4.20-8.i686/smrsh
<skipped>
cc -o smrsh smrsh.o <skipped>sendmail-8.12.9/obj.Linux.2.4.20-8.i686/libsm/libsm.a -ldb -lresolv -lcrypt -lnsl -ldl
<skipped>

Далее:
% cd <skipped>sendmail-8.12.9/obj.Linux.2.4.20-8.i686/smrsh
% cc -o -static smrsh smrsh.o <skipped>sendmail-8.12.9/obj.Linux.2.4.20-8.i686/libsm/libsm.a -ldb -lresolv -lcrypt -lnsl -ldl
Получили таким образом статическую версию smrsh. Замечание:На самом деле статическая версия smrsh нам не нужна, поскольку утилита запускается в нормальном окружении. Но мне нравится независимость от внешних библиотек.

Вспомним теперь, что smrsh может запускать команды только из определенной директории, которая указывается при компиляции. Эту директорию можно указать, вставив "#define CMDDIR <путь>" в исходник "smrsh.c", либо скормив Build'у длинную строку соответствующих параметров для последующего скармливания ее make'у:
% ./Build CPPFLAGS+=-DCMDDIR=\"\\\"\\\\\\\"<base>/<project>/smrsh.bin\\\\\\\"\\\"\"
Повторим теперь всю, описанную выше, цепь действий начиная с запуска Build'а с указанием ему пути. (Главное не запутаться в слэшах :-) )

Компиляция strace

В процессе отладки нашего CVS-сервер'а нам может понадобится дополнительная информация, которую иначе как через strace не получишь. Попытка сходу статически скомпилировать утилиту из исходников полученных с sourceforge.net у меня не увенчалась успехом. С целью сэкономить время на хакинге предлагаю взять исходники из дистрибутива RedHat'а. И скомпилировать их с ключиком -static:
Распаковываем исходники (как правило, находятся в директории SRPMS дистрибутива):
% rpm -Uhv <path to>/strace-<revision>.src.rpm
Находим установленные исходники здесь: /usr/src/redhat/SOURCES/strace-<revision>.tar.bz2. Распаковываем. Процесс статической компиляции выполняется по аналогии с компиляцией cvs и smrsh.

Компиляция run-cvs

Осталось откомпилировать утилиту для запуска cvs в chroot-окружении c указанием в какую директорию делать chroot. Исходник можно взять отсюда: "Chrooted SSH CVS server HOW-TO - DRAFT version". Подправленный под использование strace исходник лежит тут.
% gcc -O2 -DBASE=\"<base>/<project>/chrooted-cvs\" run-cvs-idx.c -o run-cvs

Установка исполняемых файлов

Теперь поместим получившиеся бинарники туда, где им необходимо быть.
% cp <путь к>/strace <base>/<project>/chrooted-cvs/bin/
% cp <путь к>/smrsh <base>/<project>/bin/
% chown 0:0 <base>/<project>/bin/smrsh
% cp <путь к>run-cvs <base>/<project>/smrsh.bin/cvs
% chown 0:0 <base>/<project>/smrsh.bin/cvs
% chmod 4755 <base>/<project>/smrsh.bin/cvs
% cp <путь к>/cvs <base>/chrooted-cvs/bin/

[Up] [Top]

Перенос и настройка репозитория.

В моем случае требовалось перенести существующий репозиторий. Репозиторий "с нуля" создается стандартным образом, и этот процесс здесь не описан. Замечание:Однако, стоит учесть, что если мы создаем с помощью cvs init новый репозиторий, он не будет содержать CVSROOT/val-tags, этот файл необходимо будет создать вручную с помощью команды touch.
% cp -a <путь к старому репозиторию>/* <base>/<project>/chrooted-cvs/cvs
% chowh -R cvs-adm.cvs-adm <base>/<project>/chrooted-cvs/cvs
% chgrp cvs-devel <base>/<project>/chrooted-cvs/cvs/CVSROOT/{history,val-tags}
% chmod 775 <base>/<project>/chrooted-cvs/cvs <base>/<project>/chrooted-cvs/cvs/CVSROOT
% chmod 444 <base>/<project>/chrooted-cvs/cvs/CVSROOT/*
% chmod 775 <base>/<project>/chrooted-cvs/cvs/CVSROOT/Emptydir
% chmod 664 <base>/<project>/chrooted-cvs/cvs/CVSROOT/{history,val-tags}
% chown -R cvs-adm.cvs-devel <base>/<project>/chrooted-cvs/cvs-locks
% chmod -R 770 <base>/<project>/chrooted-cvs/cvs-locks

Поправим в конфигурациях пути к лок-файлам:
% su - cvs-admin
% <base>/<project>/chrooted-cvs/bin/cvs -d <base>/<project>/chrooted-cvs/cvs co CVSROOT
% cd CVSROOT

Дабавляем в файл config строчку LockDir=/cvs-locks. Сохраняем наши изменения в репозитории:
% <base>/<project>/chrooted-cvs/bin/cvs -d <base>/<project>/chrooted-cvs/cvs ci config
Теперь наш репозиторий будет доступен только в окружении chroot.

[Up] [Top]

Сетевая безопасность, доступ клиентов к репозиторию

Сетевая безопасность достигается путем разрешения отдаленного доступа к CVS-серверу только по протоколу SSH.

Чтобы отдаленный клиент мог получить доступ к серверу, ему необходимо установить переменную окружения CVS_RSH=ssh и выполнить команду, например, чтобы получить последнюю версию модуля mymodule, вроде этой: % cvs -d :ext:anoncvs@cvs.myproject.org:/cvs checkout mymodule

[Up] [Top]

Возможные неполадки

Если после того, как все подготовительные действия проделали, наблюдаются, какие-то странный неполадки, имеет смысл проверить, чтобы:

  • Все используемые бинарные файлы не имели зависимостей от внешних библиотек (ldd cvs);
  • Все используемые бинарные файлы находятся на полагающихся им местах;
  • smrsh и run-cvs скомпилированы с нужными путями к исполняемым файлам в первом случае и к новому корневому каталогу во втором;
  • Правильно задана переменная LockDir в CVSROOT/config;
  • Правильно заданы права доступа к CVSROOT/history и CVSROOT/val-tags ("стандартный" пользователь должен входить в группу cvs-devel);

[Up] [Top]
Смотри еще:
ГлавнаяО себеФоткиРазбиралкиМарафон
Карта

Обратная связь: otokarev@ngs.ru

Rambler's Top100

Hosted by uCoz