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

24

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

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

Аидас Бендорайтис
источник
1
Теоретически легче читать файл, чем память, поэтому вы можете считать поверхность атаки большей, а сложность - меньшей.
Florin Asăvoaie
Основное правило моего разработчика заключается в том, что хранить настройки в переменных окружения лучше всего только в докероподобных средах. Вне контейнерных виртуальных машин он одобряет / предпочитает все остальные пункты 12factor.net и использование файлов конфигурации. Никому из нас не нравилась небезопасная природа переменных среды при регулярном развертывании сервера.
Кори Огберн

Ответы:

21

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

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

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

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

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

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

Недостатки:

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

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

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

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

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

Недостатки

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

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

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

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

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

Недостатки:

  • Как и переменные среды, в большинстве систем легко читать командную строку другого процесса.
  • Чрезвычайно утомительно обновлять конфигурацию.
  • Установлено жесткое ограничение на длину конфигурации (иногда до 1024 символов).
Остин Хеммелгарн
источник
1
Один немаловажный момент - автоматическая (пере) загрузка сервера без необходимости вручную
вводить
7
В большинстве систем UNIX вы можете читать практически любые переменные среды процессов без каких-либо значительных привилегий. - Можете ли вы расширить это? Файл / proc / #### / environment доступен для чтения только владельцу, поэтому вам нужно иметь права root или иметь sudo.
rrauenza
Я думаю, что некоторые из этих тенденций конфигурации env также возникли в таких вещах, как docker, где вы используете стандартный контейнер и конфигурируете его, передавая переменные env в контейнер.
rrauenza
@rrauenza Право собственности на процесс не является значительной привилегией, если вы не очень хорошо разбираете вещи по учетным записям, и вам на самом деле нужна только возможность CAP_SYS_ADMIN (которая неявно имеет root), если вы не владелец. Кроме того, в отношении переменных среды вы, вероятно, правы, но это маргинальный дизайн даже с Docker.
Остин Хеммельгарн
3
Я согласен с точкой зрения @rrauenza. Ответ довольно велик, но я хотел бы уточнить, как именно вы можете читать практически любые переменные среды процессов без каких-либо значительных привилегий . Что касается « а вам на самом деле нужна только возможность CAP_SYS_ADMIN (которая неявно имеет root) ...» хорошо, если у злонамеренного агента есть привилегии root, дальнейшее обсуждение излишне, и CAP_SYS_ADMIN также может быть привилегией root (см. Man7.org/linux /man-pages/man7/capabilities.7.html , CAP_SYS_ADMIN и заметки для разработчиков ядра )
Nubarke
13

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

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

Эндрю Шульман
источник
1
«Это каждый сеанс, который подключается к серверу» - вводящее в заблуждение утверждение. Вы не можете открыть сеанс http на сервере и получить доступ к его переменным среды, а также не можете войти в оболочку на этом сервере и получить их, если у вас нет прав root или вы не владеете процессом веб-сервера.
Сегфо
Каждый процесс, порожденный веб-сервером, наследует свою среду, если вы не предпримете активных действий в противном случае. HTML-страница не имеет возможности использовать эту информацию, но скрипт имеет.
Андрей Шульман
Несмотря на правильность, этот ответ может быть связан с некоторыми исправлениями / уступками, особенно в отношении термина сессий . При первом прочтении, кажется, что использование переменных окружения выглядит плохо, почти чтобы предложить возможности раскрытия информации внешнему клиенту. Кроме того, уступка, сравнимая с suexec, может быть сделана для ограниченной настройки env-vars, например, настройка env-vars для каждого процесса (а-ля MYVAR=foo /path/to/some/executable) ограничивает распространение только процессом и его дочерними элементами - и, где это необходимо, главные демоны могут выполнять очистку / сброс / изменение. среда дочерних процессов.
Шаломб
2

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

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

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

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

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

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

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

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


1 : источник: составлен.

Segfault
источник
1

TL; DR

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

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

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

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

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

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

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

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

Прощальные мысли о безопасности

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

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

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

CodeGnome
источник
2
Это не убедительно, потому что все недостатки, которые вы упоминаете для файлов конфигурации, также применимы к переменным среды. Переменные среды являются данными конфигурации. Они волшебным образом не устанавливают себя. Они должны быть распределены по каждой системе, и для их настройки необходимо использовать какой-то механизм конфигурации .
jpaugh
@jpaugh Вы спорите с соломенным человеком и нападаете на то, чего я никогда не говорил. Проблемы, которые я решаю, это внешняя конфигурация и разделение данных. Как четко объяснено, вы можете делать эти вещи любым удобным для вас способом. Если вы предпочитаете, вы можете опубликовать свои секреты вместе с вашим кодом публично на GitHub, но это, безусловно, кажется неразумным в общем случае. Однако только вы можете определить компромиссы, необходимые для правильной работы вашей системы в рамках данной модели угрозы.
CodeGnome
2
Все ваши пункты верны, за исключением того, что это относится к переменным среды так же, как и к любым другим данным конфигурации. Если вы храните переменные среды в файлах, вы можете зафиксировать их; и если вы отправляете их вне группы, это легче сделать в файле, чем просто печатать их. Но если вы предпочитаете вводить их, почему бы не напечатать вместо этого объект JSON и прочитать его на stdin? Это на самом деле более безопасно, чем командная строка.
jpaugh
1

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

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

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

  • 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 plus и обладает всеми преимуществами достойной безопасности, позволяя при этом разработчикам / тестировщикам добавлять свои собственные файлы EnvironmentFiles в среде dev / qa / test.

shalomb
источник
0

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

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

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

Дерек Гусофф
источник