Moby: Секреты: лучшие практики написания, что можно и чего нельзя делать, дорожная карта

Созданный на 26 мая 2015  ·  203Комментарии  ·  Источник: moby/moby

Обработка секретов (паролей, ключей и т. Д.) В Docker - это повторяющаяся тема. Многие запросы на вытягивание были «перехвачены» людьми, которые хотели (неправильно) использовать определенную функцию для обработки секретов.

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

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

Особенности / хаки, которые (неправильно) используются для секретов

Этот список, вероятно, неполный, но стоит упомянуть

  • Переменные среды . Вероятно, наиболее часто используемый, потому что он является частью «12-факторного приложения» . Переменные среды не приветствуются, потому что они есть;

    • Доступен любым процессам в контейнере, поэтому легко "протекает"

    • Сохраняется в промежуточных слоях изображения и отображается в docker inspect.

    • Совместно с любым контейнером, связанным с контейнером

  • Переменные среды времени сборки (https://github.com/docker/docker/pull/9176, https://github.com/docker/docker/pull/15182). Переменные среды времени сборки не предназначены для обработки секретов. Из-за отсутствия других возможностей люди планируют использовать их для этого. Чтобы не создать _впечатление_, что они подходят для секретов, было решено сознательно не шифровать эти переменные в процессе.
  • Отметьте .. Сквош / Сглаживание слоев . (https://github.com/docker/docker/issues/332, https://github.com/docker/docker/pull/12198, https://github.com/docker/docker/pull/4232, https://github.com/docker/docker/pull/12198, https://github.com/docker/docker/pull/4232, https : //github.com/docker/docker/pull/9591). Сжатие слоев приведет к удалению промежуточных слоев из окончательного изображения, однако секреты, используемые в этих промежуточных слоях, все равно останутся в кэше сборки.
  • Объемы . Некоторые люди IIRC смогли использовать тот факт, что тома воссоздаются для каждого шага сборки, что позволяет им хранить секреты. Я не уверен, что это действительно работает, и не могу найти ссылку на то, как это делается.
  • Создание контейнеров вручную . Пропустите использование Dockerfile и вручную создайте контейнер, зафиксировав результаты в образе.
  • Пользовательские хаки . Например, размещение секретов на сервере, curl сохранение секретов с последующим их удалением на одном уровне. (также см. https://github.com/dockito/vault)

Итак, что нужно?

  • Добавьте документацию о том, что можно и чего нельзя делать при работе с секретами; @diogomonica сделал несколько отличных замечаний в https://github.com/docker/docker/pull/9176#issuecomment -99542089
  • Опишите официально "одобренный" / одобренный способ обработки секретов, если это возможно, с использованием _current_ функций.
  • Предоставьте дорожную карту / дизайн для официальной обработки секретов, мы можем захотеть сделать это подключаемым, чтобы нам не пришлось заново изобретать колесо и использовать существующие предложения в этой области, например, Vault , Keywiz , Sneaker

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

@calavera разработала быстрое и грязное доказательство того, как для этого можно использовать новые Volume-Drivers (https://github.com/docker/docker/pull/13161); https://github.com/calavera/docker-volume-keywhiz-fs

Примечание. Переменные среды используются как стандарт де-факто для передачи конфигурации / настроек, включая секреты, в контейнеры. Сюда входят официальные образы на Docker Hub (например, MySQL , WordPress , PostgreSQL ). Эти изображения должны соответствовать новым «лучшим методам» при написании / внедрении.

По доброй традиции, вот несколько старых предложений по работе с секретами;

aresecurity statuneeds-attention

Самый полезный комментарий

Я знаю, что это не по теме, но кто-нибудь заметил, что эта проблема существует уже почти год! Завтра его юбилей. 👏

Все 203 Комментарий

ping @ewindisch @diogomonica @NathanMcCauley Это просто краткое описание . Не стесняйтесь изменять / обновлять описание, если считаете, что это необходимо :)

Это полезная информация:

https://github.com/hashicorp/vault/issues/165

Как это:

https://github.com/hashicorp/vault/issues/164

@ dreamcat4 есть некоторые планы по реализации универсального «секретного API», который позволит вам использовать либо Vault, либо Keywiz, либо you-name-it с Docker, но все одинаково. Это только ранняя мысль, поэтому потребуются дополнительные исследования.

@thaJeztah Ага. Извините, я не хочу никоим образом отвлекать от этих усилий / обсуждения. Я больше думаю, что, может быть, это тоже полезное упражнение (как часть этого более длительного процесса и пока мы ждем), чтобы увидеть, как далеко мы можем продвинуться прямо сейчас. Тогда это более ясно показывает другим ограничения и недостатки текущего процесса. Чего не хватает, и чего больше всего нужно было добавить, чтобы улучшить секреты.

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

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

@ dreamcat4 да, ты прав; в краткосрочной перспективе эти ссылки действительно полезны.

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

Спасибо! Думаю, это было в моем первоначальном описании, должно быть, я потерялся в процессе. Я добавлю пулю

Однако я не специалист по безопасности.

Я тоже, поэтому я «пингнул» специалистов по обеспечению безопасности; ИМО, это должно быть что-то написанное ими 😇

@thaJeztah отличное резюме. Я постараюсь ткнуть в это всякий раз, когда найду время.

@diogomonica, хотя и не связана _directly_, есть длинный открытый запрос функции для пересылки ключевого агента SSH во время сборки; https://github.com/docker/docker/issues/6396, учитывая количество комментариев, было бы неплохо подумать и об этом. (Если даже принять решение, можно / нужно это реализовать)

Предполагая, что вы можете монтировать тома как пользователь, отличный от root (я знаю, что это невозможно, но пошутите меня), будет ли это благоприятным подходом к хранению секретов в контейнерах?

Если это так, я бы выступил за альтернативу -v host_dir:image_dir которая предполагает использование контейнера только для данных и может выглядеть как -vc host_dir:image_dir (т.е. копия тома), в которой содержимое host_dir скопировано в том image_dir в контейнере только данных.

Затем мы могли бы выделить парадигму secure-data-only containers и разрешить шифрование этих томов.

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

Итак, у вас есть два Dockerfile:

  • Dockerfile.build (здесь вы просто копируете все свои секреты)
  • Dockerfile.dist (его нужно отправить в реестр)

Теперь мы можем построить наш дистрибутив следующим образом:

# !/bin/sh
docker build -t hello-world-build -f Dockerfile.build .
docker run hello-world-build >build.tar.gz 
docker build -t hello-world -f Dockerfile.dist ^

Ваши секреты в безопасности, так как вы никогда не нажимаете hello-world-build image.

Я рекомендую прочитать статью @jrslv для получения более подробной информации http://resources.codeship.com/ebooks/continuous-integration-continuous-delivery-with-docker

Спасибо, что поделились @kepkin !
Только что дочитал статью. Действительно лаконично!

Мне нравится идея экспортировать файлы и загружать их через отдельный Dockerfile. Это похоже на сжатие без "промежуточных слоев в кеше сборки".

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

@kepkin без обид, но в этом нет никакого смысла. Секреты определенно небезопасны, так как они находятся в тарболе, а тарбол ADD редактируется в производственный образ - даже если вы удалите тарбол без сжатия, он будет протекать на каком-то уровне.

@TomasTomecek, если я правильно понимаю пример, tarball - это не слои изображений, а просто двоичный файл, который был построен внутри контейнера сборки. См. Например; https://github.com/docker-library/hello-world/blob/master/update.sh (здесь нет никаких секретов, а просто простой пример контейнера сборки)

@TomasTomecek Я говорю о секретах построения образа Docker. Например, вам нужно передать ключ ssh для извлечения исходного кода из вашего частного репозитория GitHub. А tarball содержит только артефакты сборки, но не содержит ключа GitHub.

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

@TomasTomecek - именно так я и получаю артефакты.

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

Есть ли каноническая статья «Лучшие практики» - «Что можно делать в соответствии с« Что нельзя »» - которую вы все порекомендовали бы прочитать?

Стоит отметить (для всех, кто, как я, наткнулся на это), что Docker Compose поддерживает параметр env_file .

https://docs.docker.com/compose/compose-file/#env -file

Сам докер http://docs.docker.com/engine/reference/commandline/run/#set -environment-variables-e-env-env-file, но эти env-vars по-прежнему будут появляются в одних и тех же местах, так что не имеет значения "утечка"

@kepkin вот как я docker build :

# serve the ssh private key once over http on a private port.
which ncat
if [ "$?" = "0" ]; then
  ncat -lp 8000 < $HOME/.ssh/id_rsa &
else
  nc -lp 8000 < $HOME/.ssh/id_rsa &
fi
nc_pid=$!
docker build --no-cache -t bob/app .
kill $nc_pid || true

и внутри Dockerfile, где 172.17.0.1 - IP-адрес шлюза докеров:

RUN \
  mkdir -p /root/.ssh && \
  curl -s http://172.17.0.1:8000 > /root/.ssh/id_rsa && \
  chmod 600 /root/.ssh/id_rsa && chmod 700 /root/.ssh && \
  ssh-keyscan -t rsa,dsa github.com > ~/.ssh/known_hosts && \
  git clone --depth 1 --single-branch --branch prod [email protected]/app.git . && \
  npm i --production && \
  ... && \
  rm -rf /root/.npm /root/.node-gyp /root/.ssh

Если у кого-то есть что-то попроще, дайте нам знать.

Так каков текущий статус этого?

Все лето шли длинные цепочки разговоров, свидетельствующие о том, насколько распространена эта проблема. Это было подано в мае, и оно все еще открыто. Например, как мне установить пароль для Postgres?

@thaJeztah Что можно сделать, чтобы продвинуться вперед? Я полагаю, что на эту проблему обращают внимание многие во всех последующих проектах ... эй. https://github.com/rancher/rancher/issues/1269

Я думаю, что здесь делается _secret_: D

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

Некоторый актуальный контент по этой теме от k8s .

Что вы думаете об этом как о потенциальном способе решения секретов времени выполнения?
https://github.com/docker/docker/issues/19508

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

Некоторые из них, которые, как я видел, вызывают вполне обоснованные опасения, включают:

Учетные данные времени выполнения

  • Информация о пользователе / ​​пароле скоординирована между двумя контейнерами, которые разделяют link
  • Информацию легко сохранить вне вашего репозитория git
  • Информацию легко скрыть от ваших загруженных изображений (как насчет локальных контейнеров?)
  • Информацию легко сохранить вне .bash_history (возможно, слишком далеко?)
  • Некоторые приложения ожидают секреты как часть файла конфигурации, который содержит другую информацию.
  • Некоторые приложения ожидают секреты как переменную среды
  • Некоторые приложения позволяют

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

Учетные данные времени сборки

  • Проект построен из одного или нескольких частных репозиториев (например, package.json позволяет использовать URL-адреса git)
  • Builder может находиться за защищенным паролем прокси
  • Builder может использовать кеш, защищенный паролем
  • Конечный пользователь заботится только о рабочем изображении (т.е. они будут использовать pull или FROM, но никогда не docker build ).
  • Информацию легко скрыть от загружаемых изображений.

1-е редактирование:

Документация о том, что есть, а что нет в типичном образе, контейнере

  • Какие файлы попадают в образ (просто КОПИРОВАТЬ и ДОБАВИТЬ? Что-нибудь еще?)
  • Что docker-machine сохраняет после сборки образа (особенно boot2docker, но как насчет других?)
  • Как переменные среды и командной строки фиксируются в образе и где они фиксируются
  • Ожидания от PR-эмитентов относительно изменения такого поведения

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

Ключи API для любых json-сервисов.

Например (и это мой реальный вариант использования), сборка Docker компилирует программу, ключ API необходим для аутентификации меня и загрузки продуктов сборки на Bintray.com.

@ dreamcat4 Я мог бы быть далек от того, что вы говорите, но вот что:

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

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

Я пытался сказать об использовании ключей API в целом. Существует множество различных и разнообразных онлайн-сервисов JSON / rest, с которыми может потребоваться взаимодействие контейнера (либо во время сборки, либо во время выполнения) ... для которых требуются ключи API. Не обязательно конкретно относиться к сборке.

@dreamcat о, так токены

Да, я думаю, что эти два типа следует рассматривать по-разному с точки зрения оценки базового минимального уровня безопасности.

Токены API Auth часто бывают:

  • Не пароли
  • Может быть отозван
  • Некоторые (гораздо меньшее количество) предназначены для одноразового использования - выбросить. И, по сути, обесценить самих себя.
  • Часто службы API ограничены в своем объеме лишь подмножеством функций. (т. е. только для чтения или может запускать только определенное действие).

Пароли, как правило, бывают / часто бывают:

  • Для более полного доступа / контроля учетной записи.
  • После взлома может быть изменен злоумышленником на что-то другое (блокировка). Или вставлен другой бэкдор (например, модификация db других учетных записей, хранящихся в базе данных, в случае SQL).
  • Наличие пароля значительно повышает риск «повторного использования одного и того же пароля» среди других учетных записей. Ключи API Wheras, как правило, всегда уникальны и не используются ни для чего другого.

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

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

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

Например, мой ключ API bintray: он хранится в том же репозитории .git, что и мой Dockerfile. Таким образом, чтобы сохранить его в безопасности, он хранится в ЧАСТНОМ репозитории git (доступ через SSH). Таким образом, получение доступа к ключу API там относительно хорошо защищено. Однако без докера, имеющего собственные встроенные секреты, функциональность / защиту, созданный образ докера всегда включает ключ API в виде обычного текста. Следовательно, полученный образ сборки Docker должен быть частным, как репозиторий git ... который имеет нежелательный эффект (нежелательный эффект), который никто другой не может публично просматривать / просматривать журналы сборки / статус сборки там.

Во многих отношениях это не идеально. Но в целом решение достаточно простое и действительно работает (например, вчера). Если бы в будущем был создан лучший механизм, я бы подумал о переходе на него. Но не в том случае, если этот механизм будет значительно дороже / сложнее в настройке, чем текущее решение, которое я уже сделал. Таким образом, сверхсильная безопасность (хотя приветствуется) может быть излишней в случае всего 1 ключа api. Который просто нужно сохранить вне кеша слоев изображений докеров с помощью какой-то новой опции NOCAHCE / команды Dockerfile.

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

Я думаю, что модель клиент / сервер (например, в хранилище ) для управления и оптимизации (читай: аудит, разбитие стекла) всех вещей, связанных с секретами, была бы хорошей практикой и охватила бы большинство вариантов использования, если бы реализация была сделана продуманно. Лично я не сторонник неголистического подхода, потому что это возможность поднять планку передовых практик.

Это подразумевает наличие долго работающего клиента (ответственность за развертывание образа) и / или клиента времени сборки (ответственность за конструктор). Возможно, первый может быть каким-то образом передан демону докера, который предоставляет авторизованные секреты во время выполнения.

Действительно - я полностью согласен с предыдущим комментарием. Не то чтобы я не восхищался творческими способами, с помощью которых люди решают проблему, но я не думаю, что так оно и должно быть - давайте попробуем придумать решение, которое можно было бы использовать как во время CI / D, так и во время выполнения. , а также с учетом того, что контейнеры могут быть организованы Mesos / Kubernetes и т. д.

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

Похоже, ребята из Убежища тоже смотрят на это со своей стороны. Думаю, стоит посмотреть этот билет:

https://github.com/hashicorp/vault/issues/165

Может быть, это то, над чем можно было бы сотрудничать.

@jdmarshall

Может быть, это то, над чем можно было бы сотрудничать.

+1

+1 Докер + Хранилище Корпорации Хаши

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

Я ищу решение, которое охватывает разработку (например, ключи github) и развертывание (например, ключи сертификата nginx, учетные данные db). Я не хочу загрязнять хост env vars или инструментами сборки, и, конечно же, никакие секреты не должны попадать в github (незашифрованный) или каталог изображений докеров, даже частный.

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

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

Мое собственное предпочтение склоняется к идее, что простое хранение ключей может быть достигнуто с помощью чего-то вроде техники «хранилища» ansible. Если у вас есть зашифрованный текстовый файл, хранящийся в контексте сборки (или источники вне / вместе с контекстом сборки). Затем ключ разблокировки может разблокировать любые пароли в виде открытого текста или ключи API и т. Д. Из этого файла.

Я просто говорю это после использования собственного решения Anisible для "хранилища". Что относительно безболезненно / просто. Хранилище Hashicorp более безопасно, но его сложнее настроить и, как правило, сложнее. Хотя я не знаю какой-либо технической причины, по которой вы все еще не могли бы в конечном итоге использовать это внизу в качестве бэкэнда (скрыть / упростить его с помощью инструмента командной строки, ориентированного на докеры).

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

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

Не знаю, можно ли это использовать или сработает, но вот немного предложения левого поля для решения случая, когда я хочу ввести секрет в контейнер во время выполнения (например, пароль postgres)

Если бы я мог переопределить в docker run time точку входа и установить для нее сценарий по моему выбору, например / sbin / get_secrets, который после получения секретов от механизма по моему выбору (например, KMS), он запустил бы исходную точку входа (таким образом становясь простой оболочкой, единственной целью которой было установить переменные среды с секретами в них ВНУТРИ контейнера. Такой сценарий может быть предоставлен во время выполнения через монтирование тома. Такой механизм не будет включать секреты, когда-либо записываемые на диск ( один из моих питомцев ненавидит) или утечка докером (не является частью проверки докеров), но гарантирует, что они существуют только в среде процесса 1 внутри контейнера, что сохраняет 12-факторность.

Вы уже можете сделать это (я считаю), если точка входа не используется в метаданных изображения, а используется только cmd, поскольку точка входа затем обертывает команду. Как уже упоминалось, оболочка может быть смонтирована во время выполнения через volmount. Если точка входа уже используется в метаданных изображения, то я думаю, что вы не можете этого сделать в настоящее время, если не возможно увидеть, какая исходная точка входа была изнутри контейнера (не переопределение cmdline) - не уверен, можете ли вы это сделать или нет .

Наконец, я бы даже подумал, что можно будет предоставить зашифрованный одноразовый ключ через традиционную инъекцию env var, с помощью которой внешний / sbin / get_secrets может использовать для запроса фактических секретов (например, пароля postgres), тем самым добавив дополнительную защиту в докер утечка одноразового ключа.

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

@thaJeztah - Я могу подтвердить, что решение, которое я предлагаю выше, работает, секреты проявляются без утечки докером, они существуют только в памяти для процесса 1 через переменные среды, которые полностью совместимы с 12 факторами, но они НЕ отображаются в docker api в docker inspect или где-либо еще, потому что они относятся к процессу 1. Для того, чтобы это работало, в образе не требуется никакой работы. В моем случае я скомпилировал статический двоичный файл golang для извлечения секретов, чтобы он мог быть смонтирован на томе и перекрыл точку входа с этим, двоичный файл выдает sys exec для передачи управления точке входа, определенной изображением, по завершении.

@gtmtech Интересно. Было бы интересно, как вы узнали, что была исходная точка входа из вашего двоичного файла секретов.

Возможно, папка с примерами кода упростит демонстрацию / понимание подхода.

Пример кода и сценарии работы здесь @ dreamcat4 @kaos >

https://github.com/gtmtechltd/secret-squirrel

Я могу ошибаться, но зачем эти сложные методы? Я полагаюсь на стандартные права доступа к файлам unix. Передайте все секреты докеру с помощью -v /etc/secrets/docker1:/etc/secrets доступного для чтения только пользователю root, а затем при запуске контейнера с правами root запускается сценарий, который передает секреты в соответствующие места для соответствующих программ (например, конфигурация apache). Эти программы сбрасывают права суперпользователя при запуске, поэтому в случае взлома они не смогут позже прочитать секрет, принадлежащий суперпользователю. Является ли этот метод, который я использую, некорректным?

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

Я могу ошибаться, но зачем эти сложные методы? Я полагаюсь на стандартные права доступа к файлам unix. Передайте все секреты докеру с помощью -v / etc / secrets / docker1: / etc / secrets, доступных для чтения только root, а затем есть скрипт, запускаемый при запуске контейнера как root, который передает секреты в соответствующие места для соответствующих программ (например, apache config). Эти программы сбрасывают права суперпользователя при запуске, поэтому в случае взлома они не смогут позже прочитать секрет, принадлежащий суперпользователю. Является ли этот метод, который я использую, некорректным?

Привет,
Я согласен и думаю, что этот подход ^^ в целом следует рекомендовать как лучший способ для секретов RUNTIME. Если только кто-то здесь не возражает против этого. После этого можно впоследствии также перечислить любые оставшиеся угловые случаи (во время RUNTIME), которые не покрываются этим ^^.

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

Итак, это уходит (вы, наверное, уже догадались) ...
Секреты времени сборки!

Но я считаю, что это прогресс! Так как по прошествии долгого времени ничего не получается, возможно, это сокращает количество вещей вдвое и решает примерно 45-50% общей проблемы.

И если все еще остаются проблемы с секретами, по крайней мере, они будут более конкретными / сфокусированными и могут продолжать развиваться / решать впоследствии.

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

secret_squirrel в любом случае является взломом в пространстве, где я пока не вижу никаких жизнеспособных решений, вокруг докера, еще не предоставляющего секреты api или подключаемого секретного драйвера, который, надеюсь, они в какой-то момент будут, но, возможно, он служит для иллюстрации того, что настройка ENV vars внутри контейнера перед выполнением процесса, но не как часть процесса создания докеров (или метаданных), - это безопасный способ обеспечения 12-факторной совместимости с секретами, и, возможно, сообщество разработчиков докеров может использовать эту идею, когда они начнут создавать секреты-api / driver, если они считают его хорошим!

Удачного стыковки!

Мы с большим успехом использовали подход, описанный в @gtmtech . Мы вводим зашифрованные с помощью KMS секреты через переменные среды, а затем позволяем коду внутри контейнера расшифровываться по мере необходимости.

Обычно это связано с простой точкой входа в оболочку перед приложением. В настоящее время мы реализуем эту прокладку с комбинацией оболочки и небольшого двоичного файла Golang (https://github.com/realestate-com-au/shush), но мне нравится звук подхода чистого Go.

@gtmtech @mdub Я определенно был бы рад увидеть это больше.
@ dreamcat4 Я думаю, что определение «сложного» может зависеть от пути, что, очевидно, вполне нормально. Тем не менее, это, вероятно, не может быть абстрактным суждением. Поэтому, однако, защитная оболочка внутри контейнера докеров не кажется мне чем-то слишком сложным на уровне дизайна. Другой аспект - это лучшие практики: их нужно рассматривать не с точки зрения разработчика, а с точки зрения эксплуатации.
мои 2 цента

Убежище +1

Убежище -1. Хранилище имеет некоторые эксплуатационные характеристики (вскрытие), которые делают его действительно нежелательным для многих людей.

Имеет смысл иметь подключаемый API.

Есть также хранилище Ансибля. Это совсем другой зверь.

@gtmtech спасибо за предложение, это вдохновило меня написать эту точку входа:

#!/bin/bash

if [ -d "/var/secrets" ]; then
  tmpfile="$(mktemp)"
  for file in /var/secrets/*
  do
    if [ -f $file ]; then
      file_contents=$(cat $file)
      filename=$(basename "$file")
      underscored_filename="${filename//-/_}"
      capitalized_filename=${underscored_filename^^}
      echo "export $capitalized_filename=$file_contents" >> $tmpfile
    fi
  done

  source $tmpfile
  rm -f $tmpfile
fi

exec "$@"

Я просто добавляю его в Dockerfile вот так (не забудьте добавить chmod + x ):

ENTRYPOINT ["/app/docker-entrypoint.sh"]

И вуаля. Варианты ENV доступны во время выполнения. Достаточно хорошо :)

Если я правильно понял, директория /var/secrets должна монтироваться через тома правильно ??
Кроме того, когда есть комментарии о том, что секреты не записываются на диск, насколько плохо записывать их на диск, а затем удалять их ???

Хороший! Вы должны использовать shred чтобы безопасно удалить файл.

В четверг, 3 марта 2016 г., Хуан Игнасио Доносо [email protected]
написал:

Если я правильно понял, каталог / var / secrets надо монтировать через
объемы правильно ??
Также, если есть комментарий о том, что секреты не записываются на диск, как
плохо записать их на диск, а потом удалить ???

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/docker/issues/13490#issuecomment -191887424.

Руи Мариньо

Вдохновленный "секретной-белкой" @gtmtech , я расширил свой инструмент управления shush ", чтобы сделать его пригодным для использования в качестве точки входа в изображение:

ADD shush_linux_amd64 /usr/local/bin/shush
ENTRYPOINT ["/usr/local/bin/shush", "exec", "--"]

Это расшифровывает любые переменные KMS_ENCRYPTED_xxx и возвращает результаты обратно в среду.

https://github.com/realestate-com-au/shush#use -as-a-command-shim

Итак, цепочка начинается с НЕ ДЕЛАЙТЕ НИКАКОГО ИЗ ЭТИХ ВЕЩЕЙ .....

... но я не вижу ничего, ПОЖАЛУЙСТА, ВМЕСТО ЭТОГО ... только различные предложения / хаки, которые в основном были отклонены / закрыты.

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

@alexkolson
Насколько я понял, если вам нужны секреты во время выполнения, вы должны либо использовать тома (секреты файловой системы), либо некоторые службы, такие как HashiCorp Vault (сетевые секреты).

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

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

Некоторые люди даже говорят, что использование файловой системы для секретов небезопасно, и что демон докера должен предоставлять некоторый API для безопасного предоставления секретов (с использованием сети / брандмауэра / автоматически смонтированного тома?). Но никто даже не представляет, как будет выглядеть этот API и как его использовать.

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

  1. Агрегирование журналов, улавливающих все переменные env или забытые phpinfo, оставшиеся на рабочем веб-сервере, поэтому будьте осторожны с секретами и правильно настройте.
  2. Может быть, троян, который предоставляет env vars - так что не запускайте ненадежное программное обеспечение.
  3. Атаки, использующие слабые места, такие как внедрение sql, поэтому проверяйте ввод и используйте брандмауэр веб-приложения.

Слабые стороны, представленные вверху этой ветки:

Доступен для любого процесса в контейнере, поэтому легко "протекает"

Примените крестики 1 и 2 сверху. Законно, но при обращении с осторожностью, верно? Кроме того, ваш док-контейнер выполняет гораздо меньше процессов, чем полнофункциональный веб-сервер.

Как насчет config в env var, но секретные env vars имеют зашифрованные значения, а приложение имеет ключ в коде? Это просто обфускация, потому что ключ находится в коде, но потребуются эксплойты для получения доступа как к ключу, так и к переменным env. Возможно, используйте управление конфигурацией для управления ключом на хосте докера, а не в коде приложения. Может помочь с процессами наложения румян и случайными утечками, но, очевидно, не с инъекционными атаками от кого-то, у кого есть ключ.

Сохраняется в промежуточных слоях изображения и отображается в docker inspect.

Запекают ли люди env vars в образы докеров, а не устанавливают во время выполнения, или я неправильно понимаю это. Никогда не превращайте секреты в артефакты, верно? Да, sudo docker inspect container_name дает переменную env, но если вы находитесь на моем рабочем сервере, то iv уже потерян. sudo docker inspect image_name не имеет доступа к моим переменным окружения, установленным во время выполнения.

Совместно с любым контейнером, связанным с контейнером

Как насчет того, чтобы вместо этого не использовать ссылки и новую сеть?

Единственная проблема, которая кажется проблемой докеров, а не универсальной, - это ссылки ...

Поместите меня в лагерь людей, которым нужен хороший способ обработки секретов во время docker build . Мы используем composer для некоторых проектов php и ссылаемся на некоторые частные репозитории github для определения зависимостей. Это означает, что если мы хотим построить все внутри контейнеров, для доступа к этим частным репозиториям нужны ssh-ключи.

Я не нашел хорошего и разумного способа справиться с этим затруднительным положением без устранения некоторых других вещей, которые я считаю полезными в docker (см. docker squash ).

Теперь мне пришлось регрессировать в создании частей приложения за пределами контейнера и использовать COPY для внесения конечного продукта в контейнер. Мех.

Я думаю, что docker build нужна некоторая функциональность для обработки эфемерных данных, таких как секреты, чтобы они не попали в окончательный транспортный контейнер.

Я думаю, что docker build нуждается в некоторой функциональности для обработки эфемерных данных, таких как секреты.

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

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

Если секреты не должны быть частью образа, вы можете запустить временный контейнер, который будет зеркалировать / проксировать все ваши защищенные секретом ресурсы и предоставлять доступ без секретов. Зеркалирование, кстати, имеет другое обоснование: https://developers.slashdot.org/story/16/03/23/0652204/how-one-dev-broke-node-and-thousands-of-projects-in-11-lines -of-javascript

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

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

Я читал кучу этих потоков сейчас, и одна функция, которая решит некоторые варианты использования здесь и будет иметь варианты использования вне секретов, - это флаг --add для docker run который копирует файл в контейнер, точно так же, как инструкция ADD в Dockerfiles

Это действительно отличная статья. Очень хорошее чтение. И именно то, что мы надеялись увидеть.

КСТАТИ:

Также нашел пару других секретных инструментов, которые, кажется, были упущены из статьи. Приносим извинения за повторы / дублирование. Еще не заметил их здесь упомянутых:

Секреты времени сборки:

https://github.com/defunctzombie/docket

Секреты времени выполнения:

https://github.com/ehazlett/docker-volume-libsecret

Что думают люди? Большое спасибо.

Для меня:

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

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

Мы написали еще один инструмент, похожий на docket, который использует новый формат изображения:

https://github.com/AngryBytes/docker-surgery

Наша реализация сначала создает слой, содержащий секреты с комментариями SECRETS , затем создает копию Dockerfile с измененным FROM , строит и, наконец, удаляет все слои SECRETS из полученного изображения.

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

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

@Vanuan [Dockerfile] не может воспроизводиться. Команда RUN гарантирует, что мы с вами не можем разумно ожидать получения одного и того же изображения из двух запусков. Почему? Потому что большую часть времени люди используют RUN для доступа к сетевым ресурсам. Если вы хотите такой же образ, как и я, вам нужно создать свое собственное изображение «ОТ» моего. Никакая другая аранжировка не даст нам таких же изображений. Никакая другая аранжировка не может дать нам такие же образы. Вся надежная воспроизводимость обеспечивается Docker Hub, а не Dockerfile.

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

@stephank Я реализовал инструмент сборки

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

Внешний вид конвейера сборки полностью зависит от проекта с использованием файла спецификации, настраивающего требования сборки.

На самом деле, я очень взволнован этим инструментом, я просто жду, когда мы сможем выпустить его с открытым исходным кодом (ожидающие принятия руководящих принципов политики компании).

@kaos С одной стороны, я не хотел отказываться от стандартного инструментария Docker. С другой стороны, я чувствую, что среди инструментов для создания изображений действительно должно быть больше конкуренции. Звучит интересно! 😀

@thaJeztah для

@alexkolson Я думаю, что ключ к этой теме - «НЕ ДЕЛАЙТЕ ЭТО», если вы не смягчили X, Y, Z. Это явно инженерная теория - всегда будут «решения» общих проблем. Тем не менее, обучение тому, чего не следует делать и почему, важно, чтобы можно было начать настоящие обходные пути. Дьявол всегда в значениях по умолчанию, поэтому мы должны убедиться, что новые пользователи понимают, что находится под угрозой.

Может быть, некоторые из вас, ребята, могут мне помочь, потому что у меня еще мало опыта работы с докером.
Я использовал Хэшикорпс Хранилище, чтобы получить свои секреты.

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

Но я думаю, что все еще сталкиваюсь с несколькими общими проблемами.

  • Мне нужно создавать новые изображения, если изменяются конфиденциальные данные
  • Если мое изображение было украдено / взломано, конфиденциальные данные находятся внутри изображения.

С помощью docker inspect можно найти использованный токен, но его больше нельзя использовать.
Я решил запечатать и вскрыть хранилище hashicorps только во время сборки, чтобы максимально ограничить доступ к хранилищу секретов. Я также не видел возможности сохранять секреты при извлечении данных во время выполнения.

Итак, насколько плохо я это сделал (можно сказать, если я сильно напортачил;)) есть ли у кого-нибудь для меня советы и рекомендации, чтобы сделать вещи более безопасными?

@weemen AFAIK хранить секреты в вашем изображении тоже не лучшая идея. В вашем изображении не должно быть запеченных учетных данных (включая токены Vault). Вместо этого используйте серверную часть аутентификации Vault по идентификатору приложения для ваших контейнеров, чтобы получать секреты во время загрузки. Каким-то образом храните их в памяти контейнера, в зависимости от используемого стека приложений.

Кроме того, Vault работает над серверной частью aws auth, которая будет полезна в будущем, если вы используете AWS в качестве облачного провайдера.

@ jaredm4 Не могли бы вы прояснить это утверждение ?:

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

Я еще не понимаю, когда и где получить секреты из Vault (или Keywhiz и т. Д.). Это делается до того, как докер запускается и передается команде запуска? Происходит ли это в какой-то момент во время инициализации контейнера (если да, то какие-нибудь примеры)? Должно ли мое приложение получать их при необходимости? Например, моему приложению rails нужны ключи Google API. Могу ли я написать что-нибудь внутри rails для вызова хранилища, когда ключи нужны?

Я думаю, что мне ясно, что нужно использовать что-то вроде Vault, и я понимаю, как его настраивать, я просто не понимаю, как использовать службу и обновлять мои yml-файлы, а также готово к загрузке rails.

Любое руководство здесь будет оценено. Спасибо

Конечно, @mcmatthew , хотя в

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

При загрузке контейнера ваше приложение Rails заметит, что у него еще нет секретов, и должно получить их из Vault. Он имеет предоставленный app-id , и ему нужно будет каким-то образом сгенерировать его user-id . Это создание идентификатора пользователя должно быть определено вами, но в их документации указывается, что «обычно это значение, уникальное для машины, такое как MAC-адрес или идентификатор экземпляра, или значение, хешируемое из этих уникальных значений».

Когда ваше приложение Rails подготовит идентификатор приложения и идентификатор пользователя, оно может использовать API Vault для входа в систему. Оттуда вы можете выполнять вызовы API, чтобы получить необходимые секреты.

Теперь, чтобы прояснить, что я имел в виду, говоря о хранении их в памяти - это зависит от типа приложения, которое вы используете, но с Rails должен быть способ хранить ваши секреты в кеше переменных пользовательской среды, который позволит Rails получить доступ к секреты из памяти при каждом запросе вместо того, чтобы получать их из Vault снова и снова (что, как вы понимаете, было бы медленным). Взгляните на это руководство по кешированию в Rails. А именно раздел 2.0, но убедитесь, что он использует memory_cache, а не диск.

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

Надеюсь, это поможет. Я знаю, немного высокий уровень, но именно так мы и планировали подойти к нему.

Что не ясно, так это то, что следует хранить в секрете, идентификатор приложения, идентификатор пользователя или и то, и другое.

Хорошо, ответ - https://www.vaultproject.io/docs/auth/app-id.html
Но все еще не ясно, почему он более безопасен, чем простой доступ через брандмауэр.
Может быть, каждый секрет хоста должен быть привязан к секрету приложения (политики)?
Т.е. если у вас есть доступ к секрету хоста, вы сможете получить доступ к определенным приложениям, если вы знаете их секретные имена?

Теперь нам нужно где-то хранить 2 токена?

@Vanuan.Они оба должны храниться как можно в секрете, да.

Основная цель app-id - ограничить доступ к определенным секретам внутри Vault с помощью политик. Любой, у кого есть доступ к идентификатору приложения, получает доступ к секретам политик этого идентификатора приложения. Идентификатор приложения должен быть предоставлен вашей стратегией развертывания. Например, если вы используете Chef, вы можете установить его в пакетах параметров (или CustomJSON для OpsWorks). Однако сам по себе он не позволит никому получить доступ к Vault. Таким образом, тот, кто получил доступ к Chef, не сможет затем получить доступ к Vault.

Идентификатор пользователя НЕ предоставляется Chef и должен быть привязан к конкретным машинам. Если ваше приложение избыточно масштабируется по экземплярам, ​​каждый экземпляр должен иметь свой собственный идентификатор пользователя. На самом деле не имеет значения, откуда происходит этот идентификатор пользователя (хотя они дают предложения), но он не должен исходить из того же места, где развернут идентификатор приложения (например, Chef). По их словам, это можно создать сценарием, просто другими способами. Любое программное обеспечение, которое вы используете для масштабирования экземпляров, может предоставлять идентификаторы пользователей контейнерам экземпляров / докеров и авторизовать идентификатор пользователя для идентификатора приложения. Это также можно сделать вручную, если вы не масштабируете свои экземпляры динамически. Каждый раз, когда человек добавляет новый экземпляр, он создает новый идентификатор пользователя, авторизует его для идентификатора приложения и передает его экземпляру любым удобным для него способом.

Это лучше, чем экземпляры брандмауэра? Думаю, это зависит от обстоятельств. Брандмауэр не ограничивает доступ к секретам в Vault (afaik), и если кто-то получит доступ к вашим экземплярам, ​​он может легко войти в ваше Vault.

Таким образом, им сложно собрать все кусочки пазла. Чтобы сделать еще один шаг вперед, app-id также позволяет использовать блоки CIDR. Если кто-то каким-то образом получит идентификатор приложения и идентификатор пользователя, он все равно не сможет получить доступ к Vault, не находясь в этой сети.

(Опять же, это моя интерпретация после тщательного изучения документации)

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

@thaJeztah :

Доступен любым процессам в контейнере, поэтому легко "протекает"

Можете ли вы поддержать это утверждение? Непривилегированные процессы не могут получить доступ к переменным среды не родительских процессов. См. Https://help.ubuntu.com/community/EnvironmentVariables#Process_locality.

Переменные среды, установленные для контейнера (через --env или --env-file ) _ доступны для любого процесса в контейнере.

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

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

Я знаю, что это не по теме, но кто-нибудь заметил, что эта проблема существует уже почти год! Завтра его юбилей. 👏

Может ли процесс-контейнер читать переменные env в памяти процесса, а затем снимать их (в среде)? Устраняет ли это большинство проблем безопасности во время выполнения?

@davibe проблема в том, что если контейнер или его процесс (ы) перезапускаются, эти env vars исчезают без возможности их восстановления.

Я пробовал, но похоже, что env vars все еще существуют после перезапуска.

dade<strong i="6">@choo</strong>:~/work/grocerest(master)$ cat test.js
console.log("FOO value: " + process.env.FOO);
delete(process.env.FOO);
console.log("FOO value after delete: " + process.env.FOO);

dade<strong i="7">@choo</strong>:~/work/grocerest(master)$ docker run --name test -it -e FOO=BAR -v $(pwd):/data/ node node /data/test.js
FOO value: BAR
FOO value after delete: undefined

dade<strong i="8">@choo</strong>:~/work/grocerest(master)$ docker restart test
test

dade<strong i="9">@choo</strong>:~/work/grocerest(master)$ docker logs test
FOO value: BAR
FOO value after delete: undefined
FOO value: BAR
FOO value after delete: undefined

может быть, docker-run выполняет мою вещь как дочерний элемент bash? Думаю, не стоит ..

@davibe :

unset 'SECRET_ENV_VAR'

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

Итак, одна из идей - удалить sudo и su из вашего контейнера и добавить команду USER перед любыми ENTRYPOINT или CMD . Любой, кто запускает ваш контейнер, теперь не должен иметь возможности работать как root (если я не ошибаюсь), и, таким образом, теперь вы действительно можете что-то от него скрыть.

Другая идея (лучшая ИМХО) - добавить понятие пользователей и групп в сокет Docker и в контейнеры, чтобы вы могли сказать, что GROUP-A имеет доступ к контейнерам с TAG-B, а USER-C принадлежит GROUP- A, поэтому у него есть доступ к этим контейнерам. Это может быть даже разрешение для каждой операции (GROUP-A имеет доступ к запуску / остановке для TAG-B, GROUP-B имеет доступ к exec, GROUP-C имеет доступ к rm / inspect и т. Д.).

Изучив это в течение нескольких часов, я не могу поверить, что, похоже, нет официально рекомендованного решения или обходного пути для секретов времени сборки, и что-то вроде https://github.com/dockito/vault кажется единственным жизнеспособным вариантом для секреты времени сборки (за исключением сжатия всего полученного образа или его создания вручную в первую очередь). К сожалению, https://github.com/dockito/vault довольно специфичен для ключей ssh, поэтому я пытаюсь адаптировать его для размещения файлов хранилища учетных данных git https ...

После того, что казалось вечностью (первоначально я слышал, что выпуск должен был быть намечен на 4 квартал 2015 г.), AWS ECS, похоже, наконец-то выполнили свое обещание ввести роли IAM в докер-приложения . Вот и сообщение в

Похоже, что это в сочетании с некоторыми достоинствами KMS является жизнеспособным решением в ближайшем будущем. Теоретически вам просто нужно привязать секреты к определенным принципам / ролям IAM, чтобы неавторизованные роли не запрашивали то, чего они не должны, и оставить безопасное хранилище для KMS.

Еще не пробовал, но в моем коротком списке ...

Kubernetes также, кажется, имеет некоторые секреты обработки, которые напоминают мне многие зашифрованные пакеты данных Chef.

Я понимаю, что это не независимый от платформы способ OSS, в котором весь смысл этой беседы,
но хотел предложить эти два варианта людям, играющим в тех инфраструктурных пространствах, которым что-то нужно _NOW_

Я только что наткнулся на кое-что, что могло бы помочь в этом отношении: https://github.com/docker/docker/pull/13587

Похоже, что он доступен начиная с docker v1.10.0, но до сих пор я этого не замечал. Я думаю, что решение, к которому я склоняюсь на данный момент, заключается в использовании https://www.vaultproject.io/ для хранения и извлечения секретов, сохраняя их внутри контейнера в файловой системе tmpfs, смонтированной в / secrets, или что-то в этом роде. . С новой функцией ECS, позволяющей использовать роли IAM в контейнерах, я считаю, что смогу использовать авторизацию AWS EC2 хранилища для защиты авторизации самих секретов. (Для независимых от платформы я мог бы быть склонен использовать их авторизацию по идентификатору приложения.)

В любом случае, мне не хватало места, где надежно хранить секреты после того, как они будут извлечены. Параметр tmpfs мне кажется хорошим. Единственное, чего не хватает, так это того, что ECS, похоже, еще не поддерживает этот параметр, поэтому я отправил это сегодня: https://github.com/aws/amazon-ecs-agent/issues/469

Все вместе это кажется довольно всеобъемлющим решением ИМХО.

@CameronGo , спасибо за указатель. Если я правильно понимаю, это нельзя использовать при сборке, или можно?

@NikolausDemmel извините, да, вы правы. Это только решение для секретов времени выполнения, а не время сборки. В нашей среде секреты времени сборки используются только для получения кода из Git. Дженкинс делает это за нас и хранит учетные данные для доступа к Git. Я не уверен, что одно и то же решение удовлетворяет потребности всех присутствующих, но я не понимаю других вариантов использования секретов времени сборки.

Дженкинс делает это за нас и хранит учетные данные для доступа к Git.

Как это работает с докером? Или у вас нет git clone внутри самого контейнера?

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

Если вы похожи на меня, и вы пришли сюда, пытаясь решить, что делать прямо сейчас, то FWIW я опишу решение, на котором остановился, пока не появится что-то лучшее.

Для секретов времени выполнения я решил использовать http://kubernetes.io/docs/user-guide/secrets/. Это работает, только если вы используете кубернеты. В остальном хранилище выглядит нормально. Что-либо секретное в сгенерированном изображении или во временном слое - плохая идея.

Что касается секретов времени сборки - я не могу придумать другого варианта использования секретов времени сборки, кроме распространения частного кода. На данный момент я не вижу лучшего решения, чем полагаться на выполнение чего-либо «секретного» на стороне хоста и ДОБАВИТЬ сгенерированный пакет / jar / wheel / repo / и т. Д. к изображению. Сохранение одного LOC, генерирующего пакет на стороне хоста, не стоит рисковать раскрытием ключей ssh ​​или сложностью работы прокси-сервера, как это предлагается в некоторых комментариях.

Может быть, добавление флага "-v" в сборку докера, аналогичного флагу запуска докера, могло бы сработать? Он будет временно разделять каталог между хостом и изображением, но также гарантирует, что он будет пустым в кеше или в сгенерированном изображении.

В настоящее время я работаю над решением с использованием Vault :

  1. На компьютере Builder установлено хранилище и локально сохранен токен.
  2. Когда начинается сборка, машина-конструктор запрашивает новый временный токен, действительный только в течение нескольких минут (в зависимости от сборки допускается даже 1h).
  3. Вводит токен в качестве аргумента сборки
  4. Образ Docker также имеет установленное хранилище (или устанавливает и удаляет его во время сборки), и с помощью этого токена он может получить настоящие секреты.

Важно, чтобы секреты удалялись внутри одной команды, поэтому, когда докер кэширует данный слой, не остается никаких остатков. (Это, конечно, относится только к секретам времени сборки)

Я еще не построил это, но работаю над этим.

В некоторой степени связано с комментарием @kozikow : «Что касается секретов времени сборки - я не могу придумать другого

Возможно, это и не секрет времени сборки, но у меня есть необходимость использования (защиты) пароля во время сборки в файле Docker, чтобы можно было загрузить уже созданный артефакт с помощью команды RUN curl. Для загрузки во время сборки требуются учетные данные пользователя для аутентификации, чтобы получить артефакт, поэтому мы передаем пароль как переменную среды в Dockerfile прямо сейчас (мы все еще находимся в Dev). Сборки происходят за кулисами автоматически, поскольку мы используем OpenShift, а переменные среды в Dockerfile выводятся в журналы во время сборки, как и любая команда сборки docker. Это делает пароль видимым для всех, у кого есть доступ к журналам, включая наших разработчиков. Я отчаянно пытался найти способ отправить пароль, чтобы его можно было использовать во время сборки докера, но тогда у меня нет вывода пароля в журналы или в конечном итоге на каких-либо слоях.

Я также поддерживаю то, что сказал

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

Для начала предлагаю:

  • Секрет не отображается в проверке докеров
  • После запуска процесса 1 секрет не доступен ни в одном файле, доступном из контейнера (включая файлы, смонтированные на томе).
  • Секрет недоступен в / proc / 1 / cmdline
  • Секрет передается в контейнер в зашифрованном виде.

Любое предложенное выше решение, которое нарушает одно из них, проблематично.

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

@gtmtech отличные предложения :)

После запуска процесса 1 секрет не доступен ни в одном файле, доступном из контейнера (включая файлы, смонтированные на томе).

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

Я бы добавил к списку требований времени выполнения:

  • Аутентификация / авторизация контейнера при загрузке первого секрета.

Например, Vault обеспечивает авторизацию с помощью AppRole Backend, но не имеет

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

С точки зрения приложения есть три способа справиться с этим:

  1. Получите секрет из переменной окружения.
  2. Получите секрет из файла.
  3. Получите секрет из другой системы.

1 и 2 выше, как правило, наиболее распространены, потому что большинство приложений поддерживают этот механизм. №3, вероятно, более идеален, так как оставляет меньше "крошек", но приложение должно быть разработано специально для этого, и часто все же необходимо иметь учетные данные, чтобы получить секрет.

Docker - это универсальность и поддержка множества вариантов использования. Исходя из этого, 1. и 2. являются наиболее привлекательными с точки зрения приложения, несмотря на то, что оба они оставляют «крошки» в системе.

Один из распространенных подходов, которые я, конечно, использую, - это вводить секреты с помощью сценария точки входа (например, использовать такой инструмент, как credstash или простой KMS в AWS, и комбинировать его с ролями IAM). В этом отношении вы фактически выполняете №3 выше в сценарии точки входа и либо №1 (установка переменной среды), либо №2 (запись в файл). Этот подход является динамическим и для №1 (переменные среды) не предоставляет учетные данные в журналах докеров или проверке докеров.

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

Это область, в которой Docker может добавить функциональность, чтобы избежать использования собственных сценариев точки входа. Docker любит плагины и может обеспечить зацепку в жизненном цикле контейнера, где он может поддерживать плагины поставщика «секретов», которые по сути выполняют функцию ручного сценария точки входа и вводят секреты в контейнер (через внутреннюю переменную среды или файл). Таким образом, у вас может быть поставщик секретов Hashicorp Vault, поставщик секретов AWS KMS и т. Д. Docker, возможно, мог бы иметь своего собственного поставщика, основанного на шифровании RSA (через цифровые сертификаты). Вся эта концепция примерно похожа на концепцию секретов Kubernetes, которая представляет секреты в файловой системе контейнера.

Конечно, существует сложность того, как разрешить доступ к поставщику секретов, и это проблема, с которой вы сталкиваетесь сегодня. С Hashicorp вы можете выпустить и передать одноразовый / ограниченный по времени токен для аутентификации, с AWS - это роли IAM, с подходом шифрования Docker RSA, о котором я упоминал, он может просто передавать секреты, зашифрованные с использованием общедоступного сертификата Docker Engine.

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

Проблема "секретного нуля" - непростая задача. Время сборки или время выполнения? У обоих есть свои плюсы и минусы, а также очевидные меры безопасности и недостатки (а также хаки и обходные пути!).

Тем не менее, я много думал о том, как управление паролем / ключом сводится к приложению и / или услуге.

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

Код, конфигурация и секреты будут предоставлены через вспомогательные службы. В этом случае мы используем Stash, Consul и Vault. Пока существует зависимость, есть возможность извлекать конфигурацию и секреты по мере необходимости.

Я нигде не видел в этом твердого решения, поэтому пишу об этом здесь. Но чтобы вернуться к цели этой темы, это один из подходов, с которым мы собираемся поэкспериментировать, чтобы обойти проблему Docker / secret. Мы будем создавать приложения, которые поддерживают это изначально, а не полагаться на фреймворки и платформы вокруг них, в которых они работают.

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

Мне бы очень хотелось, чтобы эта функция была реализована в виде плагина Builder в ядре Docker (а также некоторых других полезных функций, которые есть в Rockerfiles)!

Я вижу, что все 4 предложения, которые сейчас находятся в OP, касаются секретного хранилища 🙁

Я бы сказал, что докеры должны облегчить передачу секрета / пароля в _docker instance_, но хранение / управление этими секретами (и должно быть) выходит за рамки docker.

При _передаче секрета_ я бы сказал, что параметр запуска почти идеален, за исключением того, что он обычно регистрируется. Поэтому я бы сузил это до функции параметра, не являющегося

Что касается _как управлять секретами_, я бы сказал все, что угодно пользователю, от домашнего сценария bash до интеграции с помощью программного обеспечения, такого как Kubernetes .

Что плохого в том, чтобы просто реализовать MOUNT, например, рокер-крепления, как отмечалось ранее в @ agilgur5 ? Я не могу поверить, что эта дискуссия длилась так долго, что команде пришлось эффективно форкнуть команду docker build , чтобы удовлетворить этот действительно простой вариант использования. Нужен ли нам еще один HTTP-сервер? ЦЕЛОВАТЬ.

Я столько часов провел вокруг этого субджета ...

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

[Habitus] (http://www.habitus.io/) кажется другим вариантом, но в моем случае я не хочу добавлять другие инструменты в основном потому, что я хотел бы, чтобы процесс сборки на сервере CI И на компьютере пользователя сохранялся простой / такой же.

А как насчет docker-in-docker (dind) способ?

Вот пример двухэтапной сборки с dind, как я только что говорил выше: https://github.com/BenoitNorrin/docker-build-with-secrets

Не стесняйтесь комментировать ...

Интересно. Отчасти напоминает мне о том, как OpenShift строит.

Мне кажется, вы передаете пароль в командной строке. Есть ли способ обойти это?

Обратите внимание, что здесь есть PR для секретов времени сборки; https://github.com/docker/docker/pull/28079 (секреты времени выполнения для сервисов будут в docker 1.13, см. https://github.com/docker/docker/pull/27794)

@thaJeztah :
Что касается # 28079, я немного пессимистичен, когда увидел, что за последние два года так много неудач PR по этой теме ...
Я не хочу иметь рой как зависимость. Часть моих клиентов использует другой оркестратор кластеров.

@cassiussa :
Я не понимаю о чем ты?
1 / Пароли были переданы «конструктору контейнеров», который не является окончательным образом. Этот конструктор выполняет сборку докеров и создает образ на основе файла Dockerfile.realease. В истории этого финального изображения нет никаких секретов.
2 / Не стесняйтесь использовать docker-compose ( пример ), если вы не хотите передавать пароль в командную строку

@BenoitNorrin Я думаю, что в будущем он может быть расширен до @diogomonica может знать об этом больше

Похоже на это:

В настоящее время это только для режима Swarm, поскольку резервным хранилищем является Swarm, и как таковое оно предназначено только для Linux. Это основа для будущей секретной поддержки в Docker с потенциальными улучшениями, такими как поддержка Windows, различные резервные хранилища и т. Д.

Было бы здорово, если бы он был реализован так же, как рокер, можно
просто, не обязательно должно быть «предприятие».

Вторник, 29 ноября 2016 г., 15:53 ​​Майкл Варкентин, [email protected]
написал:

Похоже на это:

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

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/docker/docker/issues/13490#issuecomment-263608915 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AAZk5vlLwsBHHTTbUS_vvx-qTuwnkp6Oks5rDEpjgaJpZM4Eq021
.

Думаю, решением было бы зашифровать некоторые части информации, передаваемой из файла docker-compose .

Например, запустите docker inspect и зашифрованная информация должна быть отображена / помечена как _encrypted_. Тогда docker inspect --encryption-key some_key_file покажет всю зашифрованную информацию в незашифрованном виде.

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

Я думаю, что шифрование _ это ключ_ :)

Целью моего (действительно, очень, очень распространенного) варианта использования является создание
проект программного обеспечения с сервера git, который требует аутентификации, как для
проект и его зависимости. Рокер прибил его, позволив установить
файл или каталог во время сборки (в данном случае сокет агента SSH)

Вт, 3 января 2017 г., 04:14 Хиса, [email protected] написал:

Думаю, решением было бы зашифровать некоторые части передаваемой информации.
из файла docker-compose.

Например, запустите docker inspect, и зашифрованная информация должна быть
отображается / помечено как зашифрованное . Затем docker inspect --encryption-key
some_key_file покажет всю зашифрованную информацию в незашифрованном виде.

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

Я думаю, что шифрование - это ключ к успеху :)

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/docker/docker/issues/13490#issuecomment-270049742 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AAZk5qEphZo5SR9vOWVL5dck50EPadpVks5rOcsUgaJpZM4Eq021
.

Поскольку я не видел этого, вот еще одна хорошая статья об обработке секретов в AWS ECS: https://aws.amazon.com/blogs/security/how-to-manage-secrets-for-amazon-ec2-container- сервис-приложения-с помощью-amazon-s3-and-docker /

В Docker 1.13 есть новая команда docker secret. Эту проблему можно закрыть, если документация по этой функции соответствует упомянутым здесь вариантам использования.

Команда docker secret в настоящее время применяется только к Docker Swarm (то есть к службам докеров), поэтому в настоящее время не применима для общих контейнеров Docker.

Также docker secret управляет только секретами времени выполнения, но не секретами времени сборки.

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

Я просто не могу понять, как люди могут быть такими невероятно тупыми. Только
объяснение, которое я могу придумать, заключается в том, что команда по управлению продуктом не
практиков и никогда не использовали продукт. Я часто вижу это
характеристика проявляется при организации найма на основе
jira / agile навыки.

Я просто буду использовать рокер до 2019 года или когда тогда кто-нибудь увидит смысл.

Вс, 22 января 2017 г., 23:47 Шейн СтКлер, [email protected] написал:

Также docker secrets управляет только секретами времени выполнения, но не секретами времени сборки.

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/docker/docker/issues/13490#issuecomment-274370450 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AAZk5vJVJe4OeypWd1Cwqmh8Gzyn8P-mks5rU-qqgaJpZM4Eq021
.

Я беру этот последний комментарий, извините, я высказываюсь. Просто расстроен, что
простые крайние случаи часто кажутся возможностью что-то навязать
как консул или создать что-то действительно изощренное, а не просто
реализовать такую ​​простую вещь, как монтирование во время сборки.

В пн, 23 января 2017, 09:31 Брайан Хант, [email protected] написал:

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

Я просто не могу понять, как люди могут быть такими невероятно тупыми. Только
объяснение, которое я могу придумать, заключается в том, что команда по управлению продуктом не
практиков и никогда не использовали продукт. Я часто вижу это
характеристика проявляется при организации найма на основе
jira / agile навыки.

Я просто буду использовать рокер до 2019 года или когда кто-нибудь увидит смысл
тогда.

Вск, 22 января 2017 г., 23:47 Шейн СтКлер, [email protected]
написал:

Также docker secrets управляет только секретами времени выполнения, но не секретами времени сборки.

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/docker/docker/issues/13490#issuecomment-274370450 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AAZk5vJVJe4OeypWd1Cwqmh8Gzyn8P-mks5rU-qqgaJpZM4Eq021
.

@binarytemple Всем нужны все возможности прямо сейчас. Если что-то не готово, значит, оно просто не готово. Ограничение объема новой функции определенно не плохо, поскольку даже с ограниченным объемом всегда есть возможности для улучшения.

Если кто-то действительно увлечен внедрением функции, ему следует поговорить с сопровождающим (-ями) о том, как они могут внести свой вклад в эту работу.

Я подумал, что то же самое, что и @mixja, в том, что команда secret только помогает пользователям роя, не является более общим решением (как они сделали с подключением постоянных томов). То, как вы управляете своими секретами (что это такое и кто имеет к ним доступ), очень зависит от системы и зависит от того, какие части платных и / или OSS вы сколачиваете, чтобы создать свою «платформу». Когда компания Docker приступила к созданию платформы, я не удивлен, что их первая реализация основана на роях, так же как Hashicorp интегрирует Vault в Atlas - это имеет смысл.

На самом деле способ передачи секретов выходит за рамки docker run . AWS делает то же самое с ролями и политиками для предоставления / отказа в разрешениях, а также с SDK. Chef делает это, используя зашифрованные теги данных и криптографическую "загрузку" для аутентификации. У K8S есть собственная версия того, что только что было выпущено в 1.13. Я уверен, что мезо со временем добавят похожую реализацию.

Эти реализации, похоже, делятся на 2 лагеря.
1) передать секрет через монтирование тома, которое предоставляет "платформа" или (chef / docker secret / k8s
2) передать учетные данные, чтобы поговорить с внешней службой, чтобы получить что-то при загрузке (iam / credstash / и т. Д.)

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

Я воодушевлен тем, что этот первый шаг был сделан докером, и надеюсь, что из этого выйдет более общий механизм для docker run (для поддержки лагеря №2) - что, к сожалению, означает, что я не думаю, что этот поток начальная миссия выполнена и еще не должна быть закрыта.

нравиться!
действительно простой, но очень эффективный дизайн

@bacoboy , @mixja - рой с одним узлом и единый контейнерный сервис - это не так уж и плохо
docker swarm init, docker service создать реплику = 1

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

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

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

Чтобы внедрить секреты времени сборки, теперь мы можем использовать docker build --squash для безопасного выполнения следующих действий:

COPY ssh_private_key_rsa /root/.ssh/id_rsa
RUN git pull ...
RUN rm -rf /root/.ssh/id_rsa

Флаг --squash создаст единый слой для всего Dockerfile: секрета не останется и следа.

--squash доступен в docker-1.13 в качестве экспериментального флага.

@hmalphettes Это означает, что вы упускаете преимущества общих нижних уровней между сборками.

Это определенно не цель сквоша. Я все еще буду очень осторожен, добавляя такие секреты.

@zoidbergwill нижние слои по-прежнему будут общими.

Я на 100% согласен с @ cpuguy83. Полагаться на флаг времени сборки, чтобы скрыть секреты, было бы довольно рискованно. Был PR-предложение о времени сборки (https://github.com/docker/docker/pull/30637). Я поработаю над перебазированием, чтобы получить больше отзывов.

@wpalmer Если у вас есть автоматизированная

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

WDYT?

Почему мы все время путаем секреты времени сборки с секретами времени выполнения? Для docker (или связанных с ним инструментов, таких как kubernetes) уже есть много хороших способов предоставить секреты времени выполнения. Единственное, чего действительно не хватает, так это секретов времени сборки. Эти секреты не используются во время выполнения, они используются во время установки, например, это могут быть внутренние репозитории. Единственный рабочий способ, который я видел в этой и связанных темах (но также не рекомендовал), - это выставление http-сервера для контейнера во время сборки. Подход с http-сервером значительно усложняет доступ к этим секретам.

+1 секрет времени сборки! = Секрет времени выполнения

Как указывает Пол. Запекать внутренний репозиторий нежелательно
учетные данные в образ.

Почему это так сложно понять?

Вт, 16 февраля 2017 г., 14:42 Пол ван дер Линден, [email protected]
написал:

Почему мы все время путаем секреты времени сборки с секретами времени выполнения? Там
уже есть много хороших способов для Docker (или связанных с ним инструментов, таких как kubernetes)
предоставить секреты времени выполнения. Единственное, чего действительно не хватает, это времени сборки
секреты. Эти секреты не используются во время выполнения, они используются во время выполнения.
время установки, например, это могут быть внутренние репозитории. Единственный
способ работы, который я видел в этой и связанных темах (но также посоветовал
против него), предоставляет http-сервер контейнеру во время сборки.
Подход с http-сервером значительно усложняет доступ к
эти секреты.

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/docker/docker/issues/13490#issuecomment-280348116 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AAZk5h0Z2OGwApVnLNEFWKRdOfGxLOmRks5rdGBagaJpZM4Eq021
.

@pvanderlinden Вы также можете сделать это с помощью двухступенчатого построения.
Вот пример: https://github.com/BenoitNorrin/docker-build-with-secrets

@timka, как уже упоминалось, нежелательно https://github.com/docker/docker/pull/30637

@BenoitNorrin Не уверен, как это будет в моем (и других)
Пакеты, которые необходимо установить, уже созданы, когда я запускаю процесс сборки докера. Но сборка докера должна будет установить эти пакеты, ей потребуется доступ к внутреннему репозиторию anaconda и / или серверу pypi (python). Адреса и пароли, конечно же, являются личными.
Похоже, что # 30637 - это еще одна попытка, надеюсь, она попадет в докер!

@timka первая половина вашего сообщения, кажется, упоминает секреты времени сборки, но вторая половина явно говорит о секретах времени выполнения. Секреты времени выполнения просты. Моим текущим «решением» для секретов времени сборки является предварительный запуск в качестве полностью отдельного шага контейнера, который извлекает личные данные с использованием секрета времени выполнения. Затем на следующем шаге это объединяется с деревом перед запуском обычной команды docker build .

Альтернативой, если бы секреты времени сборки были стандартной функцией, было бы выполнение этих шагов в Dockerfile.

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

К вашему сведению, я написал https://github.com/abourget/secrets-bridge, чтобы решить проблему секретов времени сборки.

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

Сервер поддерживает пересылку агента SSH, туннелируемую через соединение через веб-узел TLS. Он работает и в Windows!

Александр, то, что вы сделали, было чрезвычайно творческим и умелым. Это просто
меня огорчает то, что необходимо пройти все эти шаги только для того, чтобы
добиться того же, что можно было бы сделать, если бы 'docker build' поддерживал 'mount'
команда, а не слепое настойчивое требование скопировать все в
контейнер.

Я в моем случае откажусь от docker build и буду использовать рокер или
что-то, если мое собственное творение.

13 июля 2017 г., 16:23 Александр Бурже, [email protected]
написал:

К вашему сведению, я написал https://github.com/abourget/secrets-bridge, чтобы обратиться к
проблема секретов времени сборки.

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

Сервер поддерживает пересылку агента SSH, туннелированную через TLS.
связь через веб-сокеты. Он работает и в Windows!

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/13490#issuecomment-315111388 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAZk5hZqTAgPBjS9cFP_IsYNa9wv-yoAks5sNjaBgaJpZM4Eq021
.

Вот последнее предложение секретов: https://github.com/moby/moby/issues/33343

Я думаю, что новая функциональность «многоэтапной сборки», включенная в последний выпуск Docker CE, решает большую часть наших проблем.

https://docs.docker.com/engine/userguide/eng-image/multistage-build/

Контейнеры, созданные для выполнения команд из Dockerfile поставляются с готовыми /dev и никакие изменения, сделанные там, не должны записываться в слой. Может ли докер доставлять секреты пользователя через эту точку монтирования? Аналогичным образом он предоставляет /dev/init ?

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

Сейчас август 2017 года. Между тем «старые предложения по работе с секретами» в исходном выпуске ссылаются на выпуски 2014 года.

По-прежнему нет хороших решений для секретов времени сборки. PR, предлагавший флаг --build-time-secret был закрыт без объяснения причин. Ничего не представлено в "Итак, что нужно?" раздел реализован.

тем временем

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


UPD .: как правильно и справедливо указал @ cpuguy83 ниже, полное резюме предложений находится на # 33343

Я знаю, что он не встроен, но secrets-bridge пока работает неплохо.

@dmitriid Я понимаю ваше разочарование по

Я разместил ссылку на предложение выше и видел ровно 0 комментариев, кроме моего собственного.

Вот последнее предложение секретов: # 33343

@ cpuguy83 Замечательно ! Я как бы пропустил последнюю треть этого обсуждения (и несколько других), так как это много чего нужно прочитать (в то же время ища решение), поэтому я действительно пропустил ваш комментарий, извините :(

Эта ветка началась в 2015 году.

Это 2017 год.

Почему пока нет решения для секретов времени сборки, которое не было бы хакерским и ужасным? Совершенно очевидно, что для многих это большая проблема, но на самом деле хорошего решения пока нет!

@mshappe

Почему пока нет решения для секретов времени сборки, которое не было бы хакерским и ужасным?

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

Пожалуйста, посмотрите мой комментарий чуть выше вашего:

Я разместил ссылку на предложение выше и видел ровно 0 комментариев, кроме моего собственного.
Вот последнее предложение секретов: # 33343

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

Это так легко решить. Просто нужно что-то, что-то, чего нет.
запеченные в изображениях. И на самом деле это очень просто решить, прекратите использовать
'docker build' и используйте python API, рокер или что-нибудь еще.

В среду, 23 августа 2017 г., в 21:42, Брайан Гофф [email protected]
написал:

@mshappe https://github.com/mshappe

Почему нет решения для секретов времени сборки, которое не было бы хакерским и
ужасно, но?

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

Пожалуйста, посмотрите мой комментарий чуть выше вашего:

Я разместил ссылку на предложение выше и видел ровно 0 комментариев к
это кроме моего собственного.
Вот последнее предложение секретов: # 33343
https://github.com/moby/moby/issues/33343

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

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/13490#issuecomment-324441280 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAZk5oEpcipmfCji1mXz6MOVt0p6-OA6ks5sbIC0gaJpZM4Eq021
.

@binarytemple Я начал рассматривать Rocker как альтернативу, на самом деле ... но только из-за этого странного ментального блока докера, похоже, есть секреты времени сборки.

Это странно. Я разговариваю с людьми, а они делают всякие глупые хаки
как использование HTTP-сервиса - выбросить все (мониторинг / детальный
разрешения / простота) обеспечивает комбо POSIX / SELinux. Я просто не
понимать. Мне отказ кажется нелогичным.

В среду, 23 августа 2017 г., 23:03 Майкл Скотт Шаппе [email protected]
написал:

@binarytemple https://github.com/binarytemple Я начал искать
Рокер как альтернатива, собственно, ... но только из-за этого странного
В докере mental block, похоже, есть секреты времени сборки.

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/13490#issuecomment-324461257 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAZk5ppZYsOhdfvgotCUk5l41Truo_EEks5sbJOLgaJpZM4Eq021
.

Многоступенчатая сборка докеров решает многие из этих проблем.

В простейшей форме вы можете вводить секреты как build-args, и они будут только частью истории изображений, в которой явно указано, что им нужен аргумент. Как указывает неклимдул , секреты будут доступны в списке процессов во время сборки. ИМО не большая проблема, но мы выбрали другой подход.

Наш сервер сборки работает с некоторыми секретами, смонтированными как тома, поэтому наша копия CI в f.ex. /mnt/secrets/.npmrc в текущий рабочий каталог. Затем мы используем Dockerfile, аналогичный приведенному ниже.

FROM node:latest
WORKDIR /usr/src/app
COPY .npmrc .
RUN echo '{ "dependencies": [ "lodash" ] }' > package.json
RUN npm install
RUN ls -lah

FROM alpine:latest
WORKDIR /usr/src/app
COPY --from=0 /usr/src/app/node_modules ./node_modules
RUN ls -lah
CMD ["ls", "./node_modules"]

В результирующем образе будут установлены зависимости, но не будет .npmrc или каких-либо следов его содержимого.

Использование многоэтапных сборок дает вам полный контроль над тем, как раскрывать секреты времени сборки процессу сборки. Вы можете получить секреты из внешних хранилищ, таких как Vault, через тома (которые мы монтируем из хранилища секретов в Kubernetes), зашифровав их gpg в репозитории, секреты Travis и т. Д.

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

@androa Мне нравится это решение, но я не уверен, что я думаю о секретах, копируемых в рабочий каталог. Это, вероятно, нормально для частного CI-сервера, но не так хорошо для локального здания, где вы будете копировать файлы, которые вы не должны, из защищенных мест (не говоря уже о том, что само копирование раздражает и опасно тем, что они могут случайно закончиться вверх в системе управления версиями). Другой вариант - использовать более широкий контекст сборки Docker, но для многих общих секретов, которые могут означать весь корневой том. Есть какие-нибудь предложения о том, как сделать это удобным для локальных пользователей и CI?

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

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

Этот выпуск открыт уже более двух лет, чтобы обобщить то, что было известно о проблеме на тот момент и что с ней делать. По-прежнему нет решения. Под этим я не имею в виду комплексное решение, которое будет поддерживать самые сложные схемы управления секретами «из коробки». ВООБЩЕ нет решения, нет переменных среды хоста, нет секретов загрузки из пути к файлу вне контекста сборки. Ничего такого, что можно было бы считать безопасным даже при самых строгих условиях.

@OJezu Как я уже говорил несколько раз по этому вопросу, существует открытое предложение с 0 в основном замечания по нему.
Если вы хотите, чтобы секреты раскрывались, пожалуйста, найдите время, чтобы прокомментировать это предложение.

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

Часто может показаться, что дела застопорились, когда на самом деле есть просто люди, которые усердно работают.
Для сборки см. Github.com/moby/buildkit, где большая часть этой работы выполняется сегодня.

Спасибо.

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

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

@OJezu

Есть по крайней мере одно простое решение: использовать специальный сервис (например, запускать на Jenkins) для создания артефактов.
Эта служба будет безопасно предоставлять все необходимые ключи для доступа к артефактам, от которых зависит ваше изображение.
По окончании работы артефакты будут помещены в безопасное место (например, Дженкинс). Эти артефакты не будут содержать никаких секретов, только каталог с двоичными файлами / sources / и т. Д.
Затем другая служба (например, другое задание Jenkins) получит доступ к этим предварительно созданным артефактам и превратит их в образ, который можно безопасно отправить в реестр образов, который, в свою очередь, надежно защищен с помощью rbac / keys для доступа к ним с машин разработчика / производства.

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

Build pipeline

@Vanuan не все языки

Примеры?

Проекты Python учитывают свои требования по времени установки, а не по времени сборки. В нашем случае из частного репозитория pypi / conda (защищенного паролем)

Так? Сделайте установку частью процесса сборки, а затем скопируйте установленные пакеты в новый образ.

Вам просто нужно убедиться, что ваш образ сборки и производственный образ основаны на одном и том же базовом образе Python.

Вы действительно можете просто скопировать все в новое изображение. Однако это убирает всю суть Dockerfile. Зачем нужен Dockerfile, если единственное, для чего вы можете его использовать, - это просто скопировать набор каталогов?

Итак, у меня не может быть простого потока, в котором я просто запускаю docker build . где угодно - либо на машине разработчика, либо на CI, но мне нужно полагаться на CI для сборки пакетов. Зачем тогда вообще возиться с докером? Я могу написать файл travis или настроить поток на бамбуке.

Разве вы не можете просто pip install requirements.txt на первом этапе сборки с секретами, доступными для извлечения из ваших частных репозиториев. Затем сборка следующего этапа просто копирует пакеты сайтов с первого этапа.

Зачем нужен Dockerfile, если единственное, для чего вы можете его использовать, - это просто скопировать набор каталогов?

Почему нет? Использование Dockerfile для сборки согласовано.

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

Прочтите ссылку на Dockerfile:
https://docs.docker.com/engine/reference/builder/

Похоже, вы в первую очередь сосредоточились на инструкции RUN , думая, что Dockerfile заменяет вам Makefile. Нет. Dockerfile предназначен только для одного: создать образ из исходного материала. Что это за исходный материал - бинарный файл, загруженный через http или репозиторий git, - не имеет значения. Docker не обязательно должен быть вашей CI-системой, даже если вы можете использовать его как единое целое при определенных условиях.

Я могу написать файл travis или настроить поток на бамбуке.

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

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

Если бы я не хотел всего этого, я бы придерживался lxc + ansible, тогда докеры не нужны.

Для этого не нужно docker build .

Для этого не нужно docker build .

Конечно, вы также можете предоставить собственный сценарий Makefile или build_image.sh для каждого проекта вместо одного самодостаточного файла Dockerfile, но это имеет несколько недостатков:

  • Кросс-платформенная совместимость: с предоставлением файла Dockerfile я знаю, что любая система, которая может запускать docker build , сможет создать образ. Предоставляя пользовательские Makefile или build_image.sh , я должен вручную убедиться, что они работают на всех платформах, которые я хочу поддерживать.
  • Известный интерфейс для пользователей: если вы знаете docker, вы знаете некоторые особенности поведения docker build для любого проекта, даже не глядя на Dockerfile (например, в отношении кеширования и т. Д.). Если у меня есть собственные Makefile или build_image.sh для каждого проекта, мне нужно сначала выяснить, какие команды нужно создать, очистить, где и в какой форме будет результат, если есть есть какое-то кеширование и в каком виде, ...

О, Dockerfile далеко не самодостаточен. Специально для среды разработки.
Учти это:

  • большинство разработчиков не знают всех различных вариантов docker build , но почти все знают, как запускать сценарии bash
  • docker build зависит от каталога контекста . Поэтому, если вы не готовы ждать, пока гигабайты данных (ваш исходный код с зависимостями) переместятся из одного места в другое для каждого отдельного изменения строки исходного кода, вы не будете использовать его для разработки.
  • если вы не создадите ВСЕ с нуля, у вас будет зависимость от реестра докеров
  • вполне вероятно, что вы будете зависеть от репозиториев ОС (независимо от того, используете ли вы образы на основе Debian или Alpine), если вы не загрузите контейнер прямо в статически созданный двоичный файл
  • если вы не передадите все в git, у вас будут некоторые зависимости на уровне проекта, будь то npm, индекс пакета python, rubygems или что-то еще. Так что вы будете зависеть от внешнего реестра пакетов или его зеркала.
  • как большинство людей заметили здесь, вы будете зависеть от некоторого секретного местоположения пакета для ваших частных зависимостей, которые вы не можете опубликовать в общедоступном репозитории, поэтому вы будете зависеть от этого
  • Для доступа к этому безопасному месту требуется подготовка секретов, поэтому вы будете зависеть от какой-то системы, которая будет распространять секреты среди разработчиков.
  • в дополнение к Dockefile вам понадобится docker-compose.yml, и он не кроссплатформенный: вы по-прежнему зависите от различий прямой / обратной косой черты .

Кросс-платформенная совместимость: с предоставлением файла Dockerfile я знаю, что любая система, которая может запускать сборку докеров, сможет создать образ.

Dockerfile не гарантирует кроссплатформенную совместимость. Вам по-прежнему необходимо предоставить несколько файлов Docker для нескольких платформ. «Может запускать сборку докеров» больше не означает «Использует Linux». Docker также поддерживает собственные образы Windows. Вам все равно придется использовать Cygwin + Linux VM, если вы хотите запустить что-то специально предназначенное для машин Linux на хосте Windows.

О, и я даже не упомянул x86 vs ARM ...

Известный интерфейс для пользователей: если вы знаете docker, вы знаете некоторые особенности поведения сборки docker для любого проекта, даже не глядя на Dockerfile.

Если только вы этого не сделаете. Все знают, как запустить bash-скрипт без параметров или одной команды make . Мало кто знает, как правильно указать все различные параметры командной строки для docker build , docker run или docker-compose . Неизбежно, что у вас будет какая-то оболочка bash или cmd-скрипт.


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

Я не собираюсь опровергать все ваши тезисы по отдельности. Во-первых, вы, конечно, всегда можете найти ситуации, когда подход «единого Dockerfile» вообще не работает. Тем не менее, я бы сказал, что почти для всех ваших поднятых вами вопросов (которые все действительны и актуальны) подход «настраиваемый сценарий или make-файл» либо столь же плох, либо еще хуже. Просто в качестве примера один момент:

большинство разработчиков не знают всех различных вариантов сборки докеров, но почти все знают, как запускать сценарии bash

Если я участвую в 10 проектах, и все они используют Dockerfile, мне нужно узнать о Docker только один раз, но с вашим предложением мне нужно изучить 10 совершенно разных скриптов сборки. Как мне стереть кеш и снова начать с нуля build_image.sh проекта Foo? Не ясно. Если создание образа выполняется с помощью docker build , это ясно (конечно, мне нужно знать, как работает докер, но мне также нужно сделать это для использования образа, полученного из build_image.sh ).

В целом, я полагаю, что идея, которую я и другие пытаемся сделать, заключается в том, что для сценариев / many / подход «одного файла Dockerfile», кажется, действительно хорошо работает для людей (что является причиной такой популярности докеров), в частности в мир с открытым исходным кодом, где обычно все ресурсы доступны без секретов. Но если вы попытаетесь применить тот же шаблон, который вам полюбился, в контексте, когда часть ваших ресурсов требует учетных данных для доступа, подход не работает. Было множество предложений (и реализаций) технологически не слишком сложных способов заставить его работать, но за долгое время ничего из этого не вышло (об этом много раз говорилось выше). Отсюда разочарование.

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

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

Мне кажется, что большинство людей здесь просит не о чем-то подобном, а только о простом способе использования секретов в docker build не менее безопасным способом, чем их использование в вашем пользовательском build_image.sh . Один из способов удовлетворить эту потребность - это монтирование во время сборки. У них есть недостатки, вероятно, есть способы получше, но просят не охватить все возможные угловые случаи.

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

  1. Я хочу запускать производственные образы на машинах для разработки. Использовать реестр докеров
  2. Мне нужна распределенная система CI, чтобы у каждого разработчика была воспроизводимая сборка. Используйте docker run для сборки вашего проекта, используйте docker prune для очистки
  3. Я хочу создавать образы докеров, чтобы можно было их распространять. Используйте выделенный CI-сервер, на котором вы можете запускать многоступенчатые сборки.

@Vanuan , поэтому я полагаю, что ваш подход в основном

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

Для всех, кто интересуется: я попытался использовать аргументы сборки, замаскированные по умолчанию, такие как FTP_PROXY, для создания контекстов. Это безопасно в отношении того факта, что docker-build не предоставляет эти замаскированные аргументы ни метаданным изображения, ни слоям изображения.

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

Однако работа была отклонена обоснованно, так как маскировка этих сборочных аргументов не гарантируется в будущем.

Мой лучший выбор после этого должен следовать @AkihiroSuda «s совет , используйте docker build --network или инструмент , как габитус для хранения / передать секреты через временный сервер TCP только видимые сборки контексты живут в пределах одного Docker демона, на широчайший.

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

В следующем выпуске @mumoshu я наконец получил подсказку об использовании предопределенных аргументов для секретов сборки.

Итак, по сути, я могу использовать docker-compose с таким отображением:

  myProject:
    build:
      context: ../myProject/
      args: 
        - HTTPS_PROXY=${NEXUS_USERNAME}
        - NO_PROXY=${NEXUS_PASSWORD}

Затем в папке с файлом docker-compose.yml создайте файл с именем «.env» с парами ключ-значение NEXUS_USERNAME и NEXUS_PASSWORD - и соответствующими значениями там.

Наконец, в самом Dockerfile мы указываем нашу команду запуска следующим образом:
ЗАПУСТИТЬ wget --user $ HTTPS_PROXY --password $ NO_PROXY

И НЕ объявляйте их как ARG в DockerFile.

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

@darmbrust Я попробовал ваше решение, но не смог заставить его работать.
Вот мой составной yml:
версия: "3.3"
Сервисы:

  buildToolsImage:
    image: vsbuildtools2017:web-v6

    build:
      context: .
      dockerfile: ./vsbuild-web-v6-optimized.dockerfile
      args:
        - CONTAINER_USER_PWD=${CONTAINER_USER_CREDS}

Вот файл .env, расположенный рядом с файлом yml:

CONTAINER_USER_CREDS=secretpassword

И вот мой файл докеров:

# escape=`
FROM microsoft/dotnet-framework:4.7.2-sdk
# Add non-root user
CMD ["sh", "-c", "echo ${CONTAINER_USER_PWD}"] 
RUN net user userone ${CONTAINER_USER_PWD} /add /Y

И, наконец, команда для запуска выглядит так:

docker-compose -f docker-compose.buildImage.yml build

Он создает образ, но без использования пароля, хранящегося в файле .env.

[Предупреждение] Один или несколько аргументов сборки [CONTAINER_USER_PWD] не были использованы

Что мне здесь не хватает?
Спасибо!

Вы должны использовать один из https://docs.docker.com/engine/reference/builder/#predefined -args в файле докера. Вы не можете использовать собственные имена аргументов, такие как CONTAINER_USER_PWD.

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

С помощью файла docker-compose вы можете сопоставить эти предопределенные аргументы с чем-то более разумным.

@darmbrust Да, это
Однако тебе не кажется, что он воняет? Есть лучшие рекомендации?
Спасибо!

Вероятно, это не так неприятно, как раскрытие ваших учетных данных ssh-agent через tcp
через socat для кражи любого локального процесса, но на самом деле, как и все
Что касается секретов, docker build действительно довольно вонючий.

На самом деле, я забыл, что Docker для Mac не может открыть домен Unix
сокеты на хосте osx для контейнеров, так что открывается еще больше
банка червей.

Мое текущее решение, запустить виртуальную машину Centos, учетную запись пользователя компьютера GitHub
учетные данные входят в него, соберите с помощью инструмента "Rocker" (не рекомендуется).

26 июля 2018 г., 21:49 Самир Кумар, [email protected] написал:

@darmbrust https://github.com/darmbrust Да, это помогло .
Однако тебе не кажется, что он воняет? Есть лучшие рекомендации?
Спасибо!

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/13490#issuecomment-408230125 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAZk5iz1kvCpZ0s65ng4TwL7LmHa9zZvks5uKitDgaJpZM4Eq021
.

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

Не уверен, что кто-то нашел "хорошее" решение ... мы все застряли в ожидании, когда докеры что-то с этим сделают ... не задерживайте дыхание, так как эта ошибка была написана в 2015 году, а они не Я даже не предложил дорожную карту, не говоря уже о решении.

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

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

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

Newsflash, раскрытие вашей связки ключей SSH через TCP, даже на локальном хосте, не
безопасный, ни один из них не передает учетные данные через переменные среды (подсказка, запуск
ps или заглянуть в файловую систему / proc), аргументы команд и переменные окружения - все там, в чистом виде, для всеобщего обозрения.

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

Для всех, кто работает в других экосистемах, где система сборки
извлекает зависимости из Git или репозиториев, требующих аутентификации, это большая проблема.

Я почти уверен, что есть какое-то правило запуска где-то вроде,
«не предполагайте, что вы знаете, как и почему ваши пользователи используют продукт».

26 июля 2018 г., 22:00 Дэн Армбраст, [email protected] написал:

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

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

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/13490#issuecomment-408233258 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAZk5nvbBTj4BAv5TtELNIHhJN8mU0Ctks5uKi38gaJpZM4Eq021
.

@binarytemple Все, кто когда-либо работал над Docker / moby (как и инженеры, стоящие за ним), точно знают, в чем проблема, и даже сталкивались с ней.

Volumes - это решение, которое само по себе невероятно негерметично.
Есть предложение, немного упомянутое в потоке комментариев, которое пытается решить эту проблему разумным образом (https://github.com/moby/moby/issues/33343)

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

В последнее время над конструктором было проделано много работы, которая еще не всегда видна, но плоды этих усилий начнут проявляться в ближайшие месяцы.
Начнем с того, что Docker 18.06 поставляется с альтернативной реализацией компоновщика, поддерживаемой https://github.com/moby/buildkit.
Вы можете подумать: «Как это мне поможет?». Buildkit предоставляет множество низкоуровневых примитивов, которые позволяют нам быть более гибкими в построителе Docker. Даже настолько, чтобы иметь возможность предоставить свой собственный парсер сборки (который может быть чем угодно, от расширенного парсера Dockerfile до чего-то совершенно другого). Парсеры указываются в верхней части «Dockerfile» и представляют собой любое изображение, которое вы хотите использовать для анализа файла.

Если вы действительно хотите что-то увидеть прямо сейчас, вы можете взять сам buildkit и запустить с ним сегодня, он находится поверх containerd, вы можете довольно быстро создать собственную интеграцию.

Поддержка секретных креплений была добавлена ​​в buildkit по адресу https://github.com/moby/buildkit/pull/522 . Они появляются строго в tmpfs, исключаются из кеша сборки и могут использовать настраиваемый источник данных. Пока нет PR, который раскрывает его в синтаксисе dockerfile, но должно быть простым дополнением.

Есть 2 решения для создания образов с секретами.

Многоступенчатая сборка:

FROM ubuntu as intermediate
ARG USERNAME
ARG PASSWORD
RUN git clone https://${USERNAME}:${PASSWORD}@github.com/username/repository.git

FROM ubuntu
# copy the repository form the previous image
COPY --from=intermediate /your-repo /srv/your-repo

Тогда: docker build --build-arg USERNAME=username --build-arg PASSWORD=password my-image .

Использование построителя образов: docker-build-with-secrets

@BenoitNorrin, извините, но вы предоставили этот пароль каждому процессу в хост-системе. Безопасность Unix 101 - не указывайте секреты в качестве аргументов команды.

Да, но в некоторых случаях безопасность имеет меньшее значение:

  • вы хотите построить на своем собственном компьютере
  • вы строите свой корпоративный CI-сервер (например, jenkins). В большинстве случаев речь идет о доступе к частному репозиторию (nexus, git, npm и т. Д.), Поэтому у вашего CI могут быть свои собственные учетные данные для этого.
  • вы можете использовать виртуальную машину, созданную из докер-машины, и удалить ее после.

Если это единственная проблема, @binarytemple , то простое добавление флага docker image build --args-file ./my-secret-file должно быть довольно простым решением всей этой проблемы, не так ли? : мышление:

@yajo может быть, да, это, по крайней мере, обходной путь, пока buildkit не будет поставляться с монтируемыми секретами. Хорошее предложение. Спасибо. B

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

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

Самая большая проблема для меня - это тайные ротации.

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

перечисление секретов служб кажется непростым делом (после нескольких попыток я отказался от docker service inspect --format='{{.Spec.TaskTemplate.ContainerSpec.Secrets}}' <some_service> ), список зависимостей служб из docker secret inspect <secret_name> тоже был бы полезен. Так что я пока просто поддерживаю этот (приблизительный) график вручную.

Вы также должны указать секретный пункт назначения, если он не является значением по умолчанию /run/secrets/<secret_name> в команде обновления службы докеров

Я просто надеюсь на более простой способ вращать секреты

@caub вот некоторая помощь CLI:

Документы Docker по форматированию помогают подобрать остальную часть вашего формата проверки:

docker service inspect --format='{{range .Spec.TaskTemplate.ContainerSpec.Secrets}}{{println .SecretName}}{{end}}'

Это перечислит все секретные имена в службе. Если вам нужны и имя, и идентификатор, вы можете:

docker service inspect --format='{{range .Spec.TaskTemplate.ContainerSpec.Secrets}}{{println .SecretName .SecretID}}{{end}}' nginx

У меня всегда есть мой CI / CD (команды обновления службы) или файлы стека, жестко запрограммировавшие путь, поэтому у вас не возникает этой проблемы при ротации.

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

docker build --secret наконец-то доступен в Docker 18.09 https://medium.com/@tonistiigi/build -secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066

@thaJeztah Готовы ли мы закрыть этот вопрос?

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

`` ''
ИЗ debian как сборка
КОПИРОВАТЬ ./secret.conf / путь / на / изображение /
ЗАПУСТИТЬ build.sh
...

ОТ debian
КОПИРОВАТЬ --from = build ...

@ andriy-f да, это работает, пока ты;

  • (очевидно) не копируйте секрет на финальную стадию 😉, или:
  • используйте стадию / стадию build в которой секрет присутствует в качестве «родителя» для окончательного изображения.
  • никогда не переносите этап сборки в реестр
  • доверять хосту, на котором работает ваш демон; т.е. с учетом того, что ваш этап "build" сохраняется в виде образа; кто-то, у кого есть доступ к этому изображению, сможет получить доступ к вашему секрету.

секреты времени сборки теперь возможны при использовании buildkit в качестве сборщика; см. сообщение в блоге здесь https://medium.com/@tonistiigi/build -secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066

и документация; https://docs.docker.com/develop/develop-images/build_enhancements/

опция RUN --mount используемая для секретов, скоро перейдет к синтаксису Dockerfile по умолчанию (стабильному)

Спасибо @thaJeztah. Я немного

Прохладный. Это закрывает вопрос о секретах времени сборки. Что-нибудь для runtime / devtime (ssh в OS X)?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги