Как работает создание пользователя без полномочий root путем простой установки случайного UID в контейнере «С нуля»? - PullRequest
0 голосов
/ 09 мая 2019

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

Вот простой Dockerfile, который я использую.Я импортирую свой двоичный файл в контейнер и устанавливаю случайный UID.

FROM scratch
WORKDIR /app
COPY --chown=1001:1001 my-app-binary my-app-binary
USER 1001
CMD ["/app/my-app-binary"]

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

Тем не менее, пользователь 1001 не был создан должным образом.Уроки, которые я видел, говорят мне создать пользователя в промежуточном контейнере 'builder' (например, alpine) и импортировать из него / etc / passwd.Я не нашел ни одного примера, делающего то, что я делаю.( здесь один учебник, которому я следовал)

Может кто-нибудь объяснить мне, почему мое решение работает или что я не понял?

1 Ответ

2 голосов
/ 09 мая 2019

РАСКРЫТИЕ ИНФОРМАЦИИ: В своем ответе я использовал цитаты из этого сообщения в блоге . Я не являюсь автором этого поста и никоим образом не связан с автором.

Ожидается - контейнеры могут работать под пользователем, который не известен контейнеру. Цитирование docker run документы :

root (id = 0) - пользователь по умолчанию в контейнере. Разработчик изображений может создавать дополнительных пользователей. Эти пользователи доступны по имени. При передаче числового идентификатора пользователь не обязан существовать в контейнере.

- https://docs.docker.com/engine/reference/#user

Это поможет вам решить такие проблемы:

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

- https://medium.com/redbubble/running-a-docker-container-as-a-non-root-user-7d2e00f8ee15#7d3a

И это возможно, потому что:

К счастью, docker run дает нам способ сделать это: параметр --user . Мы собираемся использовать его для указания идентификатора пользователя (UID) и идентификатора группы (GID), который должен использовать Docker. Это работает, потому что все контейнеры Docker используют одно и то же ядро ​​и, следовательно, один и тот же список UID и GID, даже если связанные имена пользователей не известны контейнерам (подробнее об этом позже).

- https://medium.com/redbubble/running-a-docker-container-as-a-non-root-user-7d2e00f8ee15#b430

Вышеприведенное относится и к команде USER dockerfile .

Использование UID, неизвестного контейнеру, имеет несколько ошибок:

Ваш пользователь будет $ HOME-менее

Что мы на самом деле здесь делаем, так это просим наш контейнер Docker сделать что-то с использованием идентификатора пользователя, о котором он ничего не знает, и это создает некоторые сложности. А именно, это означает, что пользователь упускает некоторые вещи, которые мы изучили, просто ожидая, что пользователи будут иметь - такие вещи, как домашний каталог. Это может быть хлопотно, потому что это означает, что всем, что находится в $ HOME - временным файлам, настройкам приложения, кэшам пакетов - теперь негде жить. Контейнерный процесс просто не знает, куда их поместить.

Это может повлиять на нас, когда мы пытаемся делать что-то для пользователя. Мы обнаружили, что это вызывало проблемы при использовании gem install (хотя с использованием Bundler все в порядке) или при запуске кода, основанного на ENV['HOME']. Так что это может означать, что вам нужно внести некоторые коррективы, если вы сделаете одну из этих вещей.

Ваш пользователь тоже будет безымянным

Также оказывается, что мы не можем легко разделить имена пользователей между хостом Docker и его контейнерами. Вот почему мы не можем просто использовать docker run --user=$(whoami) - контейнер не знает о вашем имени пользователя. Он может узнать о вашем пользователе только по его UID.

Это означает, что когда вы запустите whoami внутри своего контейнера, вы получите результат, подобный I have no name!. Это интересно, но если ваш код основан на знании вашего имени пользователя, вы можете получить некоторые запутанные результаты.

- https://medium.com/redbubble/running-a-docker-container-as-a-non-root-user-7d2e00f8ee15#e295

...