Как мне монтировать приватный /proc внутри пространства имен внутри контейнера докера?
Мне нужно создать пространства имен внутри контейнера Docker. И как часть этого мне нужно будет смонтировать /proc
частный для внутреннего пространства имен. Я понимаю, что мне придется запустить контейнер с определенными привилегиями, чтобы это произошло, но я бы предпочел включить минимальный набор.
Это работает:
$ sudo docker run --privileged --security-opt=seccomp=unconfined \
-it fedora:rawhide /usr/bin/unshare -Ufmp -r \
/bin/sh -c 'mount -t proc proc /proc'
Это не:
$ sudo docker run --cap-add=sys_admin --security-opt=seccomp=unconfined \
-it fedora:rawhide /usr/bin/unshare -Ufmp -r \
/bin/sh -c 'mount -t proc proc /proc'
mount: /proc: cannot mount proc read-only.
Итак, просто отключив фильтры seccomp и добавив CAP_SYS_ADMIN
не достаточно Чего достаточно?
Обновление: Selinux является частью проблемы. Если вы отключите принудительное применение selinux по всему миру, это сработает. Но вы также можете отключить принудительное применение для конкретного контейнера с помощью --security-opt label:disable
и это задокументировано в разделе конфигурации безопасности интерактивного руководства по Docker:
sudo docker run --cap-add=sys_admin --security-opt label:disable \
-it fedora:rawhide /usr/bin/unshare -fmp /bin/sh -c \
'mount --make-private / ; mount -t proc proc /proc'
Но это не удастся, если -U
а также -r
флаги добавляются обратно unshare
, И, конечно же, добавив --privileged
команда запуска Docker работает очень хорошо, даже с -U
а также -r
флаги.
В настоящее время я пытаюсь использовать средства трассировки ядра, чтобы выяснить, что именно дает мне EPERM. Это очень бесполезная ошибка.
1 ответ
Эта команда работает:
sudo docker run --cap-add=sys_admin --security-opt label:disable -it fedora:rawhide /bin/sh -c 'for dir in $(awk '"'"'/\/proc\// { print $5; }'"'"' /proc/1/mountinfo ); do umount "$dir"; done; /usr/bin/unshare -Ufmp -r /bin/sh -c '"'"'mount --make-private / ; mount -t proc proc /proc ; ls /proc'"'"
Я не разбил его на несколько строк, потому что цитирование действительно важно. По сути, он размонтирует целую кучу вещей в /proc
перед запуском делиться и монтировать /proc
в дочернем пространстве имен пользователя.
Docker монтирует кучу каталогов и файлов в /proc
с его собственными каталогами, которые являются пустыми каталогами tmpfs и пустыми файлами. Различные файлы в /proc
представляют значения, которые применимы ко всей системе. По факту, /proc/kcore
позволил бы вам читать память ядра внутри контейнера, если бы вы были пользователем root, что, поскольку многие люди хотят верить, что контейнеры - это своего рода легкая виртуальная машина или что-то в этом роде, удивило бы многих людей.
Ядро в (начиная с версии 4.14 в любом случае) fs/namespace.c:mnt_already_visible
проверяет, монтирует ли вы уже смонтированную файловую систему, и если в этой файловой системе есть вещи, смонтированные как дочерние файловые системы, и эти монтирования имеют флаг MNT_LOCKED, происходит сбой. Флаг MNT_LOCKED, кажется, применяется (я не выискивал, где это находится в ядре) ко всем монтируемым файлам всякий раз, когда вы создаете пространство имен пользователя, чтобы помешать вам демонтировать вещи в этом пространстве имен (потому что вы получаете привилегии "внутри" пространство имен пользователя) и сделать скрытые вещи видимыми снова.
Итак, команда, которую я разместил, использует скрипт awk для содержимого /proc/1/mountinfo
вытащить все подкаталоги и файлы в /proc
тот Докер сел и размонтировал их всех. Это делает /proc
файловая система снова монтируется во вложенные пространства имен пользователя.