Как я могу безопасно сохранить свои секретные ключи и пароль в моей системе контроля версий?

123

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

Но пароли - как и любые другие настройки - кажутся, что они должны быть версиями. Итак, каков правильный способ контроля версий паролей?

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


Я задаю вопрос в целом, но в моем конкретном экземпляре я хотел бы хранить секретные ключи и пароли для сайта Django/Python с помощью git и github.

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


EDIT: Для ясности я спрашиваю, где хранить секреты производства.
  • 1
    На самом деле выдать немного денег, чтобы весь репо был закрытым.
  • 25
    @JohnMee Я на самом деле уже плачу за частный репозиторий, но суть остается неизменной - вы не должны хранить конфиденциальную информацию в своем репозитории.
Показать ещё 6 комментариев
Теги:
version-control

16 ответов

3
Лучший ответ

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

git-crypt

git -crypt использует GPG для прозрачного шифрования файлов, когда их имена соответствуют определенным шаблонам. Для intance, если вы добавили в свой файл .gitattributes...

*.secret.* filter=git-crypt diff=git-crypt

... тогда файл типа config.secret.json всегда будет перенаправлен на удаленные репозитории с помощью шифрования, но останется незашифрованным в локальной файловой системе.

Если я хочу добавить к вашему репо новый ключ GPG (человек), который может расшифровать защищенные файлы, запустите git-crypt add-gpg-user <gpg_user_key>. Это создает новую фиксацию. Новый пользователь сможет расшифровать последующие коммиты.

95

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

Учебное пособие по прозрачному шифрованию/расшифровке во время Push/Pull

Этот gist https://gist.github.com/873637 показывает учебник о том, как использовать Git smudge/clean filter driver с помощью openssl для прозрачного шифрования файлов с нажатой, Вам просто нужно выполнить начальную настройку.

Краткое описание того, как это работает

В основном вы создаете папку .gitencrypt, содержащую 3 bash скрипта,

clean_filter_openssl 
smudge_filter_openssl 
diff_filter_openssl 

которые используются Git для дешифрования, шифрования и поддержки Git diff. В этих сценариях определяется основная кодовая фраза и соль (исправлена!), И вы ДОЛЖНЫ гарантировать, что .gitencrypt никогда не нажимается. Пример clean_filter_openssl script:

#!/bin/bash

SALT_FIXED=<your-salt> # 24 or less hex characters
PASS_FIXED=<your-passphrase>

openssl enc -base64 -aes-256-ecb -S $SALT_FIXED -k $PASS_FIXED

Аналогичен для smudge_filter_open_ssl и diff_filter_oepnssl. См. Gist.

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

.gitattribute Содержание:

* filter=openssl diff=openssl
[merge]
    renormalize = true

Наконец, вам также необходимо добавить следующий файл в ваш .git/config файл

[filter "openssl"]
    smudge = ~/.gitencrypt/smudge_filter_openssl
    clean = ~/.gitencrypt/clean_filter_openssl
[diff "openssl"]
    textconv = ~/.gitencrypt/diff_filter_openssl

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

Примечания

Я должен отметить, что в этом учебном пособии не описывается способ шифрования вашего файла настроек. Это будет прозрачно шифровать весь репозиторий, который будет перенаправлен на удаленный хост VC и расшифровать весь репозиторий, чтобы он был полностью расшифрован локально. Чтобы добиться желаемого поведения, вы можете разместить чувствительные файлы для одного или нескольких проектов в одном файле sensitive_settings_repo. Вы можете исследовать, как эта прозрачная технология шифрования работает с Git subodules http://git-scm.com/book/en/Git-Tools-Submodules, если вам действительно нужны конфиденциальные файлы в одном хранилище.

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

  • 1
    Ох, очень интересно. Это звучит почти так же, как то, что я хочу (за исключением шифрования всего хранилища).
  • 0
    Вы можете сохранить все файлы конфиденциальных настроек для нескольких приложений в одном зашифрованном репозитории или добавить зашифрованный репозиторий с конфиденциальными настройками в свой проект в виде подмодуля Git, как описано здесь git-scm.com/book/en/Git-Tools-Submodules ,
