fix(trivy): scan local images via the mounted socket, not a registry pull

The client scan resolved images by pulling from Docker Hub, which fails on an
offline/privacy box ("index.docker.io ... network is unreachable") — yet every
installed app's image is already present locally. Point Trivy at the docker
socket that's already bind-mounted into the container (--image-src docker, plus
DOCKER_HOST=unix:///run/user/<uid>/docker.sock for rootless, derived from the
install user — rooted's default path is found automatically). Scans local
images with zero network. Verified: aquasec/trivy:latest -> 28 CVEs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
librelad 2026-07-16 16:59:59 +01:00
parent 6bb857f5a1
commit a079050108

View File

@ -54,13 +54,23 @@ trivyScanImageCves() {
[ -n "$image" ] || { echo '[]'; return; }
command -v jq >/dev/null 2>&1 || { echo '[]'; return; }
# Scan in CLIENT mode against the running server (--server localhost:4954,
# the container's fixed --listen port). Standalone `trivy image` would try to
# open the vuln-DB cache the server already holds and fail with a cache-lock
# timeout; client mode leaves the DB to the server. --quiet keeps the
# progress spinner out of stdout; we only want CRITICAL..LOW findings.
# Scan the app's LOCAL image via the docker socket mounted into the
# container (--image-src docker) so nothing is pulled from a registry — the
# image is already present, and a privacy box may have no outbound at all.
# Client mode (--server localhost:4954, the container's fixed --listen port)
# leaves the vuln DB to the running server; a standalone scan would deadlock
# on the server's cache lock. For rootless the daemon socket lives under
# /run/user/<uid> (not trivy's default path), so point DOCKER_HOST at it;
# rooted's /var/run/docker.sock is found by default.
local envs=""
if [ "${CFG_DOCKER_INSTALL_TYPE:-}" = "rootless" ] && [ -n "${docker_install_user:-}" ]; then
local uid; uid="$(id -u "$docker_install_user" 2>/dev/null)"
[ -n "$uid" ] && envs="-e DOCKER_HOST=unix:///run/user/$uid/docker.sock"
fi
# --quiet keeps the progress spinner out of stdout; we only want CRITICAL..LOW.
local raw
raw="$(dockerCommandRun "docker exec trivy-service trivy image --server http://localhost:4954 --quiet --scanners vuln --format json --severity CRITICAL,HIGH,MEDIUM,LOW '$image'" 2>/dev/null)"
raw="$(dockerCommandRun "docker exec $envs trivy-service trivy image --server http://localhost:4954 --image-src docker --quiet --scanners vuln --format json --severity CRITICAL,HIGH,MEDIUM,LOW '$image'" 2>/dev/null)"
[ -n "$raw" ] || { echo '[]'; return; }
printf '%s' "$raw" | jq -c '