Docker Security
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools. Get Access Today:
Docker engine використовує Namespaces та Cgroups ядра Linux для ізоляції контейнерів, пропонуючи базовий рівень безпеки. Додатковий захист забезпечується через Capabilities dropping, Seccomp та SELinux/AppArmor, що покращує ізоляцію контейнерів. Auth plugin може ще більше обмежити дії користувачів.
Docker engine може бути доступний локально через Unix-сокет або віддалено за допомогою HTTP. Для віддаленого доступу важливо використовувати HTTPS та TLS для забезпечення конфіденційності, цілісності та автентифікації.
Docker engine за замовчуванням слухає на Unix-сокеті за адресою unix:///var/run/docker.sock
. На системах Ubuntu параметри запуску Docker визначені в /etc/default/docker
. Щоб увімкнути віддалений доступ до Docker API та клієнта, відкрийте демон Docker через HTTP-сокет, додавши наступні налаштування:
Однак, відкриття Docker-демона через HTTP не рекомендується через проблеми безпеки. Рекомендується захищати з'єднання за допомогою HTTPS. Існує два основних підходи до забезпечення безпеки з'єднання:
Клієнт перевіряє особу сервера.
Як клієнт, так і сервер взаємно аутентифікують особу один одного.
Сертифікати використовуються для підтвердження особи сервера. Для детальних прикладів обох методів зверніться до цього посібника.
Контейнерні образи можуть зберігатися в приватних або публічних репозиторіях. Docker пропонує кілька варіантів зберігання для контейнерних образів:
Docker Hub: Публічна реєстраційна служба від Docker.
Docker Registry: Проект з відкритим вихідним кодом, що дозволяє користувачам хостити власну реєстрацію.
Docker Trusted Registry: Комерційна реєстрація Docker, що пропонує аутентифікацію користувачів на основі ролей та інтеграцію з службами каталогів LDAP.
Контейнери можуть мати вразливості безпеки як через базовий образ, так і через програмне забезпечення, встановлене поверх базового образу. Docker працює над проектом під назвою Nautilus, який виконує сканування безпеки контейнерів і перераховує вразливості. Nautilus працює, порівнюючи кожен шар образу контейнера з репозиторієм вразливостей для виявлення дірок у безпеці.
Для отримання більшої інформації прочитайте це.
docker scan
Команда docker scan
дозволяє вам сканувати існуючі образи Docker, використовуючи ім'я або ID образу. Наприклад, виконайте наступну команду, щоб просканувати образ hello-world:
Docker image signing забезпечує безпеку та цілісність зображень, що використовуються в контейнерах. Ось стисле пояснення:
Щоб активувати довіру до вмісту Docker, встановіть export DOCKER_CONTENT_TRUST=1
. Ця функція за замовчуванням вимкнена в Docker версії 1.10 і пізніше.
З цією функцією, лише підписані зображення можуть бути завантажені. Перший пуш зображення вимагає встановлення паролів для кореневого та тегуючого ключів, при цьому Docker також підтримує Yubikey для підвищення безпеки. Більше деталей можна знайти тут.
Спроба витягти непідписане зображення з увімкненою довірою до вмісту призводить до помилки "No trust data for latest".
Для пушів зображень після першого, Docker запитує пароль для ключа репозиторію, щоб підписати зображення.
Щоб зробити резервну копію ваших приватних ключів, використовуйте команду:
Коли ви перемикаєте Docker хости, необхідно перемістити ключі root і репозиторію для підтримки роботи.
Використовуйте Trickest, щоб легко створювати та автоматизувати робочі процеси, що працюють на основі найсучасніших інструментів спільноти. Отримайте доступ сьогодні:
Namespaces - це функція ядра Linux, яка розділяє ресурси ядра так, що один набір процесів бачить один набір ресурсів, тоді як інший набір процесів бачить інший набір ресурсів. Функція працює, маючи один і той же простір імен для набору ресурсів і процесів, але ці простори імен посилаються на різні ресурси. Ресурси можуть існувати в кількох просторах.
Docker використовує наступні простори імен ядра Linux для досягнення ізоляції контейнерів:
pid namespace
mount namespace
network namespace
ipc namespace
UTS namespace
Для додаткової інформації про простори імен перегляньте наступну сторінку:
NamespacesФункція ядра Linux cgroups надає можливість обмежувати ресурси, такі як cpu, пам'ять, io, мережеву пропускну здатність серед набору процесів. Docker дозволяє створювати контейнери, використовуючи функцію cgroup, яка дозволяє контролювати ресурси для конкретного контейнера. Наступний контейнер створено з обмеженням пам'яті користувацького простору до 500m, обмеженням пам'яті ядра до 50m, часткою cpu до 512, blkioweight до 400. Частка CPU - це співвідношення, яке контролює використання CPU контейнером. Воно має значення за замовчуванням 1024 і діапазон від 0 до 1024. Якщо три контейнери мають однакову частку CPU 1024, кожен контейнер може використовувати до 33% CPU у разі конкуренції за ресурси CPU. blkio-weight - це співвідношення, яке контролює IO контейнера. Воно має значення за замовчуванням 500 і діапазон від 10 до 1000.
Щоб отримати cgroup контейнера, ви можете зробити:
Для отримання додаткової інформації перегляньте:
CGroupsМожливості дозволяють більш детальний контроль за можливостями, які можуть бути дозволені для користувача root. Docker використовує функцію можливостей ядра Linux, щоб обмежити операції, які можуть виконуватися всередині контейнера, незалежно від типу користувача.
Коли запускається контейнер Docker, процес скидає чутливі можливості, які процес міг би використовувати для втечі з ізоляції. Це намагається забезпечити, що процес не зможе виконувати чутливі дії та втекти:
Linux CapabilitiesЦе функція безпеки, яка дозволяє Docker обмежити системні виклики, які можуть використовуватися всередині контейнера:
SeccompAppArmor є покращенням ядра для обмеження контейнерів до обмеженого набору ресурсів з профілями для кожної програми.:
AppArmorСистема маркування: SELinux призначає унікальну мітку кожному процесу та об'єкту файлової системи.
Виконання політики: Він забезпечує виконання політик безпеки, які визначають, які дії може виконувати мітка процесу на інших мітках у системі.
Мітки процесів контейнера: Коли контейнерні движки ініціюють процеси контейнера, їм зазвичай призначається обмежена мітка SELinux, зазвичай container_t
.
Маркування файлів у контейнерах: Файли всередині контейнера зазвичай маркуються як container_file_t
.
Правила політики: Політика SELinux в основному забезпечує, що процеси з міткою container_t
можуть взаємодіяти (читати, писати, виконувати) лише з файлами, маркованими як container_file_t
.
Цей механізм забезпечує, що навіть якщо процес у контейнері буде скомпрометований, він обмежений у взаємодії лише з об'єктами, які мають відповідні мітки, значно обмежуючи потенційні збитки від таких компрометацій.
SELinuxУ Docker плагін авторизації відіграє вирішальну роль у безпеці, вирішуючи, чи дозволити або заблокувати запити до демона Docker. Це рішення приймається шляхом аналізу двох ключових контекстів:
Контекст аутентифікації: Це включає в себе всебічну інформацію про користувача, таку як хто вони і як вони аутентифікувалися.
Контекст команди: Це містить усі відповідні дані, пов'язані із запитом, що робиться.
Ці контексти допомагають забезпечити, що лише законні запити від аутентифікованих користувачів обробляються, підвищуючи безпеку операцій Docker.
AuthZ& AuthN - Docker Access Authorization PluginЯкщо ви не обмежуєте належним чином ресурси, які може використовувати контейнер, скомпрометований контейнер може здійснити DoS на хост, на якому він працює.
CPU DoS
Витрата пропускної здатності DoS
На наступній сторінці ви можете дізнатися що означає прапорець --privileged
:
Якщо ви запускаєте контейнер, в якому зловмисник зміг отримати доступ як користувач з низькими привілеями. Якщо у вас є неправильно налаштований suid бінарний файл, зловмисник може зловживати ним і ескалацію привілеїв всередині контейнера. Це може дозволити йому втекти з нього.
Запуск контейнера з увімкненою опцією no-new-privileges
запобігатиме такій ескалації привілеїв.
Для отримання додаткових опцій --security-opt
перегляньте: https://docs.docker.com/engine/reference/run/#security-configuration
Важливо уникати вбудовування секретів безпосередньо в образи Docker або використання змінних середовища, оскільки ці методи піддають вашу чутливу інформацію ризику для будь-кого, хто має доступ до контейнера через команди, такі як docker inspect
або exec
.
Docker volumes є більш безпечною альтернативою, рекомендованою для доступу до чутливої інформації. Їх можна використовувати як тимчасову файлову систему в пам'яті, зменшуючи ризики, пов'язані з docker inspect
та веденням журналів. Однак, користувачі з правами root та ті, хто має доступ до exec
контейнера, все ще можуть отримати доступ до секретів.
Docker secrets пропонують ще більш безпечний метод для обробки чутливої інформації. Для екземплярів, які потребують секретів під час етапу побудови образу, BuildKit пропонує ефективне рішення з підтримкою секретів під час побудови, що підвищує швидкість побудови та надає додаткові функції.
Щоб скористатися BuildKit, його можна активувати трьома способами:
Через змінну середовища: export DOCKER_BUILDKIT=1
Додаючи префікс до команд: DOCKER_BUILDKIT=1 docker build .
Увімкнувши його за замовчуванням у конфігурації Docker: { "features": { "buildkit": true } }
, після чого потрібно перезапустити Docker.
BuildKit дозволяє використовувати секрети під час побудови з опцією --secret
, забезпечуючи, щоб ці секрети не були включені в кеш побудови образу або в фінальний образ, використовуючи команду:
Для секретів, необхідних у запущеному контейнері, Docker Compose і Kubernetes пропонують надійні рішення. Docker Compose використовує ключ secrets
у визначенні служби для вказівки секретних файлів, як показано в прикладі docker-compose.yml
:
Ця конфігурація дозволяє використовувати секрети при запуску сервісів за допомогою Docker Compose.
У середовищах Kubernetes секрети підтримуються нативно і можуть бути додатково керовані за допомогою інструментів, таких як Helm-Secrets. Контроль доступу на основі ролей (RBAC) у Kubernetes підвищує безпеку управління секретами, подібно до Docker Enterprise.
gVisor - це ядро програми, написане на Go, яке реалізує значну частину системної поверхні Linux. Воно включає в себе Open Container Initiative (OCI) середовище виконання під назвою runsc
, яке забезпечує межу ізоляції між додатком і ядром хоста. Середовище виконання runsc
інтегрується з Docker і Kubernetes, що спрощує запуск пісочницьких контейнерів.
Kata Containers - це спільнота з відкритим кодом, яка працює над створенням безпечного середовища виконання контейнерів з легкими віртуальними машинами, які відчуваються і працюють як контейнери, але забезпечують сильнішу ізоляцію навантаження за допомогою технології апаратної віртуалізації як другого рівня захисту.
Не використовуйте прапор --privileged
або монтуйте сокет Docker всередині контейнера. Сокет Docker дозволяє створювати контейнери, тому це простий спосіб отримати повний контроль над хостом, наприклад, запустивши інший контейнер з прапором --privileged
.
Не запускайте як root всередині контейнера. Використовуйте іншого користувача і простори імен користувачів. Root у контейнері є тим самим, що і на хості, якщо не переназначений за допомогою просторів імен користувачів. Він лише слабо обмежений, в основному, просторами імен Linux, можливостями та cgroups.
Скиньте всі можливості (--cap-drop=all
) і активуйте лише ті, які необхідні (--cap-add=...
). Багато навантажень не потребують жодних можливостей, і їх додавання збільшує обсяг потенційної атаки.
Використовуйте опцію безпеки “no-new-privileges” для запобігання отриманню процесами більше привілеїв, наприклад, через двійкові файли suid.
Обмежте ресурси, доступні контейнеру. Обмеження ресурсів можуть захистити машину від атак відмови в обслуговуванні.
Використовуйте офіційні образи Docker і вимагайте підписів або створюйте свої на їх основі. Не успадковуйте або не використовуйте задні двері образи. Також зберігайте кореневі ключі, пароль у безпечному місці. Docker має плани з управління ключами за допомогою UCP.
Регулярно перебудовуйте свої образи, щоб застосовувати патчі безпеки до хоста та образів.
Розумно управляйте своїми секретами, щоб ускладнити доступ до них зловмиснику.
Якщо ви використовуєте демон Docker, використовуйте HTTPS з автентифікацією клієнта та сервера.
У вашому Dockerfile, надавайте перевагу COPY замість ADD. ADD автоматично розпаковує стиснуті файли і може копіювати файли з URL-адрес. COPY не має цих можливостей. Коли це можливо, уникайте використання ADD, щоб не піддаватися атакам через віддалені URL-адреси та Zip-файли.
Майте окремі контейнери для кожного мікросервісу.
Не ставте ssh всередині контейнера, “docker exec” можна використовувати для ssh до контейнера.
Майте менші образи контейнерів.
Якщо ви всередині контейнера Docker або маєте доступ до користувача в групі Docker, ви можете спробувати вийти та підвищити привілеї:
Docker Breakout / Privilege EscalationЯкщо у вас є доступ до сокета Docker або доступ до користувача в групі Docker, але ваші дії обмежуються плагіном автентифікації Docker, перевірте, чи можете ви обійти його:
AuthZ& AuthN - Docker Access Authorization PluginІнструмент docker-bench-security - це скрипт, який перевіряє десятки загальних найкращих практик щодо розгортання контейнерів Docker у виробництві. Тести повністю автоматизовані і базуються на CIS Docker Benchmark v1.3.1. Вам потрібно запустити інструмент з хоста, на якому працює Docker, або з контейнера з достатніми привілеями. Дізнайтеся, як його запустити в README: https://github.com/docker/docker-bench-security.
Використовуйте Trickest, щоб легко створювати та автоматизувати робочі процеси, що працюють на основі найсучасніших інструментів спільноти. Отримайте доступ сьогодні:
Вчіться та практикуйте Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Вчіться та практикуйте Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)