Докер и защита паролей



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

949   11  

11 ответов:

безусловно, это вызывает беспокойство. Dockerfiles обычно проверяются в репозиториях и совместно с другими людьми. Альтернативой является предоставление любых учетных данных (имена пользователей, пароли, токены, что-либо чувствительное) переменные среды во время выполнения. Это возможно через -e аргумент (для отдельных vars на CLI) или --env-file аргумент (для нескольких переменных в файле) в docker run.

используя --env-file определенно более безопасный вариант, так как это защищает от секретов, появляющихся в ps или в журналах, если используется set -x.

, переменные окружения не особо безопасно, либо. Они видны через docker inspect, и, следовательно, они доступны для любого пользователя, который может работать docker команды. (Конечно, любой пользователь, который имеет доступ к docker на хосте тоже имеет корень в любом случае.)

мой предпочтительный шаблон-использовать сценарий обертки в качестве ENTRYPOINT или CMD. Сценарий-оболочка может сначала импортировать секреты из внешнего расположения в контейнер во время выполнения, а затем выполнить приложение, предоставляя секреты. Точная механика этого зависит от вашей среды выполнения. В AWS, вы можете использовать комбинацию ролей в IAM, в Служба Управления Ключами, и S3 для хранения зашифрованных секретов в корзине S3. Что-то вроде HashiCorp Хранилище или credstash это еще один вариант.

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

вы можете найти shykes комментарии к конфигурации в контейнерах полезное.

наша команда избегает помещать учетные данные в репозитории, так что это означает, что они не допускаются в Dockerfile. Наша лучшая практика в приложениях-использовать creds из переменных среды.

мы решаем для этого с помощью docker-compose.

внутри docker-compose.yml, вы можете указать файл, содержащий переменные среды для контейнера:

 env_file:
- .env

добавьте .env до .gitignore, затем установите учетные данные в .env файл например:

SOME_USERNAME=myUser
SOME_PWD_VAR=myPwd

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

см.:https://docs.docker.com/compose/environment-variables/#/the-env-file

Docker now (версия 1.13 или 17.06 и выше) поддерживает управление секретной информацией. Вот это обзор и более подробно документация

аналогичная функция существует в kubernetes и DCOS

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

типичное решение, которое я видел, когда вам нужны creds для проверки зависимостей, и это использовать один контейнер для создания другого. Т. е., как правило, у вас есть некоторая среда сборки в базовом контейнере, и вам нужно вызвать ее для создания контейнера приложения. Таким образом, простое решение состоит в том, чтобы добавить свой источник приложения, а затем RUN команды строить. Это небезопасно, если вам нужно удостоверение в том, что RUN. Вместо этого вы помещаете свой источник в локальный каталог, запускаете (как в docker run) контейнер для выполнения шага сборки с локальным исходным каталогом, смонтированным как Том, а creds либо вводится, либо монтируется как другой том. После завершения этапа сборки вы создаете свой последний контейнер просто ADDing локальный исходный каталог, который теперь содержит встроенные артефакты.

Я надеюсь, что докер добавляет некоторые функции, чтобы упростить все это!

Update: похоже, что метод, идущий вперед, будет иметь вложенные сборки. Короче говоря, dockerfile описывает первый контейнер, который используется для создания среды выполнения, а затем вторую вложенную сборку контейнера, которая может собрать все части в последний контейнер. Таким образом, время сборки не находится во втором контейнере. Это приложение Java, где вам нужен JDK для создания приложения, но только JRE для его запуска. Есть ряд предложений, которые обсуждаются, лучше всего начать с https://github.com/docker/docker/issues/7115 и перейдите по некоторым ссылкам для альтернативных предложений.

С настройки В1.9 можно использовать ARG инструкция чтобы извлечь аргументы, переданные командной строкой в изображение на создать действие. Просто используйте -- build-arg флаг. Таким образом, вы можете избежать сохранения явного пароля (или другой разумной информации) на Dockerfile и передавать их на лету.

источник:https://docs.docker.com/engine/reference/commandline/build/ http://docs.docker.com/engine/reference/builder/#arg

пример:

Dockerfile

FROM busybox
ARG user
RUN echo "user is $user"

команды построения изображения

docker build --build-arg user=capuccino -t test_arguments -f path/to/dockerfile .

во время сборки он печатает

$ docker build --build-arg user=capuccino -t test_arguments -f ./test_args.Dockerfile .

Sending build context to Docker daemon 2.048 kB
Step 1 : FROM busybox
 ---> c51f86c28340
Step 2 : ARG user
 ---> Running in 43a4aa0e421d
 ---> f0359070fc8f
Removing intermediate container 43a4aa0e421d
Step 3 : RUN echo "user is $user"
 ---> Running in 4360fb10d46a
**user is capuccino**
 ---> 1408147c1cb9
Removing intermediate container 4360fb10d46a
Successfully built 1408147c1cb9

надеюсь, что это помогает! Пока.

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

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

например:

$ echo "secret" > /root/configs/password.txt
$ docker run -v /root/configs:/cfg ...

In the Docker container:

# echo Password is `cat /cfg/password.txt`
Password is secret

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

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

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

Итак, в файле Dockerfile выполните настройку, которая не включает секретные данные. Установите CMD чего-то вроде /root/finish.sh. В команде запуска, использования окружающей среды переменные для отправки секретных данных в контейнер. finish.sh использует переменные по существу для завершения задач сборки.

чтобы упростить управление секретными данными, поместите их в файл, который загружается docker run с помощью --env-file переключатель. Конечно, держите файл в секрете. .gitignore и так далее.

для меня finish.sh запускает программу Python. Он проверяет, чтобы убедиться, что он не работал раньше, а затем завершает установку (например, копирует имя базы данных в Django's settings.py).

хотя я полностью согласен, что нет простого решения. По-прежнему существует одна точка отказа. Либо dockerfile, etcd и так далее. Apcera имеет план, который выглядит как sidekick-двойная аутентификация. Другими словами, два контейнера не могут разговаривать, если нет правила конфигурации Apcera. В их демо uid / pwd был в чистом виде и не мог быть повторно использован, пока администратор не настроил связь. Для этого, однако, это, вероятно, означало исправление Docker или, по крайней мере, сети плагин (если есть такая вещь).

существует новая команда docker [1] для управления" секретами", но это работает только для кластеров Роя.

docker service create
--name my-iis
--publish target=8000,port=8000
--secret src=homepage,target="\inetpub\wwwroot\index.html"
microsoft/iis:nanoserver 

[1]https://docs.docker.com/engine/swarm/secrets/

решение только во время выполнения

docker-compose также предоставляет решение без Роя (начиная с версии 1.1: секреты с помощью привязки монтирует).

секреты монтируются в виде файлов ниже /run/secrets/ по docker-compose. Это решает проблему во время выполнения (запуск контейнера), но не во время сборки (создание образа), потому что /run/secrets/ не монтируется во время сборки. Кроме того, это поведение зависит от запуска контейнера с помощью докер-сочинять.


пример:

Dockerfile

FROM alpine
RUN cat /run/secrets/password
CMD sleep inifinity

docker-compose.в формате YML

version: '3.1'
services:
  app:
    build: .
    secrets:
      - password

secrets:
  password:
    file: password.txt

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

docker-compose up -d

читайте далее:

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

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

Comments

    Ничего не найдено.