cyber-cve-scan.sh
Runs Trivy against every running Docker image to surface known CVEs — report-only, against live vulnerability databases.
Note
Live script from my home-lab server. Tokens, IDs, phone numbers and other secrets have been replaced with
placeholders like
<WHATSAPP_GROUP_ID> — everything else is the real, running code.
#!/usr/bin/env bash
set -euo pipefail
REPORT_DIR=/home/lanky/reports
CACHE_DIR=/home/lanky/reports/trivy-cache
GROUP_ID=<WHATSAPP_GROUP_ID>
mkdir -p "$REPORT_DIR" "$CACHE_DIR"
stamp=$(date +%Y%m%d-%H%M%S)
report="$REPORT_DIR/cyber-cve-scan-$stamp.txt"
latest="$REPORT_DIR/cyber-cve-scan-latest.txt"
json_report="$REPORT_DIR/cyber-cve-scan-$stamp.json"
images=$(docker ps --format '{{.Image}}' | sort -u)
{
echo "Cyber Analyst CVE scan"
echo "Generated: $(date -Is)"
echo "Scanner: aquasec/trivy container"
echo "Scope: currently running Docker images"
echo "Note: This scan uses Internet CVE databases and is report-only."
echo
echo "Images:"
printf '%s\n' $images | sed 's/^/- /'
echo
} > "$report"
scan_status=0
: > "$json_report"
for image in $images; do
safe=$(printf '%s' "$image" | tr '/:@' '___')
image_json="$REPORT_DIR/trivy-$safe-$stamp.json"
echo "== $image ==" >> "$report"
if timeout 20m docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$CACHE_DIR:/root/.cache/" \
aquasec/trivy:latest image \
--quiet \
--scanners vuln \
--severity HIGH,CRITICAL \
--format table \
"$image" >> "$report" 2>&1; then
:
else
scan_status=1
echo "Scan failed or timed out for $image" >> "$report"
fi
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$CACHE_DIR:/root/.cache/" \
aquasec/trivy:latest image \
--quiet \
--scanners vuln \
--severity HIGH,CRITICAL \
--format json \
"$image" > "$image_json" 2>/dev/null || true
printf '{"image":%s,"report":%s}\n' "$(printf '%s' "$image" | jq -Rs .)" "$(cat "$image_json" | jq -c . 2>/dev/null || echo null)" >> "$json_report"
echo >> "$report"
done
cp "$report" "$latest"
crit_high=$(grep -E 'CRITICAL|HIGH' "$report" | wc -l || true)
summary=$(/home/lanky/scripts/person-friendly-report.sh cve "$report")
if [ -z "${SERVICE_DESK_JOB_ID:-}" ]; then
sudo -u lanky openclaw message send --channel whatsapp --account default --target "$GROUP_ID" --message "$summary" --media "$report" --force-document >/dev/null 2>&1 || true
fi
exit "$scan_status"