refactor: distribute Acaua as a Docker image instead of a desktop app
Release / Plan (reuse the published image?) (push) Successful in 3s
CI / Docker image (build and smoke test) (push) Skipped
CI / Format and clippy (push) Successful in 4m32s
CI / Dependency audit (push) Successful in 11s
CI / Tests (Linux) (push) Successful in 9m15s
Release / ci (push) Successful in 9m18s
Release / Build image (arm64) (push) Failing after 7m7s
Release / Build image (amd64) (push) Failing after 13m53s
Release / Publish tags (push) Skipped
Release / Gitea release (push) Skipped
Release / Plan (reuse the published image?) (push) Successful in 3s
CI / Docker image (build and smoke test) (push) Skipped
CI / Format and clippy (push) Successful in 4m32s
CI / Dependency audit (push) Successful in 11s
CI / Tests (Linux) (push) Successful in 9m15s
Release / ci (push) Successful in 9m18s
Release / Build image (arm64) (push) Failing after 7m7s
Release / Build image (amd64) (push) Failing after 13m53s
Release / Publish tags (push) Skipped
Release / Gitea release (push) Skipped
Acaua is a collective SOC daemon consuming only Zeek log files, not a single-user tool needing local hardware like its siblings. Drop the Tauri desktop shell, installers and self-update entirely; the server and its web dashboard ship as a container, updated by pulling a new image tag. Link against the official prebuilt libduckdb instead of compiling it from source via the bundled feature, cutting image build time from 15+ minutes to about 3. Fix a real bug found along the way: as PID 1 in a container, the daemon ignored SIGTERM and was always killed after the stop timeout; it now shuts down gracefully. Also corrects the Pillar 1 beaconing score: the period estimate had a harmonic alias (a perfectly periodic 4h series resolved to 600s), and the old score formula flagged pure random traffic as suspicious (p95 = 0.839 on Poisson noise). The new formula was validated against 300 samples per scenario. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VAyr8d7HuAdUGB6aA5xmDD
This commit is contained in:
1 parent
1b974bb90d
commit
8a80504c45
72 files changed
+2524
-6384
No files matched your search
+57
-45
@@ -2,66 +2,78 @@
|
||||
|
||||
**English** · [Português](pt-BR/docker.md)
|
||||
|
||||
The image is for lab and research use. It runs the same `acaua` binary as a
|
||||
native install, with the embedded UI. The skeleton does not enable the DuckDB
|
||||
feature in the image; the store remains reserved for a later release.
|
||||
Acauã is distributed as an official container image:
|
||||
`git.lucasrguerra.dev.br/ciberfauna/acaua`.
|
||||
|
||||
## Build
|
||||
Available image tags:
|
||||
- `latest`: Most recent stable release.
|
||||
- `X.Y.Z` / `X.Y`: Pinned semantic versions.
|
||||
- `edge`: Built automatically from the `main` branch.
|
||||
|
||||
The container runs as an unprivileged system user (`acaua`, UID 10001), with a
|
||||
read-only root filesystem (`read_only: true`), all capabilities dropped
|
||||
(`cap_drop: [ALL]`), and security hardening (`no-new-privileges:true`).
|
||||
|
||||
## Compose deployment
|
||||
|
||||
The recommended production and lab deployment uses Docker Compose:
|
||||
|
||||
```bash
|
||||
docker build -t acaua .
|
||||
docker run --rm -p 127.0.0.1:8787:8787 -v "$PWD/data/acaua:/data/acaua" acaua
|
||||
cp .env.example .env # configure ZEEK_INTERFACE (authorized networks only)
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
The build stage uses `rust:1-slim-bookworm`; the runtime stage uses
|
||||
`debian:bookworm-slim` and installs only `ca-certificates`, `curl` and `tar`
|
||||
(the updater needs `curl` and `tar`).
|
||||
|
||||
## Compose
|
||||
To build and run locally from source:
|
||||
|
||||
```bash
|
||||
cp .env.example .env # optional: set ZEEK_INTERFACE
|
||||
docker compose up --build
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
The Compose file starts two services:
|
||||
The stack coordinates two services:
|
||||
|
||||
| Service | Purpose | Notes |
|
||||
|---|---|---|
|
||||
| `zeek` | Capture and write Zeek logs to `./data/zeek` | Host network and `NET_RAW`/`NET_ADMIN` |
|
||||
| `acaua` | Read logs and serve the UI/API | Host port bound to `127.0.0.1:8787` |
|
||||
| Service | Image | Purpose | Security profile |
|
||||
|---|---|---|---|
|
||||
| `zeek` | `zeek/zeek:9.0.1` | Network packet capture and hourly log rotation | Host network, `NET_RAW` and `NET_ADMIN` capabilities |
|
||||
| `acaua` | `git.lucasrguerra.dev.br/ciberfauna/acaua` | Analytical processing, API and web dashboard | Unprivileged (UID 10001), read-only rootfs, no capabilities |
|
||||
|
||||
`acaua` mounts `./data/zeek` read-only at `/data/zeek` and `./data/acaua`
|
||||
read-write at `/data/acaua`. The daemon inside the container binds
|
||||
`0.0.0.0:8787`, but the published port is loopback-only on the host.
|
||||
## Volumes and data layout
|
||||
|
||||
## Data layout
|
||||
The stack uses named volumes to manage ownership and permissions cleanly:
|
||||
|
||||
```text
|
||||
data/
|
||||
zeek/ # Zeek logs, written by the zeek service
|
||||
acaua/ # store, exports and runtime files
|
||||
- `zeek-logs`: Shared volume mounted at `/logs` in the Zeek service and mounted
|
||||
**read-only** at `/data/zeek:ro` in the Acauã service.
|
||||
- `acaua-data`: Dedicated read-write volume mounted at `/data/acaua` for DuckDB
|
||||
analytical store, Parquet partitions and runtime files.
|
||||
|
||||
To inspect or extract data on the host:
|
||||
|
||||
```bash
|
||||
docker compose cp acaua:/data/acaua ./local-acaua-backup
|
||||
```
|
||||
|
||||
Do not mount the host root or a directory containing unrelated sensitive files.
|
||||
The parser is expected to confine paths to the dataset root; the skeleton does
|
||||
not parse records yet.
|
||||
Or run a one-off inspection container:
|
||||
|
||||
```bash
|
||||
docker run --rm -v acaua_acaua-data:/data:ro debian:trixie-slim ls -la /data
|
||||
```
|
||||
|
||||
## Updating
|
||||
|
||||
Because Acauã runs as a multi-user collective SOC daemon, updates are performed
|
||||
by pulling the latest verified image:
|
||||
|
||||
```bash
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
The running daemon shuts down cleanly on `SIGTERM` within sub-second intervals,
|
||||
ensuring Parquet writes and DuckDB transactions are committed properly.
|
||||
|
||||
## Security notes
|
||||
|
||||
- The `zeek` service needs packet capture privileges. Run it only on an
|
||||
interface and network you are authorized to monitor.
|
||||
- Do not change the host port mapping to `0.0.0.0:8787` without an
|
||||
authenticating reverse proxy.
|
||||
- The image has no telemetry and no outbound connection except an explicit
|
||||
`acaua update`.
|
||||
- The container is not a sandbox for hostile datasets. Treat a malformed capture
|
||||
as hostile input and keep the container unprivileged.
|
||||
|
||||
## Limitations
|
||||
|
||||
- No DuckDB build in the image; the analytical store is not active.
|
||||
- The UI is a shell and `analyze` returns a stub report.
|
||||
- The image does not include Zeek; the Compose file uses the upstream Zeek
|
||||
image.
|
||||
- There is no published image registry yet. Build locally.
|
||||
- The `zeek` service requires packet capture privileges (`NET_RAW`, `NET_ADMIN`).
|
||||
Run it only on interfaces and networks you are explicitly authorized to monitor.
|
||||
- The default dashboard binding is loopback-only (`ACAUA_PUBLISH=127.0.0.1:8787`).
|
||||
Do not expose the service on external interfaces without an authenticating reverse proxy.
|
||||
- The image contains no telemetry. Outbound traffic is restricted to operator-initiated
|
||||
update checks against the Gitea Releases API.
|
||||
Reference in new issue
Block a user