Показать ещё 2 комментария
52

Heroku толкает использование переменных окружения для настроек и секретных ключей:

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

Лучшим решением является использование переменных среды и сохранение ключей вне кода. На традиционном хосте или работающем локально вы можете установить окружение vars в вашем bashrc. На Heroku вы используете config vars.

С файлами Foreman и .env Heroku предоставляет завидную инструментальную цепочку для экспорта, импорта и синхронизации переменных среды.


Лично я считаю неправильным сохранять секретные ключи вместе с кодом. Это принципиально несовместимо с контролем источника, потому что ключи предназначены для служб, которые являются неотъемлемой частью кода. Одним из преимуществ было бы то, что разработчик может клонировать HEAD и запускать приложение без какой-либо настройки. Однако предположим, что разработчик проверяет историческую ревизию кода. Их копия будет включать в себя пароль базы данных в прошлом году, поэтому приложение будет недоступно для сегодняшней базы данных.

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

  • 1
    Этот ответ не имеет достаточного внимания, но он наиболее совпадает с образом Linux.
  • 10
    Так что, если в вашем bashrc установлены переменные среды, и вы развертываете новый сервер, то что создает bashrc? Разве это не просто перемещает пароли из репозитория исходного кода в конфигурацию развертывания? (что, по-видимому, также в репо с исходным кодом или в собственном репо?)
Показать ещё 7 комментариев
16

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

Я рекомендую прочитать главу The Twelve-Factor App, остальные тоже, если вам интересно.

  • 6
    Кажется, что переменные среды - хороший способ запустить приложение с секретными настройками ... но это все еще не отвечает на вопрос, где хранить эти настройки.
  • 2
    Обычно у вас должен быть файл README для каждого из ваших приложений. Там укажите, какие переменные среды должны быть установлены, и каждый раз, когда вы развертываете проект, просто следуйте инструкциям и установите каждую из них. Вы также можете создать скрипт с большим количеством export MY_ENV_VAR= , и при развертывании, просто заполнить его с нужными значениями и source его. Если под « держать» вы подразумеваете версию настроек, вам не следует делать это в первую очередь.
Показать ещё 10 комментариев
11

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

Обновить как ответ из моего комментария ниже:

Интересный вопрос кстати. Я просто нашел это: github.com/shadowhand/git-encrypt, который выглядит очень перспективным для автоматического шифрования

  • 0
    Было бы неплохо иметь что-то, что я мог бы автоматизировать. Так что если мой зашифрованный файл паролей изменится, он автоматически расшифрует новый файл.
  • 7
    Интересный вопрос, кстати. Я только что нашел это: github.com/shadowhand/git-encrypt, который выглядит очень перспективным для автоматического шифрования.
Показать ещё 3 комментария
9

Я предлагаю использовать файлы конфигурации для этого и не выполнять их.

Однако вы можете использовать примеры файлов.

Я не вижу проблем с совместным использованием настроек разработки. По определению он не должен содержать никаких ценных данных.

  • 1
    Но тогда где хранить канонические записи пароля? Это заставит меня нервничать, если эти данные будут храниться только в файле конфигурации на машине, которая может взорваться когда-нибудь.
  • 0
    @ChrisW. Если машина выходит из строя, вам больше не нужен пароль ... Однако, если у вас есть только одна копия данных на рабочем компьютере, это должно поднять красный флаг. Но это не значит, что это должно быть в VCS. Должен быть RAID, полные резервные копии, дополненные инкрементными резервными копиями на магнитных и оптических носителях. Многие корпорации имеют процедуру контроля изменений, которая может определять, как и где хранить пароли и другие конфиденциальные материалы на бумаге.
Показать ещё 3 комментария
7

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

Из описания https://github.com/StackExchange/blackbox:

Безопасное хранение секретов в репозитории VCS (т.е. Git или Mercurial). Эти команды упрощают для вас GPG шифрование определенных файлов в режиме репо поэтому они "зашифрованы в покое" в вашем репозитории. Однако скрипты упрощают их расшифровку, когда вам нужно просматривать или редактировать их, и расшифровать их для использования в производстве.

