Недавно я экспериментировал с Docker над созданием некоторых сервисов, с которыми можно поиграться, и одна вещь, которая меня постоянно раздражает, это вставка паролей в Dockerfile. Я разработчик, поэтому хранение паролей в исходном коде похоже на удар по лицу. Должно ли это быть проблемой? Есть ли хорошие соглашения о том, как обрабатывать пароли в Dockerfiles?
162
Ответы:
Определенно это проблема. Файлы Docker обычно регистрируются в репозиториях и передаются другим людям. Альтернативой является предоставление любых учетных данных (имена пользователей, пароли, токены и т. Д.) В качестве переменных среды во время выполнения . Это возможно с помощью
-e
аргумента (для отдельных переменных в CLI) или--env-file
аргумента (для нескольких переменных в файле) дляdocker run
. Прочитайте это для использования среды с docker-compose.Использование
--env-file
, безусловно, более безопасный вариант, так как это защищает от секретов, отображаемых вps
журналах или в журналах, если таковые используютсяset -x
.Однако env vars также не особенно безопасны. Они видны через
docker inspect
, и, следовательно, они доступны любому пользователю, который может запускатьdocker
команды. (Конечно, любой пользователь, имеющий доступ кdocker
хосту, также имеет права root ).Мой предпочтительный шаблон - использовать скрипт-обертку в качестве
ENTRYPOINT
илиCMD
. Сценарий-оболочка может сначала импортировать секреты из внешнего местоположения в контейнер во время выполнения, а затем запустить приложение, предоставив секреты. Точная механика этого зависит от вашей среды выполнения. В AWS вы можете использовать комбинацию ролей IAM, службы управления ключами и S3 для хранения зашифрованных секретов в корзине S3. Что-то вроде HashiCorp Vault или credstash - это еще один вариант.AFAIK Не существует оптимального шаблона для использования конфиденциальных данных в процессе сборки. На самом деле, у меня есть вопрос по этой теме. Вы можете использовать docker-squash для удаления слоев с изображения. Но для этого в Docker нет встроенной функциональности.
Вы можете найти полезные комментарии к конфигурации в контейнерах .
источник
.config
файл.docker inspect
.docker inspect
. Если злоумышленник уже может выполнить sudo, выхватывание вашего пароля из проверки докера, вероятно, занимает довольно мало места в вашем списке вещей, которые теперь могут пойти не так. Эта конкретная деталь кажется мне приемлемым риском.Наша команда избегает ввода учетных данных в репозитории, так что это означает, что они не допускаются
Dockerfile
. Нашей лучшей практикой в приложениях является использование кредитов из переменных среды.Мы решаем для этого, используя
docker-compose
.Внутри
docker-compose.yml
вы можете указать файл, который содержит переменные среды для контейнера:Убедитесь в том , чтобы добавить
.env
в.gitignore
, а затем установить учетные данные в пределах.env
файла , как:Храните
.env
файл локально или в безопасном месте, где остальная часть команды сможет его взять.Смотрите: https://docs.docker.com/compose/environment-variables/#/the-env-file
источник
.gitignore
чтобы.env
файл с конфиденциальной информацией не регистрировался в GitHub. Я почти уверен, что это не сработает, если вы добавите его.dockerignore
.env
файл и не выполняю развертывание на сервере в помещении, вы предлагаете снова создать.env
файл на сервере вручную?Docker сейчас (версия 1.13 или 17.06 и выше) имеет поддержку для управления секретной информацией. Вот обзор и более подробная документация
Подобная особенность существует в kubernetes и DCOS
источник
docker secret create
создать секретdocker secret inspect
: показать подробную информацию о секретеdocker secret ls
: просмотреть все секретыdocker secret rm
: удалить конкретный--secret
флаг секрета дляdocker service create
: создать секрет во время создания сервиса--secret-add
и--secret-rm
флаги дляdocker service update
: обновить значение секрета или удалить секрет во время обновления сервиса. Секреты Docker в покое защищены на узлах менеджера и предоставляются рабочим узлам при запуске контейнера.Никогда не следует добавлять учетные данные в контейнер, если вы не согласны с передачей кредитов тому, кто сможет загрузить изображение. В частности, выполнение и
ADD creds
позжеRUN rm creds
не является безопасным, поскольку файл creds остается в конечном изображении на уровне промежуточной файловой системы. Любой, имеющий доступ к изображению, может легко извлечь его.Типичное решение, которое я видел, когда вам нужны кредиты для проверки зависимостей, например, использование одного контейнера для создания другого. То есть обычно у вас есть базовая среда сборки в базовом контейнере, и вам нужно вызывать ее для сборки контейнера приложения. Поэтому простое решение - добавить исходный код приложения, а затем
RUN
команды сборки. Это небезопасно, если вам нужны кредиты в этомRUN
. Вместо этого вы помещаете свой источник в локальный каталог, запускаете (как вdocker run
) контейнер для выполнения шага сборки, когда локальный каталог источника монтируется как том, а кредиты либо внедряются, либо монтируются как другой том. После того, как шаг сборки завершен, вы создаете свой окончательный контейнер, простоADD
используя локальный исходный каталог, который теперь содержит встроенные артефакты.Я надеюсь, что Docker добавляет некоторые функции, чтобы упростить все это!
Обновление: похоже, что в будущем будет использоваться метод построения вложенных сборок. Вкратце, файл dockerfile будет описывать первый контейнер, который используется для построения среды выполнения, а затем вторую сборку вложенного контейнера, которая может собрать все части в конечный контейнер. Таким образом, материал во время сборки не находится во втором контейнере. Это Java-приложение, в котором вам нужен JDK для сборки приложения, но только JRE для его запуска. Обсуждается ряд предложений, лучше всего начать с https://github.com/docker/docker/issues/7115 и перейти по некоторым ссылкам для получения альтернативных предложений.
источник
Альтернативой использованию переменных среды, которые могут стать беспорядочными, если их много, является использование томов, чтобы сделать каталог на хосте доступным в контейнере.
Если вы поместите все свои учетные данные в виде файлов в эту папку, тогда контейнер сможет читать файлы и использовать их по своему усмотрению.
Например:
Многие программы могут считывать свои учетные данные из отдельного файла, поэтому таким образом вы можете просто указать программе один из файлов.
источник
решение только во время выполнения
docker-compose также предоставляет решение не в режиме роя (начиная с v1.11: секреты с использованием bind mounts ).
Секреты смонтированы в виде файлов ниже с
/run/secrets/
помощью docker-compose. Это решает проблему во время выполнения (запуск контейнера), но не во время сборки (сборка образа), поскольку/run/secrets/
не монтируется во время сборки. Кроме того, это поведение зависит от запуска контейнера с docker-compose.Пример:
Dockerfile
докер-compose.yml
Чтобы построить, выполните:
Дальнейшее чтение:
источник
В Docker v1.9 вы можете использовать инструкцию ARG для извлечения аргументов, переданных из командной строки, в образ при действии сборки . Просто используйте флаг --build-arg . Таким образом, вы можете избежать сохранения явного пароля (или другой разумной информации) в Dockerfile и передавать его на лету.
источник: https://docs.docker.com/engine/reference/commandline/build/ http://docs.docker.com/engine/reference/builder/#arg
Пример:
Dockerfile
команда построения образа
во время сборки распечатать
Надеюсь, поможет! До свидания.
источник
--build-arg var=secret
для передачи закрытого ключа SSH в образ, обоснование не задокументировано. Кто-нибудь может это объяснить?docker history
выставляетbuild-arg
/ARG
переменные. Можно вытащить любое изображение, проверить его и увидеть все секреты, переданные во время сборки, в качестве параметраbuild-arg
/ARG
.Мой подход, кажется, работает, но, вероятно, наивен. Скажи мне, почему это неправильно.
ARG, установленные во время сборки докера, выставляются подкомандой history, поэтому идти туда не нужно. Однако при запуске контейнера переменные среды, указанные в команде run, доступны для контейнера, но не являются частью образа.
Итак, в Dockerfile выполните настройку, которая не использует секретные данные. Установите CMD что-то вроде
/root/finish.sh
. В команде run используйте переменные среды для отправки секретных данных в контейнер.finish.sh
по существу использует переменные для завершения задач сборки.Чтобы упростить управление секретными данными, поместите их в файл, который загружается программой Docker, запущенной с
--env-file
коммутатором. Конечно, держите файл в секрете..gitignore
и тому подобное.Для меня
finish.sh
работает программа на Python. Он проверяет, чтобы убедиться, что он не запускался раньше, а затем завершает настройку (например, копирует имя базы данных в Djangosettings.py
).источник
Появилась новая команда docker для управления «секретами». Но это работает только для скоплений роя.
источник
Методология приложение 12-фактор говорит, что любая конфигурация должна храниться в переменных окружения.
Docker compose может выполнять подстановку переменных в конфигурации, так что он может использоваться для передачи паролей от хоста к докеру.
источник
Хотя я полностью согласен, простого решения не существует. Там продолжает быть единственная точка отказа. Либо dockerfile, etcd и так далее. У Apcera есть план, который выглядит как кореш - двойная аутентификация. Другими словами, два контейнера не могут общаться, если нет правила конфигурации Apcera. В их демонстрации uid / pwd был в открытом виде и не мог быть повторно использован, пока администратор не настроил связь. Однако, чтобы это работало, это, вероятно, означало исправление Docker или, по крайней мере, сетевого плагина (если есть такая вещь).
источник