Як я можу надійно зберегти свої секретні ключі та пароль у своїй системі контролю версій?


134

Я зберігаю такі важливі параметри, як імена хостів і порти серверів розробки та виробництва в моїй системі управління версіями. Але я знаю, що зберігати секрети (наприклад, приватні ключі та паролі бази даних) у сховищі VCS є поганою практикою .

Але паролі - як і будь-яке інше налаштування - здаються такими, що їх слід враховувати. Так що це правильний спосіб зберігання паролів версії контрольованих?

Я гадаю, що це передбачає збереження секретів у власному файлі "налаштування секретів", а цей файл буде зашифровано та контролюється версія. Але які технології? І як це зробити правильно? Чи є кращий спосіб цілком зробити це?


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

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


EDIT: Для ясності, я маю просити про те, де зберігати виробничі секрети.


1
Насправді нагромаджуйте трохи грошей, щоб утримати все репо приватне.
Джон Мей

29
@JohnMee Я фактично вже плачу за приватне сховище, але справа залишається - вам не варто зберігати конфіденційну інформацію у вашому сховищі.
Кріс В.

1
Я думаю, що значну частину причин, що задовольняють відповідями, важко буде отримати в тому, що старомодний звичайний пароль для підключення до бази даних є пережитком менш ворожої епохи. Правильна відповідь - це щось на кшталт "ваш код не потребує секрету", але системи, до яких ви звертаєтесь, не дають вам великого вибору.
msw

4
Чому? Значення zilch у версії, що контролює паролі для зовнішніх служб. Основна цінність контролю версій полягає в тому, що ви можете перевірити історичні версії вашої програми, як відомо, в робочому стані та запустити їх . Однак старі паролі для вас марні. Якщо їх відкликають, вони більше ніколи не працюватимуть.
Полковник Паніка

Відповіді:


100

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

Підручник з прозорого шифрування / розшифрування під час натискання / перетягування

Цей суть https://gist.github.com/873637 демонструє підручник про те, як використовувати драйвер фільтру Git для розмиття / очищення з openssl для прозорого шифрування відсунутих файлів. Вам просто потрібно зробити кілька початкових налаштувань.

Короткий огляд того, як це працює

Ви в основному будете створювати .gitencryptпапку, яка містить 3 баш сценарії,

clean_filter_openssl 
smudge_filter_openssl 
diff_filter_openssl 

які використовуються Git для дешифрування, шифрування та підтримки Git diff. Основна парольна фраза та сіль (фіксовано!) Визначені всередині цих сценаріїв, і ви ОБОВ'ЯЗКОВО переконатися, що .gitencrypt ніколи не буде натиснуто. Приклад clean_filter_opensslсценарію:

#!/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. Див.

У вашому репо з конфіденційною інформацією повинен бути файл .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, і розшифрує все сховище, щоб воно повністю розшифрувалось локально. Щоб досягти потрібної вам поведінки, ви можете розмістити чутливі файли для одного або багатьох проектів в одному чутливому_настрої_репо. Ви можете дослідити, як працює ця прозора техніка шифрування з підмодулями Git http://git-scm.com/book/en/Git-Tools-Submodules, якщо вам дійсно потрібні чутливі файли, які знаходяться в одному сховищі.

Використання фіксованої парольної фрази теоретично може призвести до вразливих ситуацій, якщо зловмисники мали доступ до багатьох зашифрованих репост / файлів. ІМО, ймовірність цього дуже низька. Як зазначається внизу цього підручника, невикористання фіксованої парольної фрази призведе до того, що локальні версії репо на різних машинах завжди показують, що зміни відбулися зі статусом "git".


1
О, дуже цікаво. Це звучить майже так, як я хочу (крім його шифрування всього сховища).
Кріс У.

Ви можете або зберегти всі чутливі файли налаштувань для декількох додатків в одному зашифрованому сховищі, або додати зашифроване сховище з чутливими налаштуваннями до свого проекту як підмодуль Git, як описано тут git-scm.com/book/en/Git-Tools-Submodules .
dgh

Зберігання виробничих паролів / налаштувань у (зашифрованому) підмодулі не є рідкістю. stackoverflow.com/questions/11207284/… . Це навіть полегшило б керування налаштуваннями для проектів.
dgh