5

Я задаю вопрос в целом, но в моем конкретном случае я бы хотел хранить секретные ключи и пароли для сайта Django/Python с помощью gitи github.

Нет, просто нет, даже если это ваше личное репо, и вы никогда не собираетесь делиться им, не делайте этого.

Вы должны создать local_settings.py поставить его на VCS игнорировать и в settings.py сделать что-то вроде

from local_settings import DATABASES, SECRET_KEY
DATABASES = DATABASES

SECRET_KEY = SECRET_KEY

Если ваши настройки секретов настолько универсальны, я очень хочу сказать, что вы что-то делаете неправильно

  • 8
    Но мне все равно нужно где-то отслеживать эти секреты. Например, клавиша или что-то в этом роде, верно?
  • 0
    Регулирование и осуществление хранения личных данных зависит от политики компании, для которой проект. Я очень сомневаюсь, что исходный код проекта является подходящим местом, так как любой сторонний тестировщик или программист мог увидеть это
4

EDIT: Я предполагаю, что вы хотите отслеживать свои предыдущие версии паролей - скажем, для script, которые предотвратили бы повторное использование паролей и т.д.

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

  • Вы сохраняете ключ на своей локальной машине.
  • Вы добавляете "mypassword" к игнорируемым файлам.
  • В режиме pre-commit hook вы зашифровываете файл mypassword в файле mypassword.gpg, отслеживаемом git, и добавляете его в commit.
  • На крюке после слияния вы просто расшифровываете mypassword.gpg в mypassword.

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

Позже вы можете использовать .gitattributes, чтобы обеспечить дешифрование "на лету" для выхода из вашего пароля git.

Также вы можете иметь отдельные ключи для разных типов паролей и т.д.

3

Предоставить способ переопределить конфигурацию

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

Переменные среды (как уже упоминалось ранее) - это один из способов сделать это.

Лучший способ - найти внешний файл конфигурации, который переопределяет значения конфигурации по умолчанию. Это позволяет вам управлять внешними конфигурациями через систему управления конфигурацией, такую ​​как Chef, Puppet или Cfengine. Управление конфигурацией - это стандартный ответ для управления конфигурациями отдельно от кодовой базы, поэтому вам не нужно делать выпуск для обновления конфигурации на одном хосте или группе хостов.

FYI: Шифрование кредитов не всегда является лучшей практикой, особенно в месте с ограниченными ресурсами. Возможно, шифрование кредитов не приведет к дополнительным смягчениям риска и просто добавит ненужный уровень сложности. Перед принятием решения убедитесь, что вы сделали правильный анализ.

2

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

2

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

Начиная с Django 1.4, ваши проекты Django теперь поставляются с модулем project.wsgi, который определяет application объект, и это идеальное место для начала использования модуля настроек project.local, который содержит настройки для конкретного сайта.

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

import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.local")

# This application object is used by the development server
# as well as any WSGI server configured to use this file.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

Теперь у вас может быть модуль local.py, владелец и группа которого могут быть настроены таким образом, чтобы только пользовательский персонал и процессы Django могли читать содержимое файла.

2

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

Я использую passwords.conf, который находится в моей домашней папке. При каждом развертывании этот файл обновляется.

  • 0
    Затем программное обеспечение должно расшифровать файл паролей.
  • 0
    Ну, только при развертывании сайта пароль расшифровывается и записывается в текстовый файл пароля
2

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

/yourapp
    main.py
    default.cfg.dist

И когда я запустил main.py, поместите настоящий пароль в default.cfg, который скопирован.

пс. когда вы работаете с git или hg. вы можете игнорировать файлы *.cfg, чтобы сделать .gitignore или .hgignore

  • 0
    Я не знаком с файлами .dist - как они работают?
  • 0
    Файлы .dist - это то, о чем я говорил: примеры реальных файлов конфигурации. Хорошей практикой является возможность запуска программного обеспечения только путем переименования, удалив расширение «.dist» (или лучше: копирование), то есть вы сможете попробовать программное обеспечение за считанные секунды, не настраивая его во время целый день.
1

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

0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню