Должны ли файлы конфигурации сервера / базы данных, включая пароли, храниться в системе контроля версий? - PullRequest
50 голосов
/ 22 ноября 2010

Мне хотелось бы услышать некоторые рекомендации ...

Предполагается, что веб-приложение взаимодействует с несколькими различными производственными серверами (базами данных и т. Д.) ... если файлы конфигурации содержат пароли базы данныххраниться в системе контроля версий (например, git, svn)?

Если нет, как лучше всего отслеживать пароли базы данных сервера (или других связанных) паролей, к которым вашему приложению необходим доступ?

Редактировать: добавлена ​​награда, чтобы стимулировать больше обсуждений и услышать, что больше людей считают лучшей практикой.

Ответы [ 12 ]

27 голосов
/ 01 декабря 2010

Здесь нет единственного ответа «серебряной пули», и все это будет в значительной степени зависеть от деталей.

Прежде всего, я считаю, что рекомендуется отделять весь исходный код от конфигурации в отдельном репозитории.Итак, исходный код остается исходным кодом, но его установка или развертывание (с настройкой, паролями и т. Д.) - это совсем другое.Таким образом, вы будете жестко отделять задачи разработчиков от задач системных администраторов и в конечном итоге сможете собрать 2 отдельные команды, которые будут делать то, что у них хорошо получается.

Когда у вас есть отдельный репозиторий исходного кода + репозиторий развертывания, ваша лучшая следующая ставкарассматривает варианты развертывания.Лучший способ, который я вижу здесь, - это использование процедур развертывания, типичных для выбранной ОС (то есть создание автономных пакетов для выбранной ОС так, как это делают сопровождающие ОС).

Например, процедуры упаковки в Red Hat или Debian обычно означают захватархив программного обеспечения с внешнего сайта (который будет экспортировать исходные коды из вашего исходного кода VCS), распаковывать его, компилировать и готовить пакеты, готовые к развертыванию.Само развертывание в идеале должно означать простую и быструю команду, которая установит пакеты, такие как rpm -U package.rpm, dpkg --install package.deb или apt-get dist-upgrade (учитывая, что ваши собранные пакеты идут в хранилище, где apt-get сможет найтиих).

Очевидно, чтобы заставить его работать таким образом, вам нужно будет предоставить все файлы конфигурации для всех компонентов системы в полностью рабочем состоянии, включая все адреса и учетные данные.

Чтобы получить более краткие сведения, давайте рассмотрим типичную ситуацию с «небольшим сервисом»: одно приложение PHP развернуто на n серверах приложений, работающих под управлением apache / mod_php, и обращающихся к m серверам MySQL.Все эти серверы (или виртуальные контейнеры, что на самом деле не имеет значения) находятся в защищенной частной сети.Чтобы упростить этот пример, давайте предположим, что все реальные интернет-соединения находятся в кластере из k http ускорителей / обратных прокси (таких как nginx / lighttpd / apache), которые имеют очень простую настройку (только внутренние IP-адреса длявперед).

Что у нас есть для того, чтобы они были подключены и полностью работали?

  • Серверы MySQL: настройка IP-адресов / имен хостов, настройка баз данных, предоставление логинов и паролей
  • PHP-приложение: настройте IP-адреса / имена хостов, создайте файл конфигурации, в котором будут указаны IP-адреса, логины, пароли и базы данных серверов MySQL

Обратите внимание, что здесь есть 2 разных «типа» информации: IPs / hostnames - это что-то фиксированное, вы, вероятно, захотите назначить их раз и навсегда.С другой стороны, логины и пароли (и даже имена баз данных) предназначены исключительно для целей подключения - чтобы убедиться, что для MySQL это действительно наше PHP-приложение, подключающееся к нему.Итак, мои рекомендации здесь будут разделять эти 2 «типа»:

  • «Постоянная» информация, такая как IP, должна храниться в некоторых VCS (отличных от исходного кода VCS)
  • «Временная» информация, такая как пароли между двумя приложениями, никогда не должна храниться, но должна генерироваться во время генерации пакетов развертывания.