Можливо, варто перевірити github.com/AGWA/git-crypt для оновлення рішення. Він має перевагу в тому, що дозволяє зафіксувати окремі файли, і він стверджує, що він "суттєво семантично захищений". Сам автор суті припустив, що цей інструмент є кращим на веб- сайті github.com/shadowhand/git-encrypt .
geekley

52

Heroku натискає на використання змінних середовища для налаштувань та секретних ключів:

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

Кращим рішенням є використання змінних оточення та збереження ключів від коду. На традиційному хості чи локальній роботі ви можете встановити vars середовища у вашому bashrc. У Heroku ви використовуєте налаштування vars.

Завдяки Foreman та .envфайлам Heroku забезпечують завидну ланцюжок інструментів для експорту, імпорту та синхронізації змінних середовища.


Особисто я вважаю, що зберігати секретні ключі поряд із кодом неправильно. Це принципово не відповідає керуванню джерелом, оскільки ключі призначені для служб, зовнішніх до коду . Найголовнішим плюсом буде те, що розробник може клонувати HEAD і запускати додаток без будь-яких налаштувань. Однак припустимо, розробник перевіряє історичну версію коду. Їх копія буде включати минулорічний пароль бази даних, тому додаток вийде з ладу проти сьогоднішньої бази даних.

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


1
На цю відповідь недостатньо уваги, але вона найбільше збігається з linux-способом.
Микола Фоміних

11
Отже, якщо у вашому bashrc встановлено vars середовища, а ви розгортаєте новий сервер, то що створює bashrc? Хіба це не просто переміщує паролі з репо-версії вихідного коду та у конфігурацію розгортання? (що, мабуть, також є у репо-коді вихідного коду чи у власному репо?)
Джонатан Хартлі

@JonathanHartley, ваш .bashrc не повинен бути в кодовому коді для вашої програми Django.
Стів

4
Вибачте, мій коментар неоднозначний, але це тому, що я справді розгублений. Я люблю звучання точки зору цієї відповіді, але ніколи не зрозумів її повністю. Якщо я розгортаю декілька різних середовищ, кожне з яких містить кілька хостів, а можливо, декілька типів хостів, то, очевидно, мені потрібно автоматизувати створення файлів .bashrc, які існуватимуть на кожному хості, щоб встановити його змінні середовища. Тож відповідь говорить, що я повинен мати друге репо, окремо від мого джерела, яке містить усі налаштування, які стануть змінними середовища в .bashrc при розгортанні?
Джонатан Хартлі

1
Їх потрібно налаштувати лише після того, як машина PER, до якої ви розгорнулися. Якщо ваш процес розгортання - "закрутити нову машину і перевірити, чи це нормально, перш ніж перенаправити на неї трафік, а потім застрелити старий у голову", що найкраще практикує IMHO, тоді вам дійсно потрібно автоматизувати створення будь-яких установок env vars.
Джонатан Хартлі

16

Найчистіший спосіб, на мою думку, - використовувати змінні середовища. Вам не доведеться мати справу з .distНаприклад, файлами , і стан проекту у виробничому середовищі буде таким же, як у вашої локальної машини.

Я рекомендую прочитати розділ конфігурації програми « Дванадцять фактор », інші, якщо вам це цікаво.


6
Здається, що змінні середовища - це хороший спосіб запустити додаток із секретними налаштуваннями ... але він все ще не відповідає на питання, де зберегти ці налаштування.
Кріс В.

2
Зазвичай у вас є файл README для кожного із ваших програм. Там же вкажіть, які змінні середовища слід встановити, і кожен раз, коли ви розгортаєте проект, просто виконайте кроки та встановіть кожну з них. Ви також можете створити скрипт оболонки з багатьма export MY_ENV_VAR=, а коли ви розгортаєте, просто заповніть його потрібними значеннями та sourceним. Якщо по тримати ви маєте в виду версію налаштувань, ви не повинні робити це в першу чергу.
Samy Dindane

Крім того, підняття на додаток «Дванадцять факторів» - справді чудові речі.
Кріс В.

4
@Samy: А якщо ви автоматизували розгортання?
Джонатан Хартлі

