diff --git a/argocd/manifests/prowler/cronjob-image-scan.yaml b/argocd/manifests/prowler/cronjob-image-scan.yaml new file mode 100644 index 0000000..969fe49 --- /dev/null +++ b/argocd/manifests/prowler/cronjob-image-scan.yaml @@ -0,0 +1,40 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: prowler-image-scan + namespace: prowler +spec: + schedule: "0 3 * * 6" # Saturday 3am + concurrencyPolicy: Forbid + jobTemplate: + spec: + ttlSecondsAfterFinished: 604800 # Auto-delete after 7 days + template: + spec: + securityContext: + seccompProfile: + type: RuntimeDefault + containers: + - name: prowler + image: registry.ops.eblu.me/blumeops/prowler:kustomized + args: + - image + - --registry + - registry.ops.eblu.me + - --image-filter + - blumeops/ + - -z + - --output-formats + - html + - csv + - json-ocsf + - --output-directory + - /reports/prowler-images + volumeMounts: + - name: reports + mountPath: /reports + restartPolicy: OnFailure + volumes: + - name: reports + persistentVolumeClaim: + claimName: prowler-reports diff --git a/argocd/manifests/prowler/kustomization.yaml b/argocd/manifests/prowler/kustomization.yaml index 7d870ff..ca6ef56 100644 --- a/argocd/manifests/prowler/kustomization.yaml +++ b/argocd/manifests/prowler/kustomization.yaml @@ -9,6 +9,7 @@ resources: - pv-nfs.yaml - pvc.yaml - cronjob.yaml + - cronjob-image-scan.yaml images: - name: registry.ops.eblu.me/blumeops/prowler diff --git a/containers/prowler/Dockerfile b/containers/prowler/Dockerfile index cb557ca..7cafd17 100644 --- a/containers/prowler/Dockerfile +++ b/containers/prowler/Dockerfile @@ -1,5 +1,6 @@ -# Prowler CIS scanner — slim build for Kubernetes provider only -# Strips PowerShell (M365), Trivy (IaC), and dashboard dependencies from upstream +# Prowler CIS scanner — slim build for Kubernetes, image, and IaC providers +# Strips PowerShell (M365) and dashboard dependencies from upstream +# Includes Trivy for image vulnerability and IaC scanning ARG CONTAINER_APP_VERSION=5.22.0 FROM python:3.12-slim-bookworm AS build @@ -30,14 +31,31 @@ LABEL org.opencontainers.image.title="prowler" LABEL org.opencontainers.image.version="${CONTAINER_APP_VERSION}" LABEL org.opencontainers.image.source="https://forge.eblu.me/eblume/blumeops" LABEL org.opencontainers.image.vendor="blumeops" -LABEL org.opencontainers.image.description="Prowler CIS scanner (Kubernetes provider)" +LABEL org.opencontainers.image.description="Prowler scanner (Kubernetes, image, IaC providers)" + +ARG TRIVY_VERSION=0.69.2 + +RUN ARCH=$(dpkg --print-architecture) \ + && case "$ARCH" in \ + amd64) TRIVY_ARCH="Linux-64bit" ;; \ + arm64) TRIVY_ARCH="Linux-ARM64" ;; \ + *) echo "Unsupported architecture: $ARCH" && exit 1 ;; \ + esac \ + && apt-get update && apt-get install -y --no-install-recommends wget ca-certificates \ + && wget -q "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_${TRIVY_ARCH}.tar.gz" -O /tmp/trivy.tar.gz \ + && tar xzf /tmp/trivy.tar.gz -C /usr/local/bin trivy \ + && chmod +x /usr/local/bin/trivy \ + && rm /tmp/trivy.tar.gz \ + && apt-get purge -y wget && apt-get autoremove -y && rm -rf /var/lib/apt/lists/* RUN addgroup --gid 1000 prowler \ - && adduser --uid 1000 --gid 1000 --disabled-password --gecos "" prowler + && adduser --uid 1000 --gid 1000 --disabled-password --gecos "" prowler \ + && mkdir -p /tmp/.cache/trivy && chown prowler:prowler /tmp/.cache/trivy COPY --from=build /opt/prowler /opt/prowler ENV PATH="/opt/prowler/bin:${PATH}" +ENV TRIVY_CACHE_DIR="/tmp/.cache/trivy" USER prowler WORKDIR /home/prowler diff --git a/docs/changelog.d/+prowler-image-scan.feature.md b/docs/changelog.d/+prowler-image-scan.feature.md new file mode 100644 index 0000000..e109074 --- /dev/null +++ b/docs/changelog.d/+prowler-image-scan.feature.md @@ -0,0 +1 @@ +Add container image vulnerability scanning via Prowler image provider (Saturday 3am, all blumeops/* images). diff --git a/docs/how-to/operations/deploy-prowler.md b/docs/how-to/operations/deploy-prowler.md index 2b29d39..c42f65f 100644 --- a/docs/how-to/operations/deploy-prowler.md +++ b/docs/how-to/operations/deploy-prowler.md @@ -15,6 +15,8 @@ Prowler runs weekly CIS Kubernetes Benchmark scans against minikube-indri and wr ## What it checks +### Kubernetes CIS benchmarks (Sunday 3am) + Prowler's Kubernetes provider runs ~70 checks from the CIS Kubernetes Benchmark v1.11, grouped into: | Category | Checks | How it works | @@ -31,6 +33,22 @@ Prowler's Kubernetes provider runs ~70 checks from the CIS Kubernetes Benchmark **k3s note:** k3s embeds the control plane in a single binary — no static pods exist. Only core + RBAC checks (~22 of 70) produce results. Consider `kube-bench` for k3s control plane checks. +### Image vulnerability scanning (Saturday 3am) + +Prowler's image provider scans all `blumeops/*` container images in `registry.ops.eblu.me` for: + +- **CVEs** — known vulnerabilities from NVD, Alpine SecDB, Debian Security Tracker, and other sources +- **Embedded secrets** — credentials or API keys baked into image layers +- **Misconfigurations** — Dockerfile best practices (running as root, missing HEALTHCHECK, etc.) + +Uses Trivy under the hood. Reports are written to `sifaka:/volume1/reports/prowler-images/`. + +To run an ad-hoc image scan: + +```fish +kubectl create job --from=cronjob/prowler-image-scan prowler-image-manual -n prowler --context=minikube-indri +``` + ## Reports Reports are written to `sifaka:/volume1/reports/prowler/` with timestamped filenames. See [[read-compliance-reports]] for how to access and interpret them. diff --git a/docs/how-to/operations/read-compliance-reports.md b/docs/how-to/operations/read-compliance-reports.md index e2088f7..bfc0afa 100644 --- a/docs/how-to/operations/read-compliance-reports.md +++ b/docs/how-to/operations/read-compliance-reports.md @@ -18,7 +18,8 @@ Reports are stored on sifaka at `/volume1/reports/`. Each scanner writes to its | Scanner | Path | Schedule | |---------|------|----------| -| [[prowler]] | `sifaka:/volume1/reports/prowler/` | Weekly (Sunday 3am) | +| [[prowler]] K8s CIS | `sifaka:/volume1/reports/prowler/` | Weekly (Sunday 3am) | +| [[prowler]] Image | `sifaka:/volume1/reports/prowler-images/` | Weekly (Saturday 3am) | Copy reports to your local machine (remember `scp -O` for sifaka): diff --git a/docs/reference/operations/security.md b/docs/reference/operations/security.md index 8a621b1..ab9ef25 100644 --- a/docs/reference/operations/security.md +++ b/docs/reference/operations/security.md @@ -49,5 +49,5 @@ All compliance scan reports are stored on `sifaka:/volume1/reports/`. See [[read - No SOC 2 compliance mapping for Kubernetes (Prowler only maps SOC 2 for AWS/Azure/GCP) - k3s control plane checks produce no results (embedded binary, no static pods) — consider kube-bench -- No container image vulnerability scanning yet (Prowler has an `image` provider) +- Container image scanning covers `blumeops/*` images only — upstream images (ollama, immich, etc.) are not scanned - No IaC scanning of manifests/Dockerfiles yet (Prowler has an `iac` provider using Trivy) diff --git a/docs/reference/services/prowler.md b/docs/reference/services/prowler.md index f68a573..d617a7c 100644 --- a/docs/reference/services/prowler.md +++ b/docs/reference/services/prowler.md @@ -17,13 +17,18 @@ CIS Kubernetes Benchmark scanner for compliance posture reporting. |----------|-------| | **Namespace** | `prowler` | | **Image** | `registry.ops.eblu.me/blumeops/prowler` (see `argocd/manifests/prowler/kustomization.yaml` for current tag) | -| **Schedule** | Weekly (Sunday 3am) | -| **Reports** | `sifaka:/volume1/reports/prowler/` (NFS) | +| **Schedule** | K8s CIS: Sunday 3am / Image scan: Saturday 3am | +| **Reports** | `sifaka:/volume1/reports/prowler/` and `prowler-images/` (NFS) | | **Manifests** | `argocd/manifests/prowler/` | ## What it does -Runs Prowler 5 as a CronJob against minikube-indri, executing CIS Kubernetes Benchmark v1.11 checks across pod security, RBAC, apiserver, etcd, kubelet, controller-manager, and scheduler. Reports are written in HTML, CSV, and JSON-OCSF to the NFS share on sifaka. +Runs Prowler 5 as two CronJobs: + +- **K8s CIS scan** (Sunday) — CIS Kubernetes Benchmark v1.11 checks across pod security, RBAC, apiserver, etcd, kubelet, controller-manager, and scheduler +- **Image scan** (Saturday) — CVE, secret, and misconfiguration scanning of all `blumeops/*` container images in the registry via Trivy + +Reports are written in HTML, CSV, and JSON-OCSF to the NFS share on sifaka. ## See also