dagu: weekly trivy scan of running images, with alerts #287
No reviewers
Labels
No labels
audit-work
bug
docs
general-admin
major-upgrade
needs-vps-sync
new-service
on-hold
outside-work
post-podman
renovate
upstream
vps
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
mysticalsoap/docker!287
Loading…
Reference in a new issue
No description provided.
Delete branch "image-scan"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Digest pinning is a deliberate opt-out of silent security patches, and Renovate only ever says "a newer digest exists", never "the one you run is CVE'd". Nothing ranks its PRs, and the locally built images (dagu-tools, config-renderer, knock, metadata) are rebuilt by nobody, so they can sit on stale base packages for months without anything noticing.
Closes #108. Deviations from the issue as filed: Trivy, not Grype; and the framing is narrower than written — Renovate does open a digest PR whenever upstream rebuilds, so the scan is the priority signal plus coverage of the local builds, not the only CVE signal.
Fix
dagu-scannersidecar (Trivy image plus curl/jq) and animage-scanDAG, Monday 06:00.scan.shlists running containers through the socket proxy and scans each distinct image by id via the daemon, so a re-pulled tag or a rebuilt local image can't mask what actually runs. Fix-available HIGH/CRITICAL only,.trivyignorefor accepted CVEs, results toimage_scan.prombeside the backup/SMART metrics.HEAD /_ping. Nothing mutating.docker saveas a 5-blob tar against a 29-layer manifest under the containerd image store (cause not pinned down; no matching Trivy issue upstream). Those are pulled from their registry by the same digest instead.imagesalert group:ImageVulnerableCritical/ImageVulnerableHighper image,ImageScanFailed,ImageScanStale(14d),ImageScanMetricMissing. Categoryimages, so they land onhomelab-alertslike backup and smart. A 7drepeat_intervalroute for the category, and Alertmanager--data.retention=192hso it doesn't forget it already notified.Verification
just up dagu, thendocker exec dagu dagu start image-scanthree times on the branch. Cold (cache cleared): 58 images in 145s, scanner peak 354MiB of the 1g limit. Warm: 10s. Proxy log shows no blocked requests during a run.not found in tar; after it, 58/58image_scan_image_ok 1.promtool check rules(35 rules) andamtool check-configclean. Prometheus and Alertmanager restarted on the branch:ImageVulnerableCriticalfiring on 14 images,ImageVulnerableHighon 43,ImageScanFailedcleared once the fallback landed. ntfy'smessages_publishedcounter rose by 3 in the window, one per grouped alert.repeat_interval is greater than the data retention periodwarning is gone.Review notes and follow-ups
_helper/knock/Dockerfileand_helper/config-renderer/Dockerfilehave unpinnedFROMlines, against the pinning policy. Separate PR.just deploynever rebuildsbuild:images, so a Renovate bump of anyFROMline (this PR'sdagu/scanner/Dockerfileincluded) changes nothing live until a manual build. Worth an issue.9664cb429e73ee38cc8573ee38cc855b4d191612Two changes since the description above, both force-pushed into the two commits:
ImageVulnerableHighrule. First run: 43 of 58 images had a fixable HIGH, 1115 findings over 234 CVEs — Go stdlib andx/modules in 14 Go binaries (openssl-style DoS and idna bugs, fixed only by upstream rebuilding with a newer toolchain), the .NET runtime bundled in the hotio *arr images,libssl3/libcrypto3in every alpine base. Nothing this repo can fix short of an upstream rebuild, so HIGH stays a metric for Grafana.ImageVulnerableCriticalis firing on 15 images right now.build:image is exactly the kind nothing rebuilds (it already carried 7 fixable HIGH of its own). Nowimage:pinned by digest, so Renovate bumps it andjust deployrecreates it. That splits the DAG into aliststep in dagu-tools (docker CLI) and a busybox-shscanstep, with the handoff on the shared volume —./jobsis the host user's and read-only to the sidecars' uid.Re-verified on the branch: two-step run 58/58 ok in 10s warm; grep-based severity counting cross-checked against jq on grafana (104 = 104); Prometheus shows only
ImageVulnerableCriticalafter the reload.