Рекомендации DevOps на https://12factor.net/config Предлагаем поместить секреты веб-сайта (пароли к базе данных, ключи API и т. д.) в переменные среды. Какие преимущества дает это вместо использования текстовых файлов (JSON, XML, YAML, INI или подобных), игнорируемых системой контроля версий?
Мне гораздо проще скопировать файл конфигурации с секретами, чем обрабатывать переменные среды в .bash_profile и конфигурации веб-сервера. Я что-то упускаю?
Автор перечисляет их рассуждения, хотя они немного не совпадают. Их основной аргумент заключается в том, что легко случайно проверить файл конфигурации, и что файлы конфигурации имеют разные форматы и могут быть разбросаны по системе (все три из которых в лучшем случае являются посредственными аргументами для конфигурации, связанной с безопасностью, такой как токены аутентификации и учетные данные).
Исходя из моего собственного опыта, у вас, по сути, есть следующие три варианта с соответствующими преимуществами и недостатками:
При таком подходе вы должны в идеале изолировать их от самого репозитория и убедиться, что они находятся за пределами области, в которой приложение хранит свой контент.
Обычно это делается путем получения списка переменных и значений среды из сценария запуска, но в некоторых случаях они могут просто указать их в командной строке перед именем программы.
hidepid
вариант крепления для /proc
на LInux, например), но они не включены по умолчанию и не защищают от атак со стороны пользователя, владеющего процессом.Серьезно, избегайте этого любой ценой, это небезопасно, и поддерживать это заноза в заднице.
Переменные среды будут унаследованы каждым дочерним процессом веб-сервера. Это каждый сеанс, который подключается к серверу, и каждая программа, созданная им. Секреты будут автоматически открыты всем этим процессам.
Если вы храните секреты в текстовых файлах, они должны быть доступны для чтения серверному процессу, и, возможно, каждому дочернему процессу. Но по крайней мере программы должны пойти и найти их; они не предоставляются автоматически. Вы также можете запустить некоторые дочерние процессы под разными учетными записями и сделать секреты доступными для чтения только этим учетным записям. Например, suEXEC делает это в Apache.
Даже если есть некоторые компромиссы, связанные с безопасностью, когда дело доходит до переменных или файлов среды, я не думаю, что безопасность была основной движущей силой этой рекомендации. Помните, что авторы 12factor.net также (или были?) Разработчики Heroku PaaS. Привлечение всех к использованию переменных среды, вероятно, немного упростило их разработку. В разных форматах и расположениях конфигурационных файлов так много разнообразия, что им было бы сложно поддерживать их все. Переменные среды легко сравнивать.
Не требуется большого воображения, чтобы угадать некоторые из разговоров, которые были между ними.
Разработчик A: «А, этот секретный пользовательский интерфейс конфигурационного файла слишком загроможден! Неужели нам действительно нужен раскрывающийся список, который переключается между json, xml и csv?»
Разработчик Б: «О, жизнь была бы такой грандиозной, если бы все использовали переменные среды для конфигурации приложения».
Разработчик A: «На самом деле для этого есть несколько веских причин, связанных с безопасностью. Переменные среды, вероятно, не будут случайно проверены в системе контроля версий».
Разработчик Б: «Разве вы не устанавливаете переменные среды с помощью сценария, запускающего демон, или файла конфигурации?»
Разработчик A: «Не в Heroku! Мы заставим их вводить их в пользовательский интерфейс».
Разработчик Б: «Ой, смотри, только что сработало мое доменное имя для 12factor.net».1
1: source: выдумано.
Существует ряд причин для использования переменных среды вместо файлов конфигурации, но две из наиболее распространенных причин, которые следует упустить из виду, - это служебное значение внеполосная конфигурация и усиленное разделение между серверами, приложениями или ролями организации. Вместо того, чтобы представлять исчерпывающий список всех возможных причин, в своем ответе я обращаюсь только к этим двум темам и слегка касаюсь их последствий для безопасности.
Если вы храните все свои секреты в файле конфигурации, вам необходимо распространить эти секреты на каждый сервер. Это означает либо проверку секретов в системе контроля версий вместе с вашим кодом, либо наличие полностью отдельного репозитория или механизма распространения для секретов.
Шифрование ваших секретов на самом деле не помогает решить эту проблему. Все, что нужно сделать, - это устранить проблему одним разом, потому что теперь вам также нужно беспокоиться об управлении ключами и их распространении!
Короче говоря, переменные среды - это подход к перемещению данных для каждого сервера или приложения из исходного кода, когда вы хотите отделить разработку от операций. Это особенно важно, если вы опубликовали исходный код!
Конечно, у вас может быть файл конфигурации для хранения ваших секретов, но если вы храните секреты в исходном коде, у вас есть проблема специфичности. У вас есть отдельная ветка или репозиторий для каждого набора секретов? Как гарантировать, что правильный набор секретов попадет на нужные серверы? Или вы снижаете безопасность, имея «секреты», которые везде одинаковы (или читаются везде, если они все в одном файле), и, следовательно, представляют собой больший риск, если какие-либо меры безопасности системы не работают?
Если вы хотите иметь уникальные секреты на каждом сервере или для каждого приложения, переменные среды решают проблему управления множеством файлов. Если вы добавляете новый сервер, приложение или роль, вам не нужно создавать новые файлы или обновлять старые: вы просто обновляете среду рассматриваемой системы.
Хотя подробное исследование безопасности ядра / памяти / файлов выходит за рамки этого ответа, стоит отметить, что правильно реализованные системные переменные среды не менее безопасны, чем «зашифрованные» секреты. В любом случае целевая система по-прежнему должна хранить дешифрованный секрет в памяти по адресу некоторые точка, чтобы использовать его.
Также стоит отметить, что когда значения хранятся в энергозависимой памяти на данном узле, на диске нет файла, который можно было бы скопировать и атаковать в автономном режиме. Обычно это считается преимуществом перед секретами в памяти, но, конечно, не окончательно.
Проблема переменных среды и других методов управления секретами на самом деле больше связана с безопасностью и удобством использования. компромиссы чем это об абсолютных. Ваш пробег может отличаться.
Лично я бы не рекомендовал устанавливать переменные среды в .bashrc
как они становятся видимыми для все процессы, запускаемые оболочкой, но для установки их на уровне демона / супервизора (сценарий init / rc, конфигурация systemd), чтобы их объем был ограничен тем, где это необходимо.
Там, где операциями управляют отдельные группы, переменные среды обеспечивают простой интерфейс для операций по настройке среды для приложения без необходимости знать о файлах / форматах конфигурации и / или прибегать к изменению их содержимого. Это особенно верно в многоязычных / мультифреймворковых настройках, когда операционные группы могут выбирать систему развертывания (ОС, процессы супервизора) в зависимости от эксплуатационных потребностей (простота развертывания, масштабируемость, безопасность и т. Д.).
Еще одно соображение - конвейеры CI / CD - поскольку код проходит разные окружающая среда (например, dev, test / qa, staging, production) параметры среды (зоны развертывания, сведения о подключении к базе данных, учетные данные, IP-адреса, доменные имена и т. д.) лучше всего настраиваются специальными инструментами / фреймворками управления конфигурацией и используются приложением процессы из окружения (в DRY, пишите один раз, запускайте где угодно). Традиционно, когда разработчики, как правило, решают эти операционные проблемы, они, как правило, регистрируют файлы конфигурации или шаблоны помимо кода, а затем добавляют обходные пути и другие сложности, когда меняются эксплуатационные требования (например, появляются новые среды / развертывание / сайты, масштабируемость / безопасность взвешивание, множественные функциональные ветки - и внезапно появляются вручную свернутые сценарии развертывания для управления / искажения множества профилей конфигурации) - эта сложность отвлекает и накладные расходы, лучше всего управляемые вне кода с помощью специальных инструментов.
Для производства я предпочитаю устанавливать env-vars приложения в EnvironmentFile Такие как/etc/default/myapplication.conf
который развертывается управлением конфигурацией и доступен для чтения только root
такой, что systemd
(или что-то еще в этом отношении) может порождать приложение под выделенным Лишение прав пользователя системы в Частная группа. При поддержке выделенных групп пользователей для ops
и sudo
- эти файлы по умолчанию не читаются. Это 12-факторная совместимость, поддерживающая все достоинства Dev + Ops, плюс все преимущества достойной безопасности, в то же время позволяя разработчикам / тестерам добавлять свои собственные файлы EnvironmentFiles в среды dev / qa / test.
С точки зрения разработчика, хранение данных конфигурации в переменных среды упрощает развертывание в различных средах - разработке, контроле качества и производстве - и освобождает разработчиков от необходимости беспокоиться о развертывании неправильного файла конфигурации.
Веб-приложения Azure предоставляют возможность использовать этот шаблон, и он работает очень хорошо.
В дополнение к этому, он сохраняет эти потенциально конфиденциальные данные вне контроля источника. Игнорирование этих файлов из системы управления версиями на самом деле невозможно (по крайней мере, в .NET), потому что в этих файлах также присутствует много необходимой стандартной конфигурации.