Последний и самый сложный вопрос здесь остается: как создавать пакеты развертывания?Доступно несколько методов, 2 основных способа:

  • Экспортированный исходный код из VCS1 + «постоянная» конфигурация из VCS2 + сценарий сборки из VCS3 = пакетов
  • Исходный код находится в VCS1;VCS2 - это распределенный контроль версий (например, git или hg), который по существу содержит «вилки» VCS1 + информация о конфигурации + сценарии сборки, которые могут генерироваться.Мне лично этот подход нравится больше, он намного короче и в конечном итоге проще в использовании, но кривая обучения может быть немного круче, особенно для администраторов, которым для этого придется освоить git или hg.

Для примера выше я бы создал пакеты типа:

  • my-application-php - который будет зависеть от mod_php, apache и будет содержать сгенерированный файл, такой как /etc/my-php-application/config.inc.php, который будет содержать IP-адреса / имена хостов базы данных MySQL и логин / пароль, сгенерированные как md5(current source code revision + salt). Этот пакет будет установлен на каждом из n серверов приложений. В идеале он должен иметь возможность установки на чисто установленную ОС и сделать полностью работающий узел кластера приложений без каких-либо ручных действий.
  • my-application-mysql - который будет зависеть от MySQL-сервера и будет включать в себя скрипт после установки, который:
    • запускает сервер MySQL и обеспечивает автоматический запуск при запуске ОС
    • подключается к серверу MySQL
    • проверяет, существует ли необходимая база данных
    • если нет - создает базу данных, загружает ее с содержимым и создает логин с паролем (те же логины и пароли, которые были сгенерированы в /etc/my-php-application/config.inc.php с использованием алгоритма md5)
    • если да - подключается к базе данных, применяет миграции, чтобы привести ее к новой версии, убивает все старые логины / пароли и воссоздает новую пару логин / пароль (опять же, сгенерированную методом md5 (revision + salt))

В конечном счете, это должно принести выгоду от обновления вашего развертывания с помощью одной команды, такой как generate-packages && ssh-all apt-get dist-upgrade. Кроме того, вы нигде не храните пароли между приложениями, и они обновляются при каждом обновлении.

Этот довольно простой пример иллюстрирует множество методов, которые вы можете использовать здесь - но, в конечном счете, вам решать, какое решение лучше здесь, а какое - излишним. Если вы укажете подробности здесь или в качестве отдельного вопроса, я с удовольствием постараюсь вникнуть в подробности.

18 голосов
/ 22 ноября 2010

Не говоря уже о том, что пароли никогда не должны храниться в виде обычного текста в любом месте (кроме чьего-либо черепа или закрытого хранилища, доступного только для генерального директора, финансового директора и ИТ-директора (и требующих все три ключа одновременно)), вы должны хранить все данные в системе управления исходным кодом, необходимые для сборки вашего продукта.

Это означает не только ваш исходный код, но даже спецификации для машин сборки, опций компилятора, самих компиляторови т. д.

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

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

11 голосов
/ 25 ноября 2010

Пароли не должны храниться в системе контроля версий. Совсем. Когда-либо. См. Как хранить секреты в секрете

Пароли, имена серверов и т. Д. Являются частью конфигурации развертывания, выполняемой администратором сервера. Важно задокументировать эту процедуру и поставить под контроль документированную процедуру.

В качестве альтернативы конфигурация развертывания может быть выполнена с помощью сценария, который sysadmin запустит для выполнения конфигурации, и во время выполнения сценария он запросит sysadmin предоставить необходимую информацию. Опять же, этот скрипт должен храниться в системе контроля версий.

Все остальное, кроме конфигурации сервера должно находиться в системе контроля версий.

