Джеймс Боттомли (James Bottomley), известный разработчик ядра Linux, входивший в координационный технический комитет Linux Foundation, опубликовал результаты анализа безопасности различных систем контейнерной изоляции, включая традиционные контейнеры Docker, недавно представленную систему Nabla, нацеленную на минимизацию выполняемых в основном ядре системных вызовов, и гибридные системы gVisor и Kata Containers с изоляцией на базе гипервизоров.
Для каждого типа систем оценивался уровень защищённости от совершения горизонтальных атак (HAP, Horizontal Attack Profile), при которых брешь в одном из базовых слоёв (например, в ядре Linux или гипервизоре) может привести к полной компрометации всей инфраструктуры и получению контроля за корневым окружением и всеми запущенными контейнерами. Уровень безопасности HAP зависит от объёма привилегированного кода, который вызывается в процессе работы той или оной системы контейнерной изоляции или виртуализации. Чем меньше привилегированного кода вовлечено в выполнение контейнера тем выше безопасность всей системы, так как сокращается число потенциальных векторов для атак и уменьшается вероятность присутствия уязвимостей.
Основным путём совершения горизонтальных атак для контейнеров являются системные вызовы, обработка которых выполняется на стороне общего ядра и, в случае наличия уязвимости в одном из обработчиков системного вызова, злоумышленник, имеющий доступ к одному из контейнеров, может получить контроль над всей инфраструктурой. В случае применения виртуализации на базе гипервизоров главными объектами для атак становятся гипервизор и прослойки для обеспечения доступа к оборудованию или эмуляции оборудования. В системах контейнерной изоляции предоставляется доступ к около 300 системным вызовам, что примерно в 10 раз превышает число гипервызовов (hypercall).
Из-за использования общего ядра Linux обычные контейнеры предоставляют больше векторов для совершения горизонтальных атак. Выходом могли бы стать комбинированные решения на базе виртуализации, использующие легковесное системное окружение, но из-за больших накладных расходов они проигрывают по производительности (наблюдается снижение производительности на 10-30%) и требуют для своей работы больше памяти. В качестве варианта, который обеспечивал бы должную производительность и защищённость, недавно была представлена система контейнерной изоляции Nabla.
В Nabla используется только 9 системных вызовов, а вся основная функциональность, включая TCP/IP стек и код файловых систем, реализована в виде работающего в пространстве пользователя unikernel, не привязанного к ядру ОС и системным библиотекам. Данную систему можно рассматривать как аналог проектов для запуска приложений поверх гипервизора, но вместо гипервизора Nabla использует обычные механизмы контейнерной изоляции с жесткой блокировкой доступа к системным вызовам при помощи фильтров seccomp.
В качестве основы в окружениях Nabla задействованы наработки открытого компанией IBM проекта Solo5, предоставляющего изолированное окружение для запуска произвольных unikernel, в том числе развиваемых проектами Rump, MirageOS и IncludeOS. Вся необходимая системная функциональность прикрепляется к приложению во время сборки. Среди протестированных приложений Nginx, Python, Redis и Node.js, для которых подготовлены типовые образы контейнеров. Для запуска контейнеров применяется runtime runnc (переработанный runc), интегрируемый с инструментарием Docker и совместимый со спецификацией
OCI (Open Container Initiative).
Для анализа безопасности была проведена оценка охвата привилегированного кода, который вовлекается при выполнении изолированных окружений. В частности, было посчитано число уникальных функций ядра, которые были вызваны в процессе работы окружений с Redis, Python и Node.js. Для контейнеров при помощи ftrace учитывалось число выполненных системных вызовов, а для систем виртуализации число гипервызовов и обращений к бэкендам, выполняемым на стороне kvm vhost или Xen dom0.
В результате в Nabla было зафиксировано в 2-3 раза меньше вызовов по сравнению с другими механизмами изоляции, в том числе по сравнению с gVisor (используется собственное мини-ядро на языке Go, предоставляющее необходимые системные вызовы) и Kata Containers (применяется урезанный вариант обычного ядра Linux).
Измерение производительности тестовых заданий на базе Redis, Python и Node.js показало, что показатели конетейнеров Nabla сравнимы с Kata Containers и отстают от Docker на 10-30%. Узким местом Nabla стала реализация сетевого стека в пространстве пользователя. При использовании конфигурации с оркестровкой контейнера напрямую (nabla-raw) без сетевого взаимодействия, производительность Nabla достигла уровня Docker. Низкая производительность gVisor объясняется большими накладными расходами при использовании ptrace и гипервызовов (gVisor-kvm) для привязки системных вызовов к изолированному окружению.
|