Java-контейнеры без уязвимости: практическое руководство

В современном местном ландшафте облака защита Java -приложений — это не только код, который мы пишем, а весь стек контейнеров. В то время как Java сохранила сильную запись безопасности, такие инциденты, как Log4shell, показали нам, что бдительность имеет решающее значение. Нам нужен комплексный подход к предотвращению уязвимостей, от изображения базового контейнера Java JRE до наших зависимостей приложения Java и самого кода приложения.

В прошлом году я работал с клиентом, который жаловался на уязвимости в их базовом изображении контейнеров для node.js. Это заставило меня проводить больше исследований базовых изображений, включая Java.

Состояние Java Container Images

Я обследовал популярные изображения на основе контейнеров на Java, используя открытый исходный код грип Сканер уязвимости. Результаты были открыты глазами:

  • Почти все базовые изображения, в том числе от основных поставщиков, содержали несколько уязвимостей
  • Уязвимость варьировалось от нескольких до сотен!
  • Только одно базовое изображение имело нулевые уязвимости: базовое изображение Chainguard’s Jre

Вот результаты опроса по состоянию на 7 февраля 2025 года:

JRE Image Уязвимости Уязвимости Изображения Размер изображения (Uncompressed) mcr.microsoft.com/openjdk/jdk-21-distroless:latest 5 критические 13 высокие 8 среды 0 низкий 331 МБ битнам/Java: последние 3 критические 139 Высокие 363 Среда 17 Low 629 МБ Openjdk: 23-lem (спредит) 3 Критические 3 27 Medium 9 Low 46M 46 МБ. gcr.microsoft.com/openjdk/java21-debian12:latest 1 Critical 2 High 1 Medium 0 Low 202MB openjdk:latest (Deprecated) 0 Critical 24 High 56 Medium 33 Low 487MB ibm-semeru-runtimes:open-23-jre 25 Medium 34 Low 282MB eclipse-temurin:latest 43 Medium 37 Low 478MB Eclipse-Temurin: 23-jre-alpine 7 Среда 11 Низкий 205 МБ контейнер-регистрация.oracle.com/java/openjdk:latest 5 средний 686 МБ Bellsoft/Liberica-openjre-alpine: Последние 2 средние 149 МБ Amazoncorto: Medium 266mb Amazoncorrretto: 23-ALPIN Chainguard/Jre: Последний 0 226 МБ

Учитывая, что изображение Java Jre Java Jre является единственным без уязвимостей, вы можете быть вынуждены попробовать его. А последний Тег бесплатный, но другие теги для конкретных версий Java требуют подписки Chainguard. Тем не менее, это изображение является отличным вариантом, если вы можете запустить новейшую версию Java JRE (в настоящее время 23).

Если вы хотите ориентироваться на конкретную версию Java, а ваша организация не использует Chainguard, моей рекомендацией будет Amazon Corretto. Я использую Corretto более двух лет без проблем, и их изображения солидны с низким количеством уязвимостей. Corretto может быть заменен в качестве базового изображения так же, как и Chainguard, как показано в этом руководстве.

Варианты сборки контейнеров Java

Чтобы упаковать изображение контейнера для вашего приложения Java, есть несколько вариантов, которые включают в себя:

  • Традиционный Dockerfile: Несмотря на то, что этот подход часто приводит к неэффективному сложности изображения и требует докера (или эквивалентного) демона для сборки.
  • Облачные нативные сборы: Интеграция BuildPack предлагает удобный путь, но не может легко настроить базовое изображение.
  • Google Jib: Обтекаемый плагин, который предлагает без демонов сборки, эффективное наслоение и гибкость базового изображения.

Для моего демонстрационного приложения Java (Spring Boot), которое предоставляется на GitHub, JIB является предпочтительным подходом по сборке контейнеров, но в качестве альтернативы также предоставляется DockerFile. Если вы хотите понять, как работает слоя изображения Jib, пожалуйста, посмотрите Readme моего демонстрационного приложения для того, как использовать погружение Чтобы изучить слои изображения вашего контейнера.

Создание изображения контейнера с нулевой Vulenerability

Используя базовое изображение JRE’s JRE’s JRE и плагин Google Jib Maven, давайте создадим контейнер для приложений Java с нулевыми уязвимостями. Если вы используете Gradle, плагин Jib Gradle будет работать так же, как и плагин Maven.

1. Настройте JIB в вашем проекте Maven

Чтобы изменить базовое изображение на изображение Chainguard Jre, добавьте следующую конфигурацию плагина Jib Maven в свой Pom.xml как сделано в демонстрационном приложении:

chainguard/jre: последний … 1234 chainguard/jre: последний …

Образец DockerFile с использованием базового изображения JRE Chainguard предоставляется, если вы предпочитаете не использовать JIB.

2. Создайте изображение контейнера

Запустите следующую команду Maven Jib для создания локального изображения контейнера для демонстрационного приложения (требует Docker):

./mvnw jib: dockerbuild 1 ./mvnw jib: dockerbuild

При использовании DockerFile вместо JIB см. Demo Application Readme для получения дополнительных инструкций о том, как построить изображение контейнера с помощью Docker BuildПолем

3. Проверьте нулевые уязвимости

Теперь, с созданным изображением, вы можете использовать грип Чтобы отсканировать недавно построенное изображение, которое находится на вашей локальной машине:

Grype docker.io/your-id/your-image:latest 1 grype docker.io/your-id/your-image:latestest

С последний Базовое изображение Chainguard и все зависимости Maven обновлены, вы должны увидеть следующий результат: уязвимостей не найдено

