четверг, 9 февраля 2012 г.

Управление конфигурацией в IT инфраструктуре ч.1

Придя на нынешнее место работы, я был несколько удивлен. При большой и развитой it инфраструктуре механизма управления конфигурациями не было. Достаточно давно я использую rancid для хранения конфигурационных файлов оборудования cisco. После того как несколько лет назад я прочитал статью об использовании subversion, я стал использовать его для управления конфигурационными файлами на unix серверах. Так как rancid не поддерживает ряд оборудования, которое используется в настоящий момент (в основном это san оборудование), то возникла необходимость разработать решение под себя. Причем решение должно быть одно для всей инфраструктуры.
Для понимания какой конечный результат нужен, я сформулировал требования/положения которые я использовал в процессе разработки и эксплуатации решения:
  • Должно быть единое хранилище конфигурационной информации, включающее в себя конфигурационные файлы приложений, сетевого и san оборудования, а так же файлы скриптов
  • Для хранения конфигураций необходимо использовать систему контроля версий
  • В корне репозитория должны быть контейнеры отражающие классовую принадлежность конфигурационных файлов (т.е. к примеру servers - для серверов, devices - для устройств). Конфигурационные файлы серверов должны группироваться по принадлежности к серверу. Контейнер, содержащий конфигурационные файлы, должен именоваться в соответствии с полным именем сервера. Путь к конфигурационным файлам, находящимся в контейнере c именем сервера, должен соответствовать пути к файлу на файловой системе.  Конфигурационные файлы устройств должны группироваться по принадлежности к семейству, контейнер должен содержать имя семейства. Соответственно структура репозитория должна выглядеть следующим образом:
  /
   /servers/
      /name_of_server/
         /path_to_file/
            /file

         /path_to_file/
            /script_file
   /devices/
      /device_name/
         /device_name
  • Механизм получения конфигураций оборудования должен работать автоматически. Должен использоваться конфигурационный файл, содержащий все необходимое (название устройства, логин, пароль, признак то что с устройства надо снимать конфигурацию). Конфигурация должна быть получена рекомендованным производителем способом, для возможности корректного восстановления. Необходимо так же предусмотреть возможность получения информации о состоянии оборудования (версия ПО, состояние портов, заполненность пулов и т.п.)
  • Конфигурационные файлы с серверов помещаться в репозиторий будут вручную, с указанием целей произведенного изменения (через несколько лет краткие комментарии бывают иногда очень полезны). 
  • Необходим web интерфейс для анализа текущей конфигурации и произведенных изменений.
Легко заметить что процесс внедрения решения разделяется на две части. В первой мы произведем установку репозитария и рассмотрим основные аспекты его использования. А во второй напишем скрипт, который будет помещать в репозиторий конфигурационные файлы оборудования.
Используемое программное обеспечение: дистрибутив linux - rhel5,  в качестве системы контроля версий - subversion, httpd и websvn - для формирования web интерфейса. Полное имя сервера с используемое в примерах - server.domain. Подключите репозиторий epel, т.к ряд rpm пакетов содержится именно там.

Установим httpd, subversion и необходимые модули:

[root@server ~]# yum install mod_dav_svn websvn subversion httpd mod_ssl
[root@server ~]# chkconfig httpd on

Создадим самоподписанный сертификат для шифрования сессии между клиентом и сервером subversion:

[root@server ~]# openssl req -out /etc/pki/tls/certs/repos.crt -nodes -keyout /etc/pki/tls/private/repos.key -newkey rsa:2048 -x509 -days 3650  -subj "/C=RU/ST=Moscow/L=Moscow/O=Organization Name/CN=server.domain/emailAddress=email@domain"

Настроим модуль mod_dav_svn следующим образом:

[root@server ~]# grep -v '^#\|^$' /etc/httpd/conf.d/subversion.conf 
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so
<Location /repos>
   DAV svn
   SVNParentPath /var/www/svn
      SSLRequireSSL
      AuthType Basic
      AuthName "Authorization Realm"
      AuthUserFile /etc/httpd/conf.d/svn-auth-conf
      Require valid-user
</Location>

Исправите путь к сертификату в файле ssl.conf:

[root@server ~]# grep "^SSLCert" /etc/httpd/conf.d/ssl.conf 
SSLCertificateFile /etc/pki/tls/certs/repos.crt
SSLCertificateKeyFile /etc/pki/tls/private/repos.key

Создадим файл паролей, который будет ограничивать доступ в репозиторий:

[root@server ~]# htpasswd -c /etc/httpd/conf.d/svn-auth-conf confrepuser
New password:
Re-type new password:
Adding password for user confrepuser

Добавим системного пользователя, от имени которого будет работать скрипт:

[root@server ~]# adduser confrepuser -c "Owner of repository"
[root@server ~]# echo "cfgbackup" | passwd --stdin confrepuser

Создадим репозиторий и запустим httpd:

[root@server ~]# mkdir /var/www/svn
[root@server ~]# cd /var/www/svn
[root@server ~]# svnadmin create confrepo
[root@server ~]# chown -R apache.confrepuser confrepo
[root@server ~]# chmod -R g+w ./confrepo
[root@server ~]# /etc/init.d/httpd start

