Initial commit
This commit is contained in:
commit
70dbff10b9
14 files changed
+1907
No files matched your search
@@ -0,0 +1,187 @@
|
||||
# Running docker-vuln-scan in Komodo
|
||||
|
||||
Two ready-to-apply Resource Sync definitions are provided. Use **one** of them,
|
||||
not both (they declare the same resource names):
|
||||
|
||||
| File | Use when |
|
||||
| --- | --- |
|
||||
| [`vuln-scan.toml`](vuln-scan.toml) | Komodo should clone this project from git and build the scanner itself. |
|
||||
| [`vuln-scan-files-on-host.toml`](vuln-scan-files-on-host.toml) | You copy this project to the Komodo server and want Komodo to use those files. |
|
||||
|
||||
Both create:
|
||||
|
||||
- a **Stack** named `vuln-scan` on the selected Komodo Server, and
|
||||
- a **Procedure** named `vuln-scan` that redeploys the stack every night,
|
||||
which rebuilds the scanner image and runs one scan.
|
||||
|
||||
Alerts for HIGH/CRITICAL findings are sent **by the scanner directly through
|
||||
Apprise**. You do not need a Komodo Alerter for that part.
|
||||
|
||||
## Before you start
|
||||
|
||||
- Komodo 2.x with a **Server** resource (Periphery) on the Docker host whose
|
||||
images you want to scan.
|
||||
- The project available to Komodo (git repo, or copied to the host).
|
||||
- A reachable Apprise target (Discord, Slack, email, Telegram, ...).
|
||||
|
||||
### 1. Create the APPRISE_URLS variable
|
||||
|
||||
In Komodo: **Variables → New Variable**
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| Name | `APPRISE_URLS` |
|
||||
| Value | e.g. `discord://webhook_id/webhook_token` |
|
||||
| Secret | **on** |
|
||||
|
||||
For several targets, separate them with a space:
|
||||
|
||||
```text
|
||||
mailto://user:app-password@gmail.com tgram://bot_token/chat_id
|
||||
```
|
||||
|
||||
The stack reads this variable through an `[[APPRISE_URLS]]` interpolation in its
|
||||
`environment`, so do this before applying the sync.
|
||||
|
||||
> If you prefer to keep everything in the TOML file, add a `[[variable]]` block
|
||||
> with `name = "APPRISE_URLS"`, `value = "..."` and `is_secret = true`. The
|
||||
> value will then live in your sync git repo, so only do this in a private repo.
|
||||
|
||||
### 2. Apply the resources
|
||||
|
||||
#### Option A - git repo mode (recommended)
|
||||
|
||||
1. Push this project to a git repository Komodo can reach.
|
||||
2. Edit `komodo/vuln-scan.toml`:
|
||||
- `server = "server-prod"` → your Komodo Server name.
|
||||
- `repo = "your-org/docker-vuln-scan"` → your repository.
|
||||
- `IMAGES = ...` → the images you want to scan.
|
||||
3. In Komodo: **Syncs → New Resource Sync → Git Repo**, then set:
|
||||
- the repository and branch,
|
||||
- `resource_path = ["komodo/vuln-scan.toml"]`,
|
||||
- a git account if the repo is private.
|
||||
4. Refresh the sync and review/apply the pending changes.
|
||||
5. Open **Procedures → vuln-scan → Run** to start the first scan now.
|
||||
|
||||
#### Option B - files on the host
|
||||
|
||||
Komodo resolves files-on-host paths under the Periphery root directory
|
||||
(default `/etc/komodo`, mounted at the same path in the standard Komodo compose
|
||||
setup). The stack path is `/etc/komodo/stacks/<stack-name>`.
|
||||
|
||||
1. Copy the project to the Docker host:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /etc/komodo/stacks/vuln-scan
|
||||
sudo cp -r docker-vuln-scan/. /etc/komodo/stacks/vuln-scan/
|
||||
```
|
||||
|
||||
(If you changed `PERIPHERY_ROOT_DIRECTORY`, use that path instead.)
|
||||
2. Edit `komodo/vuln-scan-files-on-host.toml` (`server`, `IMAGES`).
|
||||
3. Apply the file. It still needs to be readable by **Core**, which does not
|
||||
mount `/etc/komodo` by default. Either keep the TOML in a git-based Resource
|
||||
Sync, or create the Stack and Procedure in the UI using the values from the
|
||||
file.
|
||||
4. Run **Procedures → vuln-scan → Run**.
|
||||
|
||||
## What a run does
|
||||
|
||||
```
|
||||
Procedure (cron) -> DeployStack -> docker compose build -> docker compose up -d
|
||||
|
|
||||
v
|
||||
scanner container runs and exits
|
||||
|
|
||||
+---------------+---------------+
|
||||
v v
|
||||
Apprise alert (HIGH/CRITICAL) JSON report on disk
|
||||
```
|
||||
|
||||
- `run_build = true` rebuilds the scanner image on the Komodo server. Layers
|
||||
are cached, so only changes to `scan.py`/`Dockerfile` rebuild.
|
||||
- `auto_pull = false` is required: the image is built locally and must not be
|
||||
pulled from a registry.
|
||||
- `ignore_services = ["vulnscan"]` tells Komodo that the exited one-shot
|
||||
container is expected in status checks. Because this stack contains only that
|
||||
one service, Komodo may still show the stack as stopped/down between runs.
|
||||
That is normal for a scheduled one-shot job.
|
||||
- `send_alerts = false` avoids daily status noise. Findings are reported by
|
||||
Apprise instead.
|
||||
|
||||
`DeployStack` returns once `docker compose up -d` has started the container; it
|
||||
does not wait for the scan to finish. The Apprise notification is the result
|
||||
signal. The container exit code (`FAIL_ON`) is visible in the stack logs.
|
||||
|
||||
## Where the results are
|
||||
|
||||
On the scan server:
|
||||
|
||||
```
|
||||
/etc/komodo/stacks/vuln-scan/reports/<image>.json
|
||||
```
|
||||
|
||||
If your Periphery runs with a different root or the stack uses a `run_directory`,
|
||||
adjust the path accordingly. The Compose volume is `./reports:/reports` relative
|
||||
to the stack directory.
|
||||
|
||||
Logs:
|
||||
|
||||
- Komodo UI: **Stacks → vuln-scan → Logs**
|
||||
- Shell: `docker compose -p vuln-scan logs vulnscan`
|
||||
|
||||
## Customizing
|
||||
|
||||
Edit the stack's `environment` (in the TOML or in Komodo) and re-apply the sync:
|
||||
|
||||
| Setting | Meaning |
|
||||
| --- | --- |
|
||||
| `IMAGES` | Space separated images to scan. Leave empty to scan the images used by running containers. |
|
||||
| `DOCKER_SOCK` | Host path of the Docker socket (e.g. `/run/user/1000/docker.sock` for rootless Docker). |
|
||||
| `INCLUDE_SELF` | `true` to also scan the scanner's own image when auto-discovering. |
|
||||
| `APPRISE_URLS` | Notification target(s); usually kept in the secret variable. |
|
||||
| `NOTIFY_MIN_SEVERITY` | Lowest severity that sends an alert (default `HIGH`). |
|
||||
| `FAIL_ON` | Lowest severity that makes the container exit `1` (default `HIGH`). |
|
||||
| `IGNORE_UNFIXED` | `true` to ignore findings without a fix. |
|
||||
| `MAX_FINDINGS_IN_BODY` | Findings listed per notification. |
|
||||
|
||||
Schedule fields are on the Procedure:
|
||||
|
||||
```toml
|
||||
[procedure.config]
|
||||
schedule_format = "Cron"
|
||||
schedule = "0 0 3 * * ?" # seconds minute hour day month weekday
|
||||
schedule_timezone = "UTC"
|
||||
```
|
||||
|
||||
To scan every image on the server instead of just the images in use, write the
|
||||
list on the host and mount it:
|
||||
|
||||
```bash
|
||||
docker image ls --format '{{.Repository}}:{{.Tag}}' \
|
||||
| grep -v '<none>' > /etc/komodo/stacks/vuln-scan/images.txt
|
||||
```
|
||||
|
||||
Then add `- ./images.txt:/images.txt:ro` to the `vulnscan` service volumes and
|
||||
set `IMAGES_FILE = /images.txt` in the stack environment.
|
||||
|
||||
Private registries: add `TRIVY_USERNAME`, `TRIVY_PASSWORD` and optionally
|
||||
`TRIVY_INSECURE` to the stack environment. The Compose file already passes
|
||||
them through to the container.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Fix |
|
||||
| --- | --- |
|
||||
| Unresolved `[[APPRISE_URLS]]` / notification errors | Create the `APPRISE_URLS` variable (step 1) and re-apply. |
|
||||
| `docker-vuln-scan:latest` pull error | Keep `auto_pull = false`; the stack builds the image locally. |
|
||||
| Stack shows stopped/down between scans | Expected: the scanner is a one-shot container. Status alerts are disabled. |
|
||||
| No findings at all | Check the image reference is correct; Trivy pulls registry images, and the Docker socket covers local-only images. |
|
||||
| "No images configured ... nothing to scan" | The scanner cannot reach the Docker socket. With rootless Docker set `DOCKER_SOCK=/run/user/<uid>/docker.sock`, or set `IMAGES` explicitly. |
|
||||
| Procedure success but no alert | Success only means the container started. Check stack logs and the Apprise target. |
|
||||
| Need Komodo to fail on findings | Not covered by `DeployStack`; use `FAIL_ON` in CI or trigger the scanner from a Komodo Action that runs `docker run --rm` and inspects the exit code. |
|
||||
|
||||
## Security note
|
||||
|
||||
The scanner mounts `/var/run/docker.sock` and runs as root inside the container.
|
||||
That is effectively root on the scan host, so only deploy it to servers and
|
||||
Komodo users you trust.
|
||||
@@ -0,0 +1,61 @@
|
||||
# Komodo Resource Sync - docker-vuln-scan (files on host mode)
|
||||
#
|
||||
# Use this variant if you do not want Komodo to clone the project from git.
|
||||
# Copy the project to the Komodo host at:
|
||||
#
|
||||
# /etc/komodo/stacks/vuln-scan/
|
||||
#
|
||||
# (that is the default Periphery root directory, mounted at the same path in the
|
||||
# standard Komodo compose setup; adjust if you changed PERIPHERY_ROOT_DIRECTORY)
|
||||
#
|
||||
# Then apply this file with a Komodo Resource Sync. See komodo/README.md.
|
||||
#
|
||||
# Before applying:
|
||||
# 1. Replace `server` with the name of the Komodo Server to scan on.
|
||||
# 2. Create a Komodo Variable named APPRISE_URLS (mark it Secret).
|
||||
# 3. Adjust IMAGES below or replace it with [[SCAN_IMAGES]].
|
||||
|
||||
[[stack]]
|
||||
name = "vuln-scan"
|
||||
description = "Trivy image vulnerability scan with Apprise notifications"
|
||||
tags = ["security"]
|
||||
deploy = false
|
||||
|
||||
[stack.config]
|
||||
server = "server-prod"
|
||||
files_on_host = true
|
||||
# Relative to /etc/komodo/stacks/vuln-scan/. Empty means the project root.
|
||||
run_directory = ""
|
||||
file_paths = ["docker-compose.yml"]
|
||||
run_build = true
|
||||
auto_pull = false
|
||||
ignore_services = ["vulnscan"]
|
||||
send_alerts = false
|
||||
environment = """
|
||||
IMAGES = nginx:1.27-alpine redis:7-alpine
|
||||
APPRISE_URLS = [[APPRISE_URLS]]
|
||||
APPRISE_TITLE_PREFIX = Vulnerability scan
|
||||
NOTIFY_MIN_SEVERITY = HIGH
|
||||
FAIL_ON = HIGH
|
||||
IGNORE_UNFIXED = false
|
||||
MAX_FINDINGS_IN_BODY = 15
|
||||
"""
|
||||
|
||||
[[procedure]]
|
||||
name = "vuln-scan"
|
||||
description = "Rebuild and run the image vulnerability scan"
|
||||
tags = ["security"]
|
||||
|
||||
[procedure.config]
|
||||
schedule_format = "Cron"
|
||||
schedule = "0 0 3 * * ?"
|
||||
schedule_timezone = "UTC"
|
||||
schedule_enabled = true
|
||||
schedule_alert = false
|
||||
failure_alert = true
|
||||
|
||||
[[procedure.config.stage]]
|
||||
name = "Run scanner"
|
||||
executions = [
|
||||
{ execution.type = "DeployStack", execution.params.stack = "vuln-scan" },
|
||||
]
|
||||
@@ -0,0 +1,65 @@
|
||||
# Komodo Resource Sync - docker-vuln-scan (git repo mode)
|
||||
#
|
||||
# Import this file with a Komodo Resource Sync (Syncs -> New Resource Sync ->
|
||||
# Git Repo) pointing at this repo. See komodo/README.md for the full walkthrough.
|
||||
#
|
||||
# Before applying:
|
||||
# 1. Replace `server` with the name of the Komodo Server to scan on.
|
||||
# 2. Replace `repo` with the git repo that contains this project.
|
||||
# 3. Create a Komodo Variable named APPRISE_URLS (mark it Secret).
|
||||
# 4. Adjust IMAGES below or replace it with [[SCAN_IMAGES]] and create that
|
||||
# variable instead.
|
||||
|
||||
[[stack]]
|
||||
name = "vuln-scan"
|
||||
description = "Trivy image vulnerability scan with Apprise notifications"
|
||||
tags = ["security"]
|
||||
# The scan is started by the Procedure below, not during sync.
|
||||
deploy = false
|
||||
|
||||
[stack.config]
|
||||
server = "server-prod"
|
||||
repo = "your-org/docker-vuln-scan"
|
||||
branch = "main"
|
||||
file_paths = ["docker-compose.yml"]
|
||||
run_directory = ""
|
||||
# Build the scanner image on the Komodo server (no registry required).
|
||||
run_build = true
|
||||
# Do NOT try to pull docker-vuln-scan:latest from a registry.
|
||||
auto_pull = false
|
||||
# The scanner is a one-shot container, so an exited service is expected.
|
||||
ignore_services = ["vulnscan"]
|
||||
# Apprise already reports findings; avoid "stack down" noise in Komodo.
|
||||
send_alerts = false
|
||||
environment = """
|
||||
IMAGES = nginx:1.27-alpine redis:7-alpine
|
||||
APPRISE_URLS = [[APPRISE_URLS]]
|
||||
APPRISE_TITLE_PREFIX = Vulnerability scan
|
||||
NOTIFY_MIN_SEVERITY = HIGH
|
||||
FAIL_ON = HIGH
|
||||
IGNORE_UNFIXED = false
|
||||
MAX_FINDINGS_IN_BODY = 15
|
||||
"""
|
||||
|
||||
[[procedure]]
|
||||
name = "vuln-scan"
|
||||
description = "Rebuild and run the image vulnerability scan"
|
||||
tags = ["security"]
|
||||
|
||||
[procedure.config]
|
||||
schedule_format = "Cron"
|
||||
# Every day at 03:00:00. Komodo cron has 6 fields (seconds first).
|
||||
schedule = "0 0 3 * * ?"
|
||||
schedule_timezone = "UTC"
|
||||
schedule_enabled = true
|
||||
# Findings are notified directly through Apprise.
|
||||
schedule_alert = false
|
||||
# Komodo alert if the build/deploy itself fails (needs a Komodo Alerter).
|
||||
failure_alert = true
|
||||
|
||||
[[procedure.config.stage]]
|
||||
name = "Run scanner"
|
||||
executions = [
|
||||
# DeployStack (not DeployStackIfChanged) forces the one-shot scanner to run.
|
||||
{ execution.type = "DeployStack", execution.params.stack = "vuln-scan" },
|
||||
]
|
||||
Reference in new issue
Block a user