Статьи

Хранение зашифрованных учетных данных в Git

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

Знание того, чего не следует делать, является первым и очень важным шагом. Но как мы храним производственные полномочия. Учетные данные базы данных, системные секреты (например, для HMAC), ключи доступа для сторонних сервисов, таких как платежные системы или социальные сети. Кажется, не существует согласованного решения .

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

Где-то это может быть локальный каталог (рискованно), общее хранилище, например, FTP или S3, с ограниченным доступом, или отдельный репозиторий git. Я думаю, что я предпочитаю git-репозиторий, поскольку он позволяет создавать версии (Примечание: S3 также делает, но зависит от провайдера). Таким образом, вы можете хранить все свои файлы свойств среды со всеми их учетными данными и конфигурациями среды в git-репо с ограниченным доступом (только сотрудники Ops). И это неплохо, если это не тот же репо, что и в исходном коде.

Такой репо будет выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
project
└─── production
|   |   application.properites
|   |   keystore.jks
└─── staging
|   |   application.properites
|   |   keystore.jks
└─── on-premise-client1
|   |   application.properites
|   |   keystore.jks
└─── on-premise-client2
|   |   application.properites
|   |   keystore.jks

Поскольку многие компании используют GitHub или BitBucket для своих репозиториев, хранение производственных учетных данных у общедоступного поставщика может по-прежнему рискованно. Вот почему это хорошая идея, чтобы зашифровать файлы в хранилище. Хороший способ сделать это через git-crypt . Это «прозрачное» шифрование, потому что оно поддерживает diff, шифрование и дешифрование на лету. После настройки вы продолжаете работать с репо, как будто оно не зашифровано. Есть даже форк, который работает на Windows .

Вы просто запускаете git-crypt init (после того, как вы поместили бинарный файл git-crypt в путь к вашей ОС), который генерирует ключ. Затем вы указываете свои .gitattributes, например, так:

1
2
3
4
secretfile filter=git-crypt diff=git-crypt
*.key filter=git-crypt diff=git-crypt
*.properties filter=git-crypt diff=git-crypt
*.jks filter=git-crypt diff=git-crypt

И вы сделали. Ну, почти. Если это свежий репо, все хорошо. Если это существующее хранилище, вам придется очистить свою историю, которая содержит незашифрованные файлы. Следуя этим шагам, вы попадете туда с одним дополнением — перед вызовом git commit вы должны вызвать git-crypt status -f чтобы существующие файлы были фактически зашифрованы.

Вы почти закончили. Надо как-то поделиться и сделать резервную копию ключей. Что касается общего доступа, то не так уж важно, чтобы команда из 2–3 сотрудников делила один и тот же ключ, но вы также можете использовать опцию GPG git-crypt (как описано в README). Осталось сделать резервную копию вашего секретного ключа (он создается в каталоге .git / git-crypt). Вы можете хранить его (защищенный паролем) в другом хранилище, будь то общая папка компании, Dropbox / Google Drive или даже ваша электронная почта. Просто убедитесь, что ваш компьютер не единственное место, где он присутствует и что он защищен. Я не думаю, что вращение ключа необходимо, но вы можете разработать некоторую процедуру вращения.

Авторы git-crypt утверждают, что они превосходны, когда дело доходит до шифрования всего нескольких файлов в публичном репо. И рекомендую посмотреть на git-remote-gcrypt . Но так как часто существуют нечувствительные части конфигураций, зависящих от среды, вы можете не захотеть все шифровать. И я думаю, что это прекрасно использовать git-crypt даже в отдельном сценарии репо. И хотя шифрование является хорошим подходом для защиты учетных данных в вашем репо с исходным кодом, все же не обязательно хорошая идея иметь конфигурации среды в одном репо. Особенно с учетом того, что разные люди / команды управляют этими учетными данными. Даже в небольших компаниях, возможно, не все участники имеют доступ к производству.

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

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

Опубликовано на Java Code Geeks с разрешения Божидара Божанова, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Хранение зашифрованных учетных данных в Git

Мнения, высказанные участниками Java Code Geeks, являются их собственными.