🛠 Сценарий для Docker CIS & Image Audit
Салют,
Начнем неделю с практики, решил поделиться кастомом, так как ты сможешь его заюзать для триажа, конвертации отчетов.
Сценарий
- Определяет платформу Linux/macOS/другое и выбирает образ как основной для аудита
- Создаёт структуру каталогов ./audit_reports/{json,text,xlsx,odt} для результатов
- Запускает Trivy для образов, записывая JSON‑отчёты уязвимостей в audit_reports/json/*.json
- Запускает контейнер docker-bench-security с маунтами и правами, выполняя аудит
- Если Python c openpyxl и odfpy дополнительнос стоят рядом, то перебирает все JSON‑отчёты
- Сканирует Docker‑образы на CVE по заданному списку, включая docker/docker-bench-security, запускает по каждому инструмент анализ с перечнем уязвимых библиотек, их версий, идентификаторов уязвимостей, уровней критичности и статуса исправления
- Проводит конфигурационный аудит Docker‑хоста
Скрипт
set -euo pipefail
echo "Docker CIS & Image Audit"
command -v docker >/dev/null 2>&1 || { echo "no docker"; exit 1; }
docker info >/dev/null 2>&1 || { echo "docker daemon down"; exit 1; }
case "$(uname -s)" in
Linux) PLATFORM="Linux" ;;
Darwin) PLATFORM="macOS" ;;
*) PLATFORM="Other" ;;
esac
BENCH_IMAGE="${DOCKER_BENCH_IMAGE:-docker/docker-bench-security:latest}"
REPORTS_DIR="./audit_reports"
mkdir -p "${REPORTS_DIR}"/{json,text,xlsx,odt}
echo "Platform: ${PLATFORM}"
echo "Image: ${BENCH_IMAGE}"
docker image inspect "${BENCH_IMAGE}" >/dev/null 2>&1 || docker pull "${BENCH_IMAGE}"
if command -v trivy >/dev/null 2>&1; then
trivy image --format json --output "${REPORTS_DIR}/json/docker-bench-security.json" "${BENCH_IMAGE}" || true
for img in nginx:alpine python:3.11-alpine postgres:16-alpine; do
safe=$(echo "${img}" | sed 's/[:\/]/-/g')
trivy image --format json --output "${REPORTS_DIR}/json/${safe}.json" "${img}" || true
done
fi
run_bench() {
out="${REPORTS_DIR}/text/docker-bench-security-cis.txt"
docker run --rm \
--name "docker-bench-$(date +%s)" \
--cap-add audit_control \
--security-opt no-new-privileges \
--network host --pid host --userns host \
-e DOCKER_CONTENT_TRUST="${DOCKER_CONTENT_TRUST:-0}" \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /etc:/etc:ro -v /var/lib:/var/lib:ro -v /usr/bin:/usr/bin:ro \
"${BENCH_IMAGE}" 2>&1 | tee "${out}"
}
[ "${PLATFORM}" = "Linux" ] && run_bench || echo "CIS аудит в Linux/WSL"
if command -v python3 >/dev/null 2>&1; then
python3 << 'PY'
import json, os, sys
from pathlib import Path
try:
from openpyxl import Workbook
from odf.opendocument import OpenDocumentText
from odf.text import P
except ImportError:
sys.exit(0)
BASE = Path("./audit_reports")
for jf in (BASE / "json").glob("*.json"):
with jf.open() as f:
data = json.load(f)
xlsx = BASE / "xlsx" / (jf.stem + ".xlsx")
wb, ws = Workbook(), Workbook().active
ws = wb.active
ws.append(["Target","Type","VulnID","Severity","Status","Title"])
for r in data.get("Results", []):
t = r.get("Target","N/A")
for v in r.get("Vulnerabilities", []) + r.get("Misconfigurations", []):
ws.append([
t, r.get("Type","unknown"),
v.get("VulnerabilityID","N/A"),
v.get("Severity","UNKNOWN"),
v.get("Status","N/A"),
v.get("Title","N/A")[:80],
])
wb.save(xlsx)
odt = BASE / "odt" / (jf.stem + ".odt")
doc = OpenDocumentText()
doc.text.addElement(P(text=f"Report: {jf.name}"))
for r in data.get("Results", []):
doc.text.addElement(P(text=f"\nTarget: {r.get('Target','N/A')}"))
for i, v in enumerate(r.get("Vulnerabilities", []) + r.get("Misconfigurations", []), 1):
doc.text.addElement(P(text=f"[{i}] {v.get('VulnerabilityID','N/A')} ({v.get('Severity','UNKNOWN')}): {v.get('Title','N/A')}"))
doc.save(str(odt))
PY
fi
echo "Done -> ${REPORTS_DIR}/{json,text,xlsx,odt}"
#appsec #devsecops #specialty #toolchain #containersecurity #vulnmanagement #techsolution
