Проверка образов Docker на уязвимости с Clair

2016/03/24

Ни для кого не секрет, что контейнеры (и в частности Docker) не только решают много проблем (configuration drift, scalability, dependency hell), но и привносят новые (в частности, обновление базовых образов).

Я уже давно мониторил IT-мир на предмет появления хорошего инструмента для проверки Docker-образов на наличие известных CVE. До недавнего времени подходящего инструмента не было. Была парочка дистро-специфичных инструментов (например oscap-docker, с которым я помучался и забил), но ничего подходящего.

Но недавно (19.03.2016) CoreOS выпустил первый стабильный релиз инструмента под названием Clair, который как раз и предназначен для проверки образов Docker и appc, и поддерживает Debian, Ubuntu и RedHat.

К продуктами от создателей CoreOS я отношусь с нескрываемым подозрением, однако за неимением альтернатив решил попробовать.

К моему удивлению, оно работает. Конечно, все еще сыро - например, можно проверять образ на наличие уязвимостей, когда Clair еще даже не скачало базу этих самых уязвимостей, и получить отличный результат - все чисто.

А утилита для проверки образов из консоли не убирается за собой в /tmp, потому что разработчики не знают, что в Go вызов os.Exit() пропускает все defer-функции.

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

Так что после непродолжительных игрищ с Clair я прикрутил его к нашему CI-серверу (Jenkins), и настроил регулярную проверку наших базовых образов.

Выглядит это как-то так:

image="$name:$version"
echo "pulling image $image"
pull=$(docker pull "$image" >/dev/null)
if [ 0 -ne $? ]; then
  echo "pull failed!"
  echo "$pull" | tail -n 20
  exit 1
fi
echo "analyzing $image"
out=$(analyze-local-images \
  -minimum-severity High \
  -endpoint http://clair.ip.address.here:6060 \
  -my-address own.ip.address.here \
  "$image" 2>&1)
status=$?

# cleanup is done separately, with docker-gc running on cron
# docker rmi "$image"
if [ 0 -ne $status ]; then
  echo "analyze failed!"
  echo "$report"
  exit 1
fi

report=$(echo "$out" | grep -A 10000 'Clair report for image')
echo "$report" | grep CVE >/dev/null
found_cve=$?
if [ 0 -eq $found_cve ]; then
  echo "$report"
  exit 1
fi

echo "$report"

Использую пока такой-вот скрипт-обертку вокруг консольной утилиты, хотя наличие у Clair вменяемого API очень сильно радует.

Из минусов (кроме относительной сырости) - использование API требует хорошего копания в кишках образа контейнера, что для Docker чревато поломкой в каком-либо новом релизе.

Но сам факт, что наконец-то появился такой инструмент очень радует, и хочется надеяться на скорую его интеграцию в registry (уже есть в dockyard) и CI-pipeline.

Tags: Clair Docker CoreOS

Categories: IT Russian