Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Хранилище секретов для бедных #93

Open
kulakovt opened this issue Oct 7, 2019 · 17 comments
Open

Хранилище секретов для бедных #93

kulakovt opened this issue Oct 7, 2019 · 17 comments

Comments

@kulakovt
Copy link
Member

kulakovt commented Oct 7, 2019

Проблема

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

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

К хранилищу настроек предъявляются следующие требования:

  • секретность - значения не должны быть видны всем желающим
  • доступность - развёрнутый сервер должен иметь доступ к хранилищу и возможность прочитать все настройки
  • надёжность - хранилище должно быть доступно в произвольных момент времени
  • редактируемость - изменения в настройках должны легко вноситься администраторами системы

Стандартное решение

По хорошему, мы конечно должны воспользоваться для этих целей Azure Key Vault'ом или подобным сервисом. Но нам не хочется заводить новый сервис и тратить ресурсы на его поддержку. Кажется что можно обойтись более простыми и понятными инструментами.

Бесплатное решение

Нам может помочь шифрование. Файл с настройками шифреутся публичным ключом и выкладывается в общедоступное место (например в репозиторий GitHub или Gist). Приватный ключ есть только у хостинга Azure. Она должна его любезно сообщить запускаемому приложению. Приложение на старте скачивает файл настроек с известного места, расшифровывает его, используя приватный ключ, и загружает настройки. Подобный метод используется в билд системах (например AppVeyor, TravisCI).

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

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

@kulakovt
Copy link
Member Author

kulakovt commented Oct 7, 2019

@egorikas , @Sergey-Buyanov , @ilabutin, @rafaelldi
Нужны комментарии.
#1 #4 #6

@ilabutin
Copy link
Collaborator

ilabutin commented Oct 7, 2019

Из какого места приложение в продакшене будет брать приватные ключи? Их по идее тоже надо бы в KeyVault хранить. И их будет несколько как ты сам заметил.

Или ты про клиентское UI приложение?

@kulakovt
Copy link
Member Author

kulakovt commented Oct 7, 2019

Разговор пока только про сервер.

Из какого места приложение в продакшене будет брать приватные ключи?

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

И их будет несколько как ты сам заметил.

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

@egorikas
Copy link
Contributor

egorikas commented Oct 8, 2019

А может нам просто ажуровское хранилище секретов заюзать?

@ilabutin
Copy link
Collaborator

ilabutin commented Oct 8, 2019

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

Для начала могу развернуть у себя в Azure сервер и настроить keyvault + сделать powershell для его настройки. Дальше "просто" применим этот powershell к production аккаунту.

@kulakovt
Copy link
Member Author

kulakovt commented Oct 8, 2019

У нас денег нет. И стабильной Ажуры тоже нет.

Когда придёт день "Ж", Докер с контейнером можно будет быстро развернуть на любом бесплатном хостинге. С KeyVault будут проблемы. Мы не можем себе позволить подобный vendor-lock. Так же, как и нормальную БД (привет #91).

А в чём проблема с шифрованием файла?

@ilabutin
Copy link
Collaborator

ilabutin commented Oct 9, 2019

Проблем с шифрованием файлов нет, но это чуть сложнее.
ОК, вижу что там нет бесплатного плана. Я почему-то считал что есть.

Тогда да, сделаем на сертификатах.

Дополнительные вопросы:

  • редактирование настроек отдельных сообществ делается средствами API сервера? Или отдельный тул?
  • редактирование настроек системы в целом делается средствами API сервера? Или отдельный тул?

@egorikas
Copy link
Contributor

egorikas commented Oct 9, 2019

Мне кажется делать отдельный тул, для настроек - как-то оверинжиниринг на данный момент

@kulakovt
Copy link
Member Author

kulakovt commented Oct 9, 2019

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

Например:

  • заводим в репозитории «Server» папку Secrets
  • в этой папке лежат зашифрованные файлы для каждого сообщества (SpbDotNet.config.secret)
  • в ней же лежит публичный ключ, которым будут шифроваться все конфиги
  • там же находится скрипт который ищет файлы «*.config» и шифрует их с помощью публичного ключа, переименовывая результат в «*.config.secret»
  • далее файлы «*.config» остаются на локальной машине Оператора (с помощью .gitignore или другой магии), а все файлы «*.config.secret» заливаются git'ом в репозиторий
  • далее из GitHub репозитория файлы «*.config.secret» может считывать кто угодно, в том числе и наш Сервер из Ажуры

@ilabutin
Copy link
Collaborator

ilabutin commented Oct 9, 2019

Тогда у меня получается такой список задач здесь:

  • PowerShell скрипт для генерации сертификата
  • PowerShell скрипт для шифрования любых secrets\*.config в secrets\*.config.secret + .gitignore
  • Добавить настройку в сервер откуда качать файлы настроек и собственно их скачивание
  • Написать Configuration provider который умеет из скачанных зашифрованных файлов и certificate private key (взятого из переменной окружения) выдать набор опций
  • Нужно сгенерить тестовый "секретный" сертификат, в существующий Azure hosting записать private key и протестировать всё это

Мы хостим "один сервер-одно сообщество"? Т.е. один инстанс сервера только с одним сообществом работает или сразу со многими должен уметь (нужно ли одновременно от всех сообществ из ConfigurationProvider настройки отдавать?)?

@kulakovt
Copy link
Member Author

kulakovt commented Oct 9, 2019

PowerShell скрипт для генерации сертификата

Я бы не называл это "Сертификатом", ибо сие намекает на X.509. Который сложный, бажный и сильно (для нас) избыточный. Мне кажется корректнее говорить об асимметричном шифровании или криптосистеме с открытым ключом.

PowerShell скрипт для шифрования

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

Ещё было бы очень полезно иметь команду, которая создаст типичный пример *.config файла для сообщества. Чтобы не гадать о правильном формате и о нужном количестве настроек (account name, group url, api token, refresh token и прочее).

В остальном выглядит правдоподобно 👍

Мы хостим "один сервер-одно сообщество"?

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

@kulakovt
Copy link
Member Author

@ilabutin , есть все согласны, предлагаю разбить это на минимальные таски и начать делать. Ещё можно попробовать создать Project или как тут объединение в большую фичу делается?

@ilabutin
Copy link
Collaborator

ilabutin commented Oct 12, 2019

Да, можно попробовать project, но у меня нет прав создавать проекты и вешать к ним issues. Либо дай права, либо тебе придётся всё это делать.
@AnatolyKulakov

@kulakovt
Copy link
Member Author

Все права у @egorikas . Я тут такой же комментатор, как и все :)

@egorikas
Copy link
Contributor

@AnatolyKulakov ой, я только увидел

@egorikas
Copy link
Contributor

@ilabutin выдал права

@zetroot
Copy link
Collaborator

zetroot commented Apr 3, 2021

В новой концепции, "serverless", получается единственным безопасным местом является машина пользователя.
Разделить секреты по сообществам.
Хранить шифротекст секретов прям в аудите, например в дополнительной секции конфига сообщества.
Для дешифровки требовать у пользователя ключ при выборе сообщества.
Можно использовать симметричное шифрование.

Вот такой рецепт усреднённый.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants