containers
Получить список всех образов и их тегов из docker registry
- Установить утилиту crane
- При необходимости залогиниться в registry с помощью docker или crane
- Выполнить скрипт, формирующий файл со списком
REGISTRY_URL="registry.home.arpa"
cat /dev/null > catalog.txt
for image in $(crane catalog ${REGISTRY_URL}); do
for tag in $(crane ls "${REGISTRY_URL}/${image}"); do
echo "${REGISTRY_URL}/${image}:${tag}" >> catalog.txt
done
done
- (Опционально) Посчитать количество существующих тегов для каждого образа
cat catalog.txt | awk -F':' '{print $1$2}' | sort -n | uniq -c | sort -k1 -n
Посчитать занимаемое место образами в docker registry
Слои файловой системы могут переиспользоваться в разных образах. Поэтому это примерная информация о занимаемом месте
- Установить утилиту crane
- При необходимости залогиниться в registry с помощью docker или crane
- Посчитать суммарный размер слоёв каждого образа по тегу
REGISTRY_URL="registry.home.arpa"
IMAGE="service01"
cat /dev/null > size_images.txt
for tag in $(crane ls "${REGISTRY_URL}/${IMAGE}"); do
img="${REGISTRY_URL}/${IMAGE}:${tag}"
size="$(crane manifest "${img}" | jq -r '[.layers[].size | tonumber] | add')"
echo "${img} ${size}" >> size_images.txt
done
- При необходимости получить суммарный размер
cat size_images.txt | sort -rn | uniq | awk '{size+=$2;} END{print size;}'
Посчитать, сколько весят и как часто переиспользуются между тегами слои образов
- Установить утилиту crane
- При необходимости залогиниться в registry с помощью docker или crane
- Получить размеры всех слоёв образов для всех тегов
REGISTRY_URL="registry.home.arpa"
IMAGE="service01"
cat /dev/null > layers_size.txt
for tag in $(crane ls "${REGISTRY_URL}/${IMAGE}"); do
img="${REGISTRY_URL}/${IMAGE}:${tag}"
crane manifest "${img}" | jq -r '.layers[] | [.digest, .size] | @tsv' >> layers_size.txt
done
- Получить список уникальных слоёв с размерами этих слоёв и количеством переиспользования
cat layers_size.txt | sort -n | uniq -c | awk '{print $2" "$3/1024/1024" "$1}' | sort -k2 -n > unique_layers_size.txt
Почистить образы из docker registry (на Nexus)
Каждый образ - это некий конечный объект с уникальной sha256 суммой (digest). Образ скачивается указанием его дайджейста. Для удобства на дайджейсты навешивают человекочитаемые теги. Их можно навесить сколько угодно на один дайджест
docker pull centos@sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4 docker pull centos:7.9.2009 docker pull centos:7Чтобы удалить образы, нам нужно удалять их по дайджестам, а затем средствами Nexus подчистить “осиротевшие” теги, которые не ссылаются ни на какой дайджест, после чего выполнить compact blobstore
- Установить утилиту crane
- При необходимости залогиниться в registry с помощью docker или crane
- Сформировать список всех тегов целевого образа
REGISTRY_URL="registry.home.arpa"
IMAGE="service01"
cat /dev/null > all_tags.txt
for tag in $(crane ls "${REGISTRY_URL}/${IMAGE}"); do
echo "${REGISTRY_URL}/${IMAGE}:${tag}" >> all_tags.txt
done
- Сформировать список НУЖНЫХ тегов целевого образа
Тут, по сути, надо из всех тегов выделить те теги, которые нужно оставить. Например, исключить все, которые заканчиваются на PIPELINE_ID (5,6 - значный из gitlab)
grep -vE '^.+[0-9]{5,6}$' all_tags.txt > keep_tags.txt - Получить список уникальных дайджестов для всех тегов
REGISTRY_URL="registry.home.arpa"
IMAGE="service01"
cat /dev/null > all_digests.txt
for image in $(cat all_tags.txt); do
echo "${REGISTRY_URL}/${IMAGE}@$(crane digest $image)" >> all_digests.txt;
done
sort -n all_digests.txt | uniq > all_digests_unique.txt
- Получить список уникальных дайджестов для НУЖНЫХ тегов
REGISTRY_URL="registry.home.arpa"
IMAGE="service01"
cat /dev/null > keep_digests.txt
for image in $(cat keep_tags.txt); do
echo "${REGISTRY_URL}/${IMAGE}@$(crane digest $image)" >> keep_digests.txt;
done
sort -n keep_digests.txt | uniq > keep_digests_unique.txt
- Выбрать из списка всех дайджейстов те, которых нет в списке НУЖНЫХ дайджестов
Флаг -u для uniq после сортировки двух списков выведет только те элементы, которые встречаются только один раз
sort -n all_digests_unique.txt keep_digests_unique.txt | uniq -u > delete_digests.txt - Удалить ненужные дайджесты
for digest in $(cat delete_digests.txt); do
crane delete $digest;
done
- Запустить в Nexus таску для удаления “осиротевших” тегов (Docker - Delete unused manifests)
- Запустить compact соответствующего blobstore (Admin - Compact blob store)
Варианты запуска сборок
Shell executor
- Небезопасно, т.к. можно выполнять какие угодно docker команды на хосте, в т.ч. пробрасывать хостовые папки и запускать privileged контейнеры
docker-in-docker
- Изолированные друг от друга контейнеры, т.к. здесь child контейнеры от контейнера dind, а не от хостового docker.sock
- Необходим запуск с privileged (небезопасно)
Проброс docker.sock
- Все контейнеры - siblings (видят друг друга), т.к. запускается через хостовый docker
- Небезопасно, т.к. можно выполнять какие угодно docker команды на хосте, в т.ч. пробрасывать хостовые папки и запускать privileged контейнеры
buildah/buildkit/img
- Позволяют внутри докер контейнера запускать сборку образа без докер-демона
- Требуется unprivileged_userns_clone (user namespaces), у которого свои security-риски
- Синтаксис запуска отличается -> переучивать команду
kaniko
- Позволяют внутри докер контейнера запускать сборку образа без докер-демона
- Не поддерживается установка бинарника в свой образ. Необходимо использовать официальный образ
- Синтаксис запуска отличается -> переучивать команду
Потенциальные векторы атаки
Источник
- В сборке используется публичный образ, в котором в entrypoint выполняется команда проверки docker.sock и запуск контейнера через него
- При сборке в зависимостях (напрмер, node) скачивается зловред, который запускается в процессе сборки. Далее проверка docker.sock и запуск контейнера через него
Цель
- Закрепиться в системе. Через докер возможно установить свои бинарники и сервисы в систему
- Дальнейший скан сети и поиск уязвимостей для распространения и закрепления
