Блокером оказался не ClickHouse#
Кейс Docker про hardened image для ClickHouse описывает знакомый сбой на пути в production: контейнер работает, база данных готова, а релиз всё равно блокируется, потому что image не проходит сканирование на уязвимости.
По данным Docker, пример касался команды, которая готовила production deployment в Kubernetes и загружала ClickHouse image в AWS ECR. Scanner сообщил о трёх critical vulnerabilities. Docker утверждает, что находки были не в самом ClickHouse, а в base image, который использовался для его упаковки.
Технически эта разница важна, но на release gate она может не помочь. Многие security programs считают critical CVEs в images, предназначенных для production, блокерами. Тогда application team приходится доказывать, что уязвимость non-exploitable, запрашивать exception, пересобирать image или откладывать deployment.
Главный урок шире, чем продуктовый pitch Docker: проблемы container security часто оказываются проблемами упаковки. Уязвимый компонент может присутствовать только потому, что его принесла базовая distribution.
Почему полные base images создают шумный, но реальный риск#
Docker пишет, что стандартный image clickhouse/clickhouse-server построен на Ubuntu 22.04. Полная distribution base удобна: в ней есть привычные tools, package management, shells, system utilities и широкая совместимость.
Но вместе с этим она включает packages, которые приложению могут быть не нужны.
Docker приводит примеры вроде Perl, system utilities, apt и transitive dependencies. ClickHouse может не использовать многие из этих компонентов при обычной работе, но scanners вроде Trivy, Grype и AWS ECR image scanning проверяют то, что присутствует в image. Они не всегда надёжно определяют, достижим ли vulnerable package в конкретном workload path.
С точки зрения application team находка может казаться нерелевантной: database не использует затронутую utility. С точки зрения security team vulnerable package присутствует в production image, а scanner помечает его как critical. Если attacker получит execution внутри container, даже неиспользуемые tools могут стать полезными tools.
Risk exceptions могут быть оправданными, но они дорогие. Кому-то нужно сопоставить CVEs с packages, оценить reachability, задокументировать compensating controls и получить approval. Эта работа повторяется, когда scanners обновляются, base images меняются или публикуются новые CVEs. Часто проще удалить ненужные packages, чем снова и снова объяснять, почему они там есть.
Что меняет hardened image#
Docker пишет, что его hardened ClickHouse image начинается с более узкого вопроса: что нужно ClickHouse для работы в production?
Это отличается от подхода, где берут general-purpose Linux base и принимают всё, что в неё входит. В посте говорится, что Docker Hardened Images сокращают runtime image до необходимых компонентов и исключают tools, которые не нужны в production.
Одно важное изменение — отсутствие package manager в runtime. Без apt attacker, который закрепился внутри container, с большим трудом сможет установить дополнительные инструменты изнутри image.
Docker также указывает на удаление network utilities, например wget. В посте говорится, что стандартный ClickHouse image содержал wget с unpatched issue, потому что upstream fix отсутствовал. Hardened-подход Docker состоит не в том, чтобы patch этот tool внутри image, а в том, чтобы не поставлять его, если ClickHouse он не нужен.
Практический паттерн простой:
- удалять package managers из production images;
- удалять network download tools, если workload их не требует;
- не включать debugging utilities в runtime images;
- отделять удобство разработки от production surface area;
- сокращать количество packages, которые scanners могут пометить.
Docker пишет, что shell остаётся доступным для operational work. Это всё ещё tradeoff, но без package manager и распространённых download tools image меньше помогает attacker после compromise.
Встройте разделение dev/runtime в pipeline#
Минимальные production images могут создать трение, если появляются слишком поздно. Developers тестируют в одной среде, security approves другую, а production ведёт себя иначе.
Кейс Docker описывает два варианта image: development image с дополнительными tools для local testing и debugging, а также runtime image, где большая часть этой surface удалена для production deployment.
Смысл workflow — тестировать hardened runtime image до финального security gate. Если первое серьёзное scan происходит только тогда, когда image попадает в ECR, команда может оказаться перед срочным exception, rebuild или delay. Если более компактная runtime base встроена в pipeline раньше, scanner output должен быть менее шумным, а оставшиеся findings — с большей вероятностью действительно важными.
Это само по себе не делает ClickHouse secure. Такой подход не заменяет ClickHouse configuration, network controls, authentication, encryption, Kubernetes policy, secret handling, backups или monitoring. Он также не гарантирует, что будущие scanners всегда будут показывать ноль findings.
Он меняет baseline. В image остается меньше packages, меньше inherited CVEs, меньше удобных post-exploitation tools и меньше спорных exceptions перед релизом.
Практические проверки для production containers#
Перед тем как спорить с scanner output, проверьте сам image.
- Нужна ли workload полноценная Linux distribution?
- Есть ли в runtime package manager?
- Есть ли download tools вроде
wgetилиcurl, если приложение ими не пользуется? - Попали ли debugging utilities в production image?
- Разделены ли dev image и runtime image?
- Можно ли воспроизвести build и понять, откуда пришел каждый package?
- Показывает ли scanner CVEs в компонентах, которые можно просто удалить?
Если ответ “мы не знаем”, проблема не только в CVE. Проблема в том, что container больше похож на маленький general-purpose server, чем на минимальный runtime artifact.
Что не стоит переобещать#
Hardened base image не делает приложение безопасным автоматически. Minimal image может всё равно содержать уязвимую application configuration, слабую authentication model, открытый network policy или неправильно обработанные secrets.
Также не стоит превращать scanner score в единственный критерий. Zero critical CVEs в base image не означает zero risk. Но если production image несет десятки ненужных packages, security team справедливо спросит, зачем они там.
Лучший результат — не красивый badge, а понятный release process: image scan происходит рано, findings разбираются по источнику, ненужные components удаляются, exceptions документируются, а runtime image остается достаточно малым, чтобы его можно было объяснить.
Вывод#
История с ClickHouse показывает типичный container-security урок: уязвимость в scanner output не всегда находится в приложении, но она все равно может блокировать production release.
Командам стоит относиться к base image как к части продукта. Если package не нужен runtime, его присутствие создает лишний audit burden и иногда реальный post-compromise risk. Минимальный production image не заменяет security engineering, но он убирает шум и уменьшает поверхность атаки до того, что команда действительно собиралась запускать.