cve: exclude the collector's own container from the scan (+ SOC_EXCLUDE_IMAGES)
Build and push soc-collector / build (push) Successful in 5s

This commit is contained in:
Steffen Skui
2026-06-25 10:31:40 +02:00
parent 9277db02a5
commit 2ff4e703c4
2 changed files with 41 additions and 2 deletions
+3
View File
@@ -61,12 +61,15 @@ enable what you give it.
| `SOC_TITLE` | | `Security scan — <slug>` | the report's title | | `SOC_TITLE` | | `Security scan — <slug>` | the report's title |
| `SOC_VISIBILITY` | | `private` | `private` or `authenticated` | | `SOC_VISIBILITY` | | `private` | `private` or `authenticated` |
| `SOC_TAGS` | | `collector` | extra report tags | | `SOC_TAGS` | | `collector` | extra report tags |
| `SOC_EXCLUDE_IMAGES` | | — | comma-separated substrings; running images matching any are skipped by the `cve` source |
## Notes ## Notes
- **Docker socket** is mounted **read-only** (`:ro`) and is only used to *list* running - **Docker socket** is mounted **read-only** (`:ro`) and is only used to *list* running
containers and *inspect* their config. For extra isolation, point it at a scoped containers and *inspect* their config. For extra isolation, point it at a scoped
socket-proxy instead of the raw socket. socket-proxy instead of the raw socket.
- The `cve` source **skips the collector's own container**, so the scanner never reports
on itself. Use `SOC_EXCLUDE_IMAGES` to drop any other images you don't want scanned.
- The collector is **pure-stdlib Python**; the image just adds `nmap` and `trivy`. - The collector is **pure-stdlib Python**; the image just adds `nmap` and `trivy`.
- Multi-server: run one container per server with a distinct `SOC_SLUG` — one report each. - Multi-server: run one container per server with a distinct `SOC_SLUG` — one report each.
+38 -2
View File
@@ -13,6 +13,9 @@ that you can apply it. For an image you don't build and already run :latest of,
explicit, and actionable findings sort above the can't-do-anything ones. explicit, and actionable findings sort above the can't-do-anything ones.
""" """
import json import json
import os
import re
import socket
import subprocess import subprocess
from soc import finding from soc import finding
@@ -23,13 +26,46 @@ OWN_PREFIX = "git.skui.io/"
STATUS_RANK = {"yours": 0, "update": 1, "upstream": 2} STATUS_RANK = {"yours": 0, "update": 1, "upstream": 2}
def _own_container_id():
"""The collector's own container id, so we don't scan ourselves.
/proc carries the full id regardless of `--hostname`; fall back to the
hostname (== the short container id by Docker default). Empty string when
not running in a container (then nothing is excluded)."""
try:
with open("/proc/self/mountinfo") as fh: # …/containers/<id>/{hostname,hosts}
m = re.search(r"/containers/([0-9a-f]{64})/", fh.read())
if m:
return m.group(1)
except OSError:
pass
try:
with open("/proc/self/cgroup") as fh: # cgroup v1: …/docker/<id>
m = re.search(r"docker[-/]([0-9a-f]{64})", fh.read())
if m:
return m.group(1)
except OSError:
pass
try:
return socket.gethostname().strip()
except Exception:
return ""
def _running_images(): def _running_images():
conts = _docker.get("/containers/json") or [] conts = _docker.get("/containers/json") or []
self_id = _own_container_id()
# optional extra exclusions: SOC_EXCLUDE_IMAGES=substr1,substr2
extra = [s.strip() for s in os.environ.get("SOC_EXCLUDE_IMAGES", "").split(",") if s.strip()]
seen = [] seen = []
for c in conts: for c in conts:
cid = c.get("Id", "")
if self_id and cid.startswith(self_id):
continue # don't scan the collector itself
img = c.get("Image", "") img = c.get("Image", "")
if img and img not in seen: if not img or img in seen or any(x in img for x in extra):
seen.append(img) continue
seen.append(img)
return seen return seen