3
@Samy Я досі не розумію, як встановлювались змінні середовища. Сторінка програми з 12 факторами також не дає зрозуміти (якщо ви не перебуваєте на Heroku, що не є моїм поточним проектом) дайте мені свої конфігураційні дані ", і це відповідає значенням змінних оточуючих середовищ, які слід встановити. У такому випадку я не думаю, що вам більше не потрібен створений сценарій. Я дико спекулюю тут, чи я гавкую правильне дерево?
Джонатан Хартлі

10

Варіантом було б помістити пов'язані з проектом облікові дані в зашифрований контейнер (TrueCrypt або Keepass) і натиснути на нього.

Оновити як відповідь з мого коментаря нижче:

Цікаве питання btw. Я щойно знайшов це: github.com/shadowhand/git-encrypt, що виглядає дуже перспективно для автоматичного шифрування


Було б непогано мати щось, що я міг би автоматизувати. Таке, що якщо мій зашифрований файл пароля зміниться, він автоматично розшифровує новий файл.
Кріс В.

7
Цікаве питання btw. Я щойно знайшов це: github.com/shadowhand/git-encrypt, що виглядає дуже перспективно для автоматичного шифрування.
шнек

1
Ого, чудово. Опис git-encryptзвучить як саме те, що я шукаю "Під час роботи з віддаленим сховищем git, яке розміщується на сторонньому сервері зберігання даних, конфіденційність даних іноді викликає занепокоєння. Ця стаття розглядає вас через процедури налаштування сховищ git для яких ваші локальні робочі каталоги є нормальними (незашифровані), але закріплений вміст зашифрований. " (Звичайно, я хочу лише зашифровану підмножину мого вмісту ...)
Chris W.

@schneck опублікуйте ваш коментар як відповідь, щоб Кріс міг його прийняти - схоже, це те, що він шукає.
Тоні Абу-Асале

9

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

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

Я не бачу жодних проблем із спільним налаштуванням розробки. За визначенням він не повинен містити цінних даних.


1
Але тоді де зберігати канонічні записи паролів? Мене буде нервувати, щоб ці дані сиділи лише у файлі конфігурації на машині, який може підірватися якийсь день.
Кріс В.

@ChrisW. Якщо машина підірветься, вам більше не потрібно мати пароль ... Однак, якщо у вас є лише одна копія даних на виробничій машині, це повинно підняти червоний прапор. Але це не означає, що воно повинно бути в VCS. Повинні бути RAID, повні резервні копії, доповнені покроковими резервними копіями на магнітних та оптичних носіях. Багато корпорацій мають процедуру контролю змін, яка може диктувати, як і де зберігати паролі та інші чутливі матеріали на папері.
Стів Бузонас

@ChrisW Я не хочу бути грубим, але, здається, ти не кажеш нам правди, і паролі, які ти хочеш зберегти, використовуються не в розробці, а у виробництві. Чи це не правда? В іншому випадку, чому ви дбаєте про розробку або тестування машини та паролі розробки? Ніхто цього не зробив.
титак

BTW, в нашій компанії всі паролі розробки доступні на папері та в інтрамережі. Тому що вони не мають значення. Вони там, тому що програмне забезпечення, яке ми розробляємо, потребує аутентифікації.
титак

@tiktak, ви праві - моє запитання стосується того, що робити з виробничими паролями. Мене особливо не хвилює збереження паролів розробки в VCS. Вибачте, якщо я цього не зробив досить ясно.
Кріс В.

7

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

З опису на https://github.com/StackExchange/blackbox :

Безпечно зберігайте секрети у репортажі VCS (тобто Git або Mercurial). Ці команди полегшують вам шифрування GPG певних файлів у репо, щоб вони були «зашифровані у спокої» у вашому сховищі. Однак сценарії дозволяють легко розшифрувати їх, коли вам потрібно переглянути або відредагувати, та розшифрувати їх для використання у виробництві.


7

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

git-склеп

git-crypt використовує GPG для прозорого шифрування файлів, коли їх імена відповідають певним шаблонам. Наприклад, якщо ви додасте у свій .gitattributesфайл ...

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

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

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


5

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

Ні, просто не робіть, навіть якщо це ваше приватне репо, і ви ніколи не збираєтесь ним ділитися, не варто.

Вам слід створити local_settings.py, поставити його на ігнор VCS, а в налаштуваннях.py зробити щось подібне

from local_settings import DATABASES, SECRET_KEY
DATABASES = DATABASES

