Назад | Перейти на главную страницу

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

Рекомендации DevOps на https://12factor.net/config Предлагаем поместить секреты веб-сайта (пароли к базе данных, ключи API и т. д.) в переменные среды. Какие преимущества дает это вместо использования текстовых файлов (JSON, XML, YAML, INI или подобных), игнорируемых системой контроля версий?

Мне гораздо проще скопировать файл конфигурации с секретами, чем обрабатывать переменные среды в .bash_profile и конфигурации веб-сервера. Я что-то упускаю?

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

Исходя из моего собственного опыта, у вас, по сути, есть следующие три варианта с соответствующими преимуществами и недостатками:

Храните данные в файлах конфигурации.

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

Преимущества:

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

Недостатки:

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

Храните данные в переменных среды.

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

Преимущества:

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

Недостатки

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

Используйте аргументы командной строки для передачи данных.

Серьезно, избегайте этого любой ценой, это небезопасно, и поддерживать это заноза в заднице.

Преимущества:

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

Недостатки:

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

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

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

Даже если есть некоторые компромиссы, связанные с безопасностью, когда дело доходит до переменных или файлов среды, я не думаю, что безопасность была основной движущей силой этой рекомендации. Помните, что авторы 12factor.net также (или были?) Разработчики Heroku PaaS. Привлечение всех к использованию переменных среды, вероятно, немного упростило их разработку. В разных форматах и ​​расположениях конфигурационных файлов так много разнообразия, что им было бы сложно поддерживать их все. Переменные среды легко сравнивать.

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

Разработчик A: «А, этот секретный пользовательский интерфейс конфигурационного файла слишком загроможден! Неужели нам действительно нужен раскрывающийся список, который переключается между json, xml и csv?»

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

Разработчик A: «На самом деле для этого есть несколько веских причин, связанных с безопасностью. Переменные среды, вероятно, не будут случайно проверены в системе контроля версий».

Разработчик Б: «Разве вы не устанавливаете переменные среды с помощью сценария, запускающего демон, или файла конфигурации?»

Разработчик A: «Не в Heroku! Мы заставим их вводить их в пользовательский интерфейс».

Разработчик Б: «Ой, смотри, только что сработало мое доменное имя для 12factor.net».1


1: source: выдумано.

TL; DR

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

Внеполосная конфигурация: отделение секретов от исходного кода

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

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

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

Улучшение разделения: серверы, приложения и роли

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

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

Размышления о безопасности

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

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

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

Лично я бы не рекомендовал устанавливать переменные среды в .bashrc как они становятся видимыми для все процессы, запускаемые оболочкой, но для установки их на уровне демона / супервизора (сценарий init / rc, конфигурация systemd), чтобы их объем был ограничен тем, где это необходимо.

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

Еще одно соображение - конвейеры CI / CD - поскольку код проходит разные окружающая среда (например, dev, test / qa, staging, production) параметры среды (зоны развертывания, сведения о подключении к базе данных, учетные данные, IP-адреса, доменные имена и т. д.) лучше всего настраиваются специальными инструментами / фреймворками управления конфигурацией и используются приложением процессы из окружения (в DRY, пишите один раз, запускайте где угодно). Традиционно, когда разработчики, как правило, решают эти операционные проблемы, они, как правило, регистрируют файлы конфигурации или шаблоны помимо кода, а затем добавляют обходные пути и другие сложности, когда меняются эксплуатационные требования (например, появляются новые среды / развертывание / сайты, масштабируемость / безопасность взвешивание, множественные функциональные ветки - и внезапно появляются вручную свернутые сценарии развертывания для управления / искажения множества профилей конфигурации) - эта сложность отвлекает и накладные расходы, лучше всего управляемые вне кода с помощью специальных инструментов.

  • Env-vars упрощают настройку / сложность в масштабе.
  • Env-vars передают операционную конфигурацию напрямую команде, ответственной за без кода связанные аспекты приложения единым (если не стандартным) необязательным способом.
  • Env-vars поддерживают замену процессов master / supervisor (например, god, monit, supervisord, sysvinit, systemd и т. Д.), Которые поддерживают приложение - и, конечно, даже систему развертывания (ОС, образы контейнеров и т. Д.) Или т. Д. В качестве рабочих требований. развиваться / меняться. В то время как каждая языковая среда в настоящее время имеет своего рода среду выполнения, она, как правило, хуже с точки зрения эксплуатации, больше подходит для сред разработки и / или увеличивает сложность в многоязычных / многофреймовых производственных средах.

Для производства я предпочитаю устанавливать env-vars приложения в EnvironmentFile Такие как/etc/default/myapplication.conf который развертывается управлением конфигурацией и доступен для чтения только root такой, что systemd (или что-то еще в этом отношении) может порождать приложение под выделенным Лишение прав пользователя системы в Частная группа. При поддержке выделенных групп пользователей для ops и sudo - эти файлы по умолчанию не читаются. Это 12-факторная совместимость, поддерживающая все достоинства Dev + Ops, плюс все преимущества достойной безопасности, в то же время позволяя разработчикам / тестерам добавлять свои собственные файлы EnvironmentFiles в среды dev / qa / test.

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

Веб-приложения Azure предоставляют возможность использовать этот шаблон, и он работает очень хорошо.

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