Передача секретов в контейнер Docker

26

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

PrestonM
источник
Хасикорп хранилище
030

Ответы:

23

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

1 - переменные среды

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

2 - Установленные объемы

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

3 - выборка из секретного магазина

Как упоминалось в @ 030, вы можете использовать Hashicorp Vault (или «Amazon Secrets Manager», или любую другую подобную службу).
Ваше приложение или дополнительное приложение могут напрямую получать секреты, в которых оно нуждается, без необходимости конфигурирования контейнера Docker. Этот метод позволит вам использовать динамически создаваемые секреты (очень привлекательная особенность таких систем) и не нужно беспокоиться о секретах, которые можно просматривать из файловой системы или проверять переменные env контейнера docker.

Личное мнение

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

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

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

Личное мнение (обновление)

Прекрасный комментарий Пер @ Дирка ( Передача секретов в контейнер Docker ), есть очень веский аргумент для того, чтобы расставить приоритеты в секретном хранилище, а не в ENV, из-за нежелания их утечки.

BoomShadow
источник
2
Это способствует силосам. DevOps делает вещи вместе, а не бросает их через стену.
030
2
Код должен быть изолирован от компонентов инфраструктуры. Реальные люди могут кодировать как автоматизацию инфраструктуры, так и базу кода приложения, но сами задачи должны быть отдельными. Я вижу, что последнее предложение моего первоначального ответа было отстранением от разработчиков, людей. Это является ошибкой. Я отредактирую это, чтобы быть более ясным.
BoomShadow
7
Ввод секретов в переменные окружения предлагает различные возможности для их утечки. Несколько примеров: Каждый, у кого есть доступ к демону Docker на машине, на которой запущен контейнер, может увидеть их с помощью команд inspectили exec. Переменные среды часто сбрасываются stdoutв файлы журналов или в них при работе в каком-либо режиме отладки. Все порожденные дочерние процессы могут читать и выставлять их, которые могут быть вне вашего контроля. Более подробная информация, например, здесь: diogomonica.com/2017/03/27/…
Дирк
1
Я тоже бьюсь над этим вопросом. Вещь, которую я не понимаю, - даже если вы используете хранилище учетных данных для защиты своих секретов, вы все равно должны пройти аутентификацию, чтобы получить доступ к этому хранилищу, а это, вероятно, требует некоторого секрета. То же относится и к использованию защищенного паролем файла KeyStore. Всегда ли мы застряли с передачей хотя бы «мета-учетных данных» в среде?
Wheezil
1
@ Пока мета-учетные данные легче защитить, чем многие специальные учетные данные. Вы можете часто и автоматически поворачивать метаданные. метаданные могут передаваться в хранилище, которое находится на защищенном хосте, и могут иметь такие вещи, как белый список ip, так что оно принимает подключения только от производственных подсетей. Вы также можете убедиться, что хранилище использует шифрование в состоянии покоя и шифрование в полете, взаимное закрепление TSL и сертификатов, а также все другие передовые практики, которые делают вещи более безопасными.
simbo1905
1

Есть еще один вариант, использующий трубу:

docker run -d -i --name $n alpine sh -c 'read A; echo "[$A]"; exec some-server'
docker exec -i $n sh -c 'cat > /proc/1/fd/0' <<< _a_secret_

Сначала создайте демон docker с -iпомощью команды, которая read Aбудет зависать в ожидании ввода от /proc/1/fd/0; Затем выполните вторую команду docker, прочитав секрет из stdin и перенаправив на последний процесс зависания.

Джеймс З.М. Гао
источник