Проверить работоспособность репозитория можно пройдя по ссылке  https://server.domain/repos/confrepo, введя логин/пароль вы должны увидеть страничку "confrepo - Revision 0: /". Если все получилось то перейдем к формировании структуры репозитория.

Создадим в репозитории корневые директории:

[root@server ~]# su - confrepuser
[confrepuser@server ~]$ svn mkdir file:///var/www/svn/confrepo/servers -m "Add dir"

Committed revision 1

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

[confrepuser@server ~]$ svn mkdir file:///var/www/svn/confrepo/devices -m "Add dir"

Если указать переменную среды SVN_EDITOR с предпочитаемым редактором, то ключ "-m" можно не ставить, к примеру:

[confrepuser@server ~]$ export SVN_EDITOR=vim

Проиллюстрируем методику управления конфигурационными файлами на примере сервиса httpd, находящемся на сервере server2.domain. В соответствии с сформулируемыми ранее правилами создаем папки:

[confrepuser@server ~]$ svn mkdir --parents file:///var/www/svn/confrepo/servers/server2.domain/etc -m "Add dir"

Далее, на сервере server2.domain создадим рабочую копию каталога /etc непосредственно в корне файловой системы:

[root@server2 ~]# cd /
[root@server2 ~]# svn co https://server.domain/repos/confrepo/servers/server2.domain/etc

Error validating server certificate for 'https://server.domain:443':
 - The certificate is not issued by a trusted authority. Use the
   fingerprint to validate the certificate manually!
Certificate information:
 - Hostname: server.domain
 - Valid: from Feb  3 09:53:02 2012 GMT until Jan 31 09:53:02 2022 GMT
 - Issuer: Organization, Moscow, Moscow, RU
 - Fingerprint: 59:73:33:56:87:78:7f:06:f9:da:ae:de:c7:f9:19:ac:88:26:dd:42
(R)eject, accept (t)emporarily or accept (p)ermanently? p
...
Username: confrepuser
Password for 'confrepuser':
...
Store password unencrypted (yes/no)? no

Примите сертификат, введите логин и пароль. На вопрос "Сохранить пароль?" ответьте отрицательно, т.к. в случае утвердительного ответа пароль будет хранится в открытом виде, в файле находящемся в директории ~/.subversion/auth/svn.simple. Для того что бы в последующем этот вопрос не возникал добавьте следующий параметр:

[root@server2 ~]# echo "store-plaintext-passwords=no" >> /root/.subversion/servers

Добавим конфигурационные файлы в репозиторий, и запишем изменения (закоммитим):

[root@server2 ~]# svn add --parents /etc/httpd/conf/httpd.conf
[root@server2 ~]# svn add --parents /etc/httpd/conf.d/ssl.conf
[root@server2 ~]# svn commit /etc -m "Add apache's conf/ for server2.domain"

Итак, данные файлы теперь доступны в репозитории. Предположим что мы добавили новый хост в конфигурации httpd, произведем изменение и запишем изменение в репозиторий:

[root@server2 ~]# svn commit /etc -m "Add new vhost for server2.domain"
...
Sending        etc/httpd/conf/httpd.conf
Transmitting file data .
Committed revision 5.



Если необходимо вернуть конфигурацию к предыдущему состоянию:

[root@server2 ~]# svn co -r 4 https://server.domain/repos/confrepo/servers/server2.domain/etc/httpd/ /etc/httpd
...
U    /etc/httpd/conf/httpd.conf
Checked out revision 4.



опция "-r" указывает номер ревизии на который надо восстановить.
Если необходимо удалить файл или директорию из репозитория:

[root@server2 ~]# svn rm https://server.domain/repos/confrepo/servers/server2.domain/etc/httpd/conf/httpd.conf -m "remove file"

Развертывание конфигурационных файлов на сервер отличный от первоначального можно выполнить следующим образом:
  1. Создадите рабочую копию каталога содержащего конфигурационные файлы в домашней директории;
  2. Перепишите файлы в место назначения;
  3. Создадите новую директорию в репозитории с именем сервера, и поместите туда файлы.
Как вы уже заметили, web страница репозитария не отражает какие именно внесены изменения. Для наглядного работы с репозиторием воспользуемся уже установленным websvn. Приведите конфигурационный файл /etc/httpd/conf.d/websvn.conf виду:

[root@server ~]# grep -v '^#\|^$' /etc/httpd/conf.d/websvn.conf
Alias /websvn /usr/share/websvn/
<Directory /usr/share/websvn/>
   SSLRequireSSL
   Options MultiViews
   DirectoryIndex wsvn.php
   order allow,deny
   allow from all
   AuthType Basic
   AuthName "Subversion Repository"
   AuthUserFile /etc/httpd/conf.d/svn-auth-conf
   Require valid-user
</Directory>


Укажите нахождение репозитория в конфигурации websvn:


[root@server ~]# echo "\$config->addRepository('Organization's Repository', 'file:///var/www/svn/confrepo');" >> /etc/websvn/config.php
[root@server ~]# /etc/init.d/httpd reload


Рассказывать о websvn нет смысла, там все очень просто, просто перейдите по ссылке https://server.domain/repos/websvn. В качестве меры безопасности, вы можете сменить метод аутентификации на более стойкий (или можно просто использовать другой AuthUserFile).