Хранение конфигурации сервера в системе контроля версий, как правило, является плохой идеей, поскольку она мешает развертыванию и может привести к небольшим бедствиям (например, когда кто-то не осознает, что его тестовая версия, развернутая из системы контроля версий, взаимодействует с работающей службой) .

Всегда храните эти файлы конфигурации вне webroot.

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

7 голосов
/ 22 ноября 2010

В общем, я согласен с paxdiablo: поставьте все, что возможно, под контроль источников. Это включает в себя производственные файлы конфигурации с учетными данными базы данных.

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

Если вы хотите создавать легко развертываемые пакеты из ваших источников, используя непрерывную интеграцию (еще одна лучшая практика), вам придется поставить файлы конфигурации под контроль исходного кода.

Также учтите, что в большинстве случаев разработчики, имеющие доступ к системе контроля версий, не могут напрямую обращаться к производственному серверу базы данных. Рабочие пароли для них бесполезны.

Если неправильные люди получили доступ к вашим источникам, им все равно нужно получить доступ к производственному серверу, чтобы нанести вред паролям. Таким образом, если ваша производственная среда должным образом защищена, риски безопасности паролей в системе контроля версий очень ограничены.

3 голосов
/ 26 ноября 2010

Я думаю, что этот вопрос больше касается владения информацией, доверия и организации.Вы должны спросить себя, какой части вашей организации вы доверяете, чтобы защитить свои системные пароли от разглашения и неправильного использования?

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

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

1 голос
/ 01 декабря 2010

Проблемы с паролями в исходном коде:

  • трудно варьировать от одного развертывания к другому (я не хочу изменять исходный код в рабочей среде)
  • увеличена вероятность случайного повреждения производственной базы данных при разработке
  • проблема безопасности (в большинстве магазинов нет причин для кода / разработчиков знать пароли prod)
  • измененный пароль требует повторного развертывания

То, что я нашел, работает лучше всего, если у вас есть зарегистрированный конфиг, который использует смешанные стандартные значения и заполнители для конкретных данных развертывания. Наши приложения всегда ищут конфигурацию системы, которая позволяет переопределить любую переменную. Это позволяет производственному компьютеру иметь конфигурацию, подходящую для его развертывания.

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

1 голос
/ 01 декабря 2010

Пример файла конфигурации, конечно, я бы поставил их под контроль версий. Но обычно не с данными реального доступа, такими как адреса серверов или пароли. Больше что-то вроде

# program.conf
#
# mysql option for $myprog.
#
#SERVER_ADDR=127.0.0.1
#SERVER_USER=mysql
#SERVER_PASSWD=abcdef
1 голос
/ 01 декабря 2010

В моих репозиториях Subversion для PHP файлы конфигурации, содержащие пароли, отмечаются как config.php.sample с подсказками о том, что должно быть предоставлено, а для сценариев, требующих config.php, должно присутствовать в том же месте.

Хранилище настроено на игнорирование config.php для этого каталога, чтобы избежать «случайных» добавлений или проверок.

1 голос
/ 22 ноября 2010

Нет. Рабочий пароль должен быть настроен непосредственно на сервере. Вы должны создать инструкции по развертыванию для группы / сотрудника по развертыванию, чтобы изменить правильный файл свойств во время развертывания.

0 голосов
/ 05 февраля 2014

Я предпочитаю иметь файл local_settings рядом с основным файлом settings .Этот local_settings не должен быть добавлен в хранилище, но я добавлю sample.local_setting в хранилище, чтобы показать структуру этого файла.

При запускевремя, когда существует local_settings, его значения будут переопределять значения основного файла настроек.

Например, в python:

settings.py:

log='error.log'
db=lambda:None
db.host='localhost'
db.user=''
db.password=''

try:
    import local_settings
except ImportError:
    pass

local_settings.py:

from settings import *

db.user='abcd'
db.password='1234'
...