✔ Загруженное изображение docker.io/your-id/your-image:latest ✔ Parsed Image SHA256: 18F64293E66F391C41E7363C989687B852203E0FB9C32744F0C5D7B80A0E7F79 ✔ CATALOGED CONTERTED 0B944452BAEFA268F36E01336D79D0FB1FC35F13BEF0C11C262D3EF2C9E46D06 [74 packages]
File Digests [1,186 files]
├ack Metadata [1,186 locations]
Exectedables [121 executables]
✔ Оканируется на предмет уязвимостей [0 vulnerability matches]
├—í по серьезности: 0 Критическая, 0 высокая, 0 средняя, ​​0 низкая, 0 незначительная └мобил: 0 Статус: 0 Исправлено, 0 не сфокусировано, 0 игнорируется никаких уязвимостей, найденных 1234567891011 ✔ Загруженное изображение Docker.io/your-id/your-image:latest ✔ SHA256: 18F64293E66F391C41E7363C989687B852203E0FB9C32744F0C5D7B80A0E7F79 0B944452BAEFA268F36E01336D79D0FB1FC35F13BEF0C11C262D3EF2C9E46D06 [74 packages] File Digests [1,186 files] ├ack Metadata [1,186 locations] Exectedables [121 executables] ✔ Оканируется на предмет уязвимостей [0 vulnerability matches] ├ack по серьезности: 0 Критическая, 0 высокая, 0 средняя, ​​0 низкая, 0 незначительное └—½ по статусу: 0 исправлено, 0 не фиксирован, 0 игнорируется никаких уязвимостей, не найденных

Упреждающее обнаружение уязвимости с помощью SBOMS

Вместо того, чтобы ждать до времени настройки контейнера, вы можете поймать уязвимости ранее в своем цикле разработки, генерируя и сканируя счет материалов программного обеспечения (SBOM). Этот SBOM отражает все зависимости вашего приложения в стандартизированном формате JSON, который можно прочитать с помощью обычно используемых инструментов сканирования, как грипПолем

CyclonedX предлагает плагин Maven (или плагин Gradle) для создания SBOM на основе дерева зависимости вашего приложения. Добавьте следующий плагин в свой Pom.xml:

org.cyclonedx cyclonedx-maven-plugin 1234 org.cyclonedx cyclonenx-maven-plugin

Теперь вы можете сканировать зависимости приложения перед контейнеризацией, используя грип:

Grype Target/Classes/Meta-Inf/SBOM/Application.cdx.json ✔ Сканируется на предмет уязвимостей [4 vulnerability matches]
├ack По строй: 0 Критическая, 2 высокая, 1 среда, 1 низкий, 0 незначительный └ack └мобил: 4 Фиксированное, 0 не фиксированное, 0 Игнорированное имя установленное фиксированное в типе ядра. GHSA-6v67-2wr5-gvf4 Low tomcat-embed-core 10.1.33 10.1.34 java-archive GHSA-5j33-cvvr-w245 High tomcat-embed-core 10.1.33 10.1.34 java-archive GHSA-27hp-xhwr-wr2m High 123456789 grype Target/Classes/Meta-Inf/SBOM/Application.cdx.json ✔ Сканируется на предмет уязвимостей [4 vulnerability matches] ├ack По строй: 0 Критическая, 2 высокая, 1 среда, 1 низкий, 0 незначительный └ack └мобил: 4 Фиксированное, 0 не фиксированное, 0 Игнорированное имя установленное фиксированное в типе ядра. GHSA-6V67-2WR5-GVF4 Low Tomcat-Embed-Core 10.1.33 10.1.34 Java-Archive GHSA-5J33-CVVR-W245 High Tomcat-Embed-Core 10.1.33 10.1.34

Как видите в этом случае, SBOM и грип обнаружил устаревшую версию Tomcat в Spring Boot 3.4.0 с двумя Высокий уязвимости. Классная вещь о подходе SBOM заключается в том, что вы можете стандартизировать один инструмент сканирования уязвимости, подобный такому грип как для SBOM, так и для изображений. Как правило, для Java инструменты проверки уязвимостей отделены от инструментов сканирования изображений контейнеров, поэтому может быть полезна консолидация к одному инструменту сканирования уязвимости.

Заключение

В то время как Chainguard в настоящее время предлагает единственное базовое изображение Java с нулевой Vulnerbility, другие поставщики изображений делают прогресс по сокращению количества уязвимостей. Тем не менее, все еще необходима комплексная стратегия безопасности, которая включает в себя:

  • Тщательный выбор базового изображения
  • Регулярные изображения сканирования уязвимости
  • Генерация SBOM и сканирование
  • Автоматизированные процессы обновления зависимостей (т.е. Devingabot)

Следуя этой практике и используя современные инструменты, вы можете создавать и поддерживать контейнерные Java -приложения, которые запускаются и остаются в безопасности. Будьте в курсе новых уязвимостей, обновляйте ваши зависимости и регулярно просматривайте свою позицию в области безопасности, чтобы сохранить сильную позицию безопасности для ваших заявок на Java.

Trending Stories youtube.com/thenewstack Tech движется быстро, не пропустите эпизод. Подпишитесь на наш канал YouTube, чтобы транслировать все наши подкасты, интервью, демонстрации и многое другое. Группа подпишитесь с эскизом. Эрик любит думать об общей картине о дизайне программного обеспечения и о том, как технологии могут решить бизнес -проблемы. В прошлом Эрик проводил семинары по таким темам, как Kubernetes, Java и Domain Design. Кроме того, Эрик — опубликованный автор через О’Рейли … Подробнее от Эрика Мерфи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *