- PVSM.RU - https://www.pvsm.ru -

Решение проблемы ограничения PTRACE_ATTACH в контейнерах Docker

Решение проблемы ограничения PTRACE_ATTACH в контейнерах Docker - 1

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

Так с большим удивлением мы недавно обнаружили, что контейнер, который был разработан и протестирован некоторое время назад, не работает в текущей версии Docker. Дело в том, что контейнер был не совсем типовым и внутри него использовалась утилита strace для анализа поведения процесса. Про данное применение утилиты мы ранее подробно писали [1] на Habrahabr.

Сегодня у наших разработчиков наконец-то дошли руки до внедрения данного проблемного
контейнера [2] в приложение и они обнаружили, что он больше не работает. Начав разбираться в чем причина такого поведения, мы увидели, что strace, а конкретно ptrace, не может присоединяться к процессам и выдает ошибку вида:

strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted Could not attach to process.  If your uid matches the uid of the target process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try again as the root user.  For more details, see /etc/sysctl.d/10-ptrace.conf

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

Подсистема Seccomp

В новых ядрах ОС Linux новый Docker использует функцию ядра seccomp, которая позволяет блокировать системные вызовы внутри контейнера. Документация Docker по поводу данной возможности находится здесь [3]. Ptrace находится среди заблокированных системных вызовов. Тонкая настройка механизма осуществляется с помощью аргумента Docker run --security-opt seccomp=/path/to/file.json, который позволяет указать файл, в котором описывается что разрешено, а что нет. Поскольку наш контейнер работает в защищенной среде, то мы отключаем данную возможность полностью: --security-opt seccomp=unconfined.

Поведение Ptrace

Strace выдала нам подсказку о том, что есть некий псевдофайл /proc/sys/kernel/yama/ptrace_scope, в котором тоже описываются ограничения ptrace. Смотрим в документацию [4] ядра и узнаем, что не все так просто, как было раньше. Значения 0-3, находящиеся в данном псевдофайле существенно меняют поведение ptrace:

  • 0 — UID трассирующего процесса должен совпадать с UID трассируемого или быть 0 (поведение как было раньше);
  • 1 — ограниченный ptrace, процессы должны быть родственными, трассируемый процесс должен быть потомком
    трассирующего или трассирующий процесс должен иметь UID=0;
  • 2 — для трассирующего процесса должен быть установлен флаг CAP_SYS_PTRACE или потомок устанавливает себе флаг PTRACE_TRACEME;
  • 3 — трассирование запрещено.

Выполнив

docker exec -it <container> cat /proc/sys/kernel/yama/ptrace_scope

мы обнаружили, что в файле установлено значение 1, соответственно, не будучи родственным процессом, strace не мог подключиться к трассируемому процессу. При этом, попытка установить в /proc/sys/kernel/yama/ptrace_scope значение 0 не увенчалась успехом, было получено сообщение о том, что "/proc is read only".

Привилегированный запуск контейнера

Преодолеть данное ограничение нам помог флаг Docker, разрешающий в привилегированное исполнение: --privileged, а в инициализацию приложения мы добавили установку значения "0" в псевдофайл /proc/sys/kernel/yama/ptrace_scope.

echo 0 > /proc/sys/kernel/yama/ptrace_scope

В итоге проблема была успешно решена. Пример решения и аргументы для запуска контейнера можно найти в нашем GitHub репозитории для web ssh прокси [2].

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

Автор: Иван Кудрявцев

Источник [5]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/virtualizatsiya/261104

Ссылки в тексте:

[1] писали: https://habrahabr.ru/post/332544/

[2] контейнера: https://github.com/bwsw/webshell

[3] здесь: https://docs.docker.com/engine/security/seccomp/

[4] документацию: https://www.kernel.org/doc/Documentation/security/Yama.txt

[5] Источник: https://habrahabr.ru/post/334016/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best