SECRET_KEY = SECRET_KEY

Якщо ваші налаштування секретів такі універсальні, я хочу сказати, що ви щось робите не так


9
Але мені все одно потрібно десь слідкувати за цими секретами . Напр., Клавіатурний ключ або щось подібне, так?
Кріс В.

Регулювання та реалізація зберігання приватних даних залежить від політики компанії, для якої працює проект. Я дуже сумніваюся, що вихідний код проекту є належним місцем, оскільки це може побачити будь-який сторонній тестер або програміст
Hedde van der Heide

4

EDIT: Я припускаю, що ви хочете відслідковувати свої попередні версії паролів - скажімо, для сценарію, який би перешкоджав повторному використанню пароля тощо.

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

  1. Ви тримаєте ключ на локальній машині.
  2. Ви додаєте "мій пароль" до ігнорованих файлів.
  3. На гачку попереднього введення ви зашифровуєте файл mypassword у файл mypassword.gpg, відстежений git, і додаєте його до фіксації.
  4. На гачку після злиття ви просто розшифруєте mypassword.gpg в мій пароль.

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

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

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


3

Зазвичай я окремий пароль як файл конфігурації. і відволікти їх.

/yourapp
    main.py
    default.cfg.dist

І коли я запускаю main.py, вкладаю справжній пароль у default.cfgцей скопійований.

пс. коли ви працюєте з git або hg. ви можете ігнорувати *.cfgфайли для створення .gitignoreабо.hgignore


Файли .dist - це те, про що я говорив: приклади реальних файлів конфігурації. Доброю практикою є те, що запускати програмне забезпечення слід лише шляхом перейменування, видаливши розширення ".dist" (а краще: копіювання), тобто ви зможете спробувати програмне забезпечення за лічені секунди, не потребуючи його налаштування під час Весь день.
титак

3

Укажіть спосіб зміни конфігурації

Це найкращий спосіб керувати набором розумних стандартних налаштувань для конфігурації, яку ви перевіряєте, не вимагаючи, щоб конфігурація була повною, або містила такі речі, як імена хостів та облікові дані. Існує кілька способів змінити конфігурації за замовчуванням.

Змінні середовища (як уже згадували інші) є одним із способів цього зробити.

Найкращий спосіб - це шукати зовнішній файл конфігурації, який замінює значення конфігурації за замовчуванням. Це дозволяє керувати зовнішніми конфігураціями за допомогою системи управління конфігурацією, такою як Chef, Puppet або Cfengine. Управління конфігурацією - це стандартна відповідь для управління конфігураціями, окремо від бази даних коду, тому вам не потрібно робити випуск для оновлення конфігурації на одному хості або групі хостів.

БЮР: Шифрування кредитів не завжди є найкращою практикою, особливо в місцях з обмеженими ресурсами. Може статися так, що шифрування кредитів не позбавить вас від додаткового зменшення ризику та просто додасть зайвий рівень складності. Переконайтеся, що ви робите належний аналіз, перш ніж приймати рішення.


2

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

Я використовую passwords.conf, розміщений у моїй домашній папці. Після кожного розгортання цей файл оновлюється.


Потім програмному забезпеченню потрібно розшифрувати файл пароля.
тиктак

Ну, тільки під час розгортання сайту пароль розшифровується та записується у звичайний текстовий файл пароля
Вілліан

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

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



1

Це те, що я роблю:

  • Зберігайте всі секрети як env vars у $ HOME / .secrets (go-r perms), що джерелами $ HOME / .bashrc (таким чином, якщо ви відкриєте .bashrc перед ким-небудь, вони не побачать секрети)
  • Файли конфігурації зберігаються у VCS як шаблони, такі як config.properties, що зберігаються як config.properties.tmpl
  • Файли шаблонів містять заповнювач секрету, наприклад:

    my.password = ## MY_PASSWORD ##

  • Під час розгортання програми виконується скрипт, який перетворює файл шаблону в цільовий файл, замінюючи заповнювачі значеннями змінних оточуючих середовищ, наприклад зміною ## MY_PASSWORD ## на значення $ MY_PASSWORD.


0

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

Однак потрібно буде встановити папки EncFS, що може бути зроблено вашою програмою на основі пароля, який зберігається в іншому місці поза версіями (наприклад, змінні середовища).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.