# soc-collector A single, run-anywhere container that scans your estate and pushes the results to a [SOC Center](https://soc.ethica.no) instance as auto-updating reports. No JSON to write, no curl — you give it an **API endpoint** and a **token**, point it at some targets, and run it. Same report slug every run, so SOC Center versions each scan, diffs what changed, and alerts you only on *new* findings. ## Run it ```bash docker run --rm \ -e SOC_URL=https://soc.ethica.no \ -e SOC_TOKEN=soc_xxxxxxxx \ -e SOC_SLUG=my-server \ -e SOC_TARGETS=10.0.0.5,10.0.0.6 \ -e SOC_DOMAINS=soc.ethica.no,ethica.no \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ git.skui.io/ethica/soc-collector:latest ``` Each run produces **one report** (named by `SOC_SLUG`) merging all the sources below. One server = one report; run it per server with a distinct `SOC_SLUG` for one report each. It runs once and exits. To keep reports fresh, schedule that command — e.g. nightly: ```cron 0 2 * * * docker run --rm -e SOC_URL=… -e SOC_TOKEN=… -e SOC_TARGETS=… -e SOC_DOMAINS=… \ -v /var/run/docker.sock:/var/run/docker.sock:ro git.skui.io/ethica/soc-collector:latest ``` The `SOC_TOKEN` is a **write-scoped** token you mint once in SOC Center (**Admin → Tokens**). Reports are owned by, and visible per, that token's user. ## What it collects One run = **one consolidated report** (slug = `SOC_SLUG`) merging whichever of these sources have their inputs, criticals first: | Source | What it checks | Needs | |---|---|---| | surface | `nmap` open-port / service scan, flags risky exposed ports | `SOC_TARGETS` | | cve | `trivy` of every **running** image — **fixable** HIGH/CRITICAL only, grouped by package | Docker socket | | tls | cert-expiry, weak TLS, missing security headers | `SOC_DOMAINS` | | config | `0.0.0.0` port binds, `--privileged`, rw docker-socket mounts | Docker socket | Each source **self-skips** when its inputs are absent — no `SOC_TARGETS` → no nmap; no socket mount → no Trivy / config. So the same image is safe to run anywhere; you just enable what you give it. ## Configuration (all via env) | Var | Required | Default | Meaning | |---|---|---|---| | `SOC_URL` | ✅ | — | SOC Center base URL, e.g. `https://soc.ethica.no` | | `SOC_TOKEN` | ✅ | — | write-scoped API token | | `SOC_TARGETS` | for nmap | — | comma/space hosts or IPs to scan | | `SOC_DOMAINS` | for tls | — | comma hostnames to TLS-probe | | `SOC_SOURCES` | | `surface,cve,tls,config` | which sources to run | | `SOC_SLUG` | | `soc-scan` | the report's slug — **set one per server** (e.g. `hetzner-prod`) | | `SOC_TITLE` | | `Security scan — ` | the report's title | | `SOC_VISIBILITY` | | `private` | `private` or `authenticated` | | `SOC_TAGS` | | `collector` | extra report tags | ## Notes - **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 socket-proxy instead of the raw socket. - 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. ## License MIT — see [LICENSE](LICENSE).