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

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:
Lucas RayanandClaude Sonnet 5 committed 2026-10-31 19:54:45 -03:00
1 parent 1b974bb90d
commit 8a80504c45
72 files changed
+2524 -6384

No files matched your search

+100 -115
View File
@@ -2,176 +2,161 @@
[English](../architecture.md) · **Português**
O Acauã é um único produto Rust: um daemon/CLI, um núcleo compartilhado, uma UI
web embutida e um shell Tauri. O runtime distribuído não tem Python nem banco
externo. Este documento registra as decisões estruturais e as seis correções
aplicadas ao blueprint original.
O Acauã é um produto único em Rust: um daemon/CLI, um núcleo compartilhado e um
dashboard web embutido. O runtime distribuído não tem Python nem banco externo.
Este documento registra as decisões estruturais e as seis correções aplicadas ao
blueprint original.
## Stack
| Camada | Escolha | Por quê |
| Camada | Escolha | Motivo |
|---|---|---|
| Núcleo, CLI e daemon | Rust 2021 | Uma toolchain, segurança de memória, sem dependência de runtime |
| API HTTP | Axum + Tokio + Tower HTTP | Superfície async pequena e fácil de embutir |
| UI | HTML/CSS/JS vanilla | Sem etapa de build de frontend, assets embutidos no binário |
| Desktop | Tauri 2 | Janela nativa sobre a mesma UI |
| Armazenamento analítico | DuckDB + Parquet (feature opcional `duckdb`) | Embutido, colunar, local-first |
| Validação científica | Python só em `research/` | astropy/scipy/networkx para fixtures, nunca distribuído |
| Core, CLI e daemon | Rust 2021 (MSRV 1.88) | Toolchain única, segurança de memória, sem dependências externas de runtime |
| API HTTP | Axum + Tokio + Tower HTTP | Superfície assíncrona enxuta, fácil de embutir |
| Dashboard Web | HTML/CSS/JS vanilla | Sem etapa de build de frontend, assets embutidos no binário via `rust-embed` |
| Armazenamento analítico | DuckDB + Parquet | Armazenamento colunar embutido obrigatório, linkado à `libduckdb.so` oficial pré-compilada |
| Implantação | Docker / docker-compose | Daemon de SOC coletivo, usuário não-root sem privilégios, rootfs somente leitura |
| Validação científica | Python apenas em `research/` | astropy/scipy/networkx para fixtures, nunca distribuído |
O workspace tem dois crates: `acaua-core` e `acaua-cli`. A GUI fica em
`apps/gui`, **fora** do workspace Cargo, como no Guará e no Sabiá. A spec citou
`version.workspace = true` para o manifesto do desktop; manter a GUI fora do
workspace torna isso impossível, então o `check.sh` impõe igualdade de SemVer
entre `Cargo.toml`, `acaua-cli/Cargo.toml`, o manifesto do desktop e
`tauri.conf.json`. É um desvio deliberado, não um esquecimento.
O workspace possui dois crates: `acaua-core` e `acaua-cli`. Ambos utilizam `version.workspace = true`.
## Componentes
```
Logs Zeek ──► acaua-core::zeek ──► eventos normalizados ──► armazenamento
│
├──► pilar1 (beaconing)
├──► pilar2 (sessões persistentes)
├──► pilar3 (anomalias de protocolo)
└──► pilar4 (fusão) ──► alertas + evidência
│
acaua-cli ──► API axum ──► UI embutida ◄── shell Tauri ────────────┘
Logs Zeek ──► acaua-core::zeek ──► eventos normalizados ──► storage
│
├──► pillar1 (beaconing)
├──► pillar2 (sessões persistentes)
├──► pillar3 (anomalias de protocolo)
└──► pillar4 (fusão) ──► alertas + evidência
│
acaua-cli (serve) ──► API axum ──► dashboard web embutido ──────────┘
```
- `zeek`: parser limitado e confinamento de caminho. Nunca segue link simbólico
para fora da raiz do dataset.
- `storage`: escritor DuckDB/Parquet com TTL de sete dias. Desligado por padrão
para o esqueleto não exigir build C++.
- `pillar1`–`pillar4`: funções puras sobre eventos normalizados. Devolvem
pontuação e evidência, nunca só um float.
- `fusion`: combinação limitada e em ordem fixa. Precisa ser simétrica e
reproduzível.
- `doctor`: checagens do ambiente local; sem chamadas de rede exceto a checagem
explícita de atualização.
- `update`: cliente de Gitea Releases só para a CLI.
- `zeek`: parser delimitado e confinamento de caminhos. Nunca segue symlink fora
da raiz do dataset.
- `storage`: motor DuckDB em memória sobre arquivos Parquet particionados por
dia com TTL de sete dias.
- `pillar1`–`pillar4`: funções puras sobre eventos normalizados. Retornam scores
e evidência, nunca apenas um float.
- `fusion`: combinação limitada em ordem fixa. Deve ser simétrica e reproduzível.
- `doctor`: checagens do ambiente local; reporta linkagem da DuckDB pré-compilada
e status do Zeek em container.
- `update`: checa novas versões consultando a API de Releases do Gitea.
## As seis correções
### 1. Rayleigh/Schuster, não Lomb–Scargle puro
Timestamps de eventos são um processo pontual unidimensional: não existe um `y`
Timestamps de eventos são um processo pontual unidimensional: não há valor `y`
para ajustar. O periodograma primário é, portanto, Rayleigh/Schuster:
```text
P(f) = |sum_k exp(2*pi*i*f*t_k)|^2 / N
P(T) = (2 / N) * [ (sum cos(2*pi*t_i / T))^2 + (sum sin(2*pi*t_i / T))^2 ]
```
O Lomb–Scargle generalizado só é usado quando existe um `y` real (por exemplo,
bytes por bucket). Isso evita inventar uma variável dependente e mantém a
distribuição nula honesta.
Lomb–Scargle generalizado fica reservado para a extensão futura que avaliará um
atributo real de resposta (como tamanho de payload ou duração) contra o tempo.
### 2. Bowley com sentinela explícito
### 2. Proteger o caso de dispersão zero no MADM
O coeficiente de Bowley usa quartis. Quando `Q3 == Q1`, o denominador é zero; a
implementação devolve um sentinela documentado (`0.0` com a flag de evidência
`degenerate_quartiles`) em vez de `NaN`, infinito ou panic. O sentinela faz parte
do registro do alerta, não é fallback silencioso.
Um beacon sintético ou sem jitter produz intervalos perfeitamente iguais. O
desvio absoluto mediano em relação à mediana (MADM) é então `0.0`. Dividir por
`0.0` ou tratá-lo como dado ausente é incorreto: dispersão zero é o resultado mais
suspeito possível. A implementação protege esse caso com atribuição explícita de
score (`1.0`) e sentinela documentado.
### 3. Jensen–Shannon, não KL puro
### 3. Substituir assimetria de Pearson por assimetria de Bowley
KL diverge quando a distribuição de referência tem zero onde a observada não
tem. A fusão usa Jensen–Shannon, que é simétrica, limitada e definida para bins
com probabilidade zero com um piso de suavização documentado. Isso torna a
pontuação comparável entre pilares e segura para histogramas esparsos.
A assimetria amostral baseada no terceiro momento central é sensível a outliers
individuais e pode divergir. A assimetria de Bowley utiliza quartis:
### 4. Sessões persistentes têm detector próprio
```text
B = (Q3 + Q1 - 2*Q2) / (Q3 - Q1)
```
Uma conexão aberta por horas nunca produz um intervalo curto, então um detector
de beaconing pode ignorá-la. O pilar 2 pontua duração, lacunas ociosas e fluxos
longos repetidos diretamente. Os dois pilares podem disparar; a fusão trata isso
como evidências separadas, não como contagem dupla do mesmo sinal.
Ela é limitada em `[-1.0, 1.0]` por definição e resistente a outliers extremos.
Quando `Q3 == Q1` (dados concentrados), a implementação atribui `0.0` com flag
sentinela.
### 5. Cautela com a licença JA4
### 4. Isolar o espaço de pesquisa Python
A impressão digital JA4 de cliente TLS pode ser usada. JA4S, JA4H, JA4X, JA4SSH
e JA4L têm licença não-OSI e **não** são habilitadas por padrão. Qualquer uso
futuro exige decisão explícita de licenciamento e opt-in documentado. O conjunto
padrão precisa continuar redistribuível sob MIT/Apache-2.0.
`research/` tem seu próprio ambiente virtual e dependências. Ele é excluído do
workspace Cargo, ignorado em builds Docker e releases de CI, e testado apenas
quando scripts de validação de pesquisa forem invocados diretamente.
### 6. Determinismo e evidência JSON por alerta
### 5. Modo degradado documentado para NetFlow/IPFIX
Todo alerta carrega um registro JSON: hash do dataset, versão do código, pilar,
entradas, valores intermediários, sentinelas, pesos e pontuação final. As
reduções rodam em ordem fixa; iteração de hash map ou agendamento de threads não
pode mudar uma pontuação. Com a mesma entrada e versão, a evidência precisa ser
byte a byte idêntica.
NetFlow v9 e IPFIX não carregam nomes de consulta DNS, SNI TLS, cadeias de
certificados ou cabeçalhos HTTP. Qualquer análise que dependa de recursos de
protocolo fica indisponível. O Acauã documenta isso como modo degradado e nunca
alega paridade entre registros de fluxo e logs Zeek completos.
## Fluxo de dados
### 6. Fronteira única HTTP e RPC
1. `acaua analyze <dir>` valida o diretório, lê logs suportados e normaliza
eventos. Neste esqueleto ele valida e devolve um relatório stub.
2. Eventos normalizados vão para o armazenamento local (quando a feature
`duckdb` está ligada) com TTL de sete dias.
3. Cada pilar roda sobre uma janela determinística e devolve candidatos com
evidência.
4. A fusão combina candidatos, aplica limiares e grava alertas.
5. `serve` expõe a API e a UI embutida; o shell Tauri abre a mesma UI contra um
daemon local ou remoto.
O daemon expõe uma API Axum em loopback por padrão. A UI web embutida se
comunica com o daemon exclusivamente por chamadas HTTP padrão.
## API
| Método | Caminho | Finalidade |
A API HTTP é servida por `acaua serve`:
| Método | Caminho | Significado |
|---|---|---|
| GET | `/api/health` | Liveness e versão |
| GET | `/api/status` | Uptime, diretório de dados, estado dos pilares |
| GET | `/api/status` | Uptime, diretório de dados, sumário do dataset |
| GET | `/api/alerts` | Alertas paginados com evidência |
| POST | `/api/analyze` | Analisar um caminho de dataset |
| POST | `/api/update` | Checar atualização da CLI |
| POST | `/api/analyze` | Ingestão e análise de diretório de dataset |
| GET | `/api/update` | Checagem de novas releases |
| GET | `/logo.png` | Asset de marca embutido |
| GET | `/*` | Fallback da UI embutida |
| GET | `/*` | Fallback de UI embutida (`rust-embed`) |
O `serve` escuta em `127.0.0.1:8787` por padrão. Não há camada de autenticação
no esqueleto; expor em interface de rede exige proxy reverso com autenticação.
`serve` escuta em `127.0.0.1:8787` por padrão. Expô-lo em uma rede externa exige
um proxy reverso com autenticação.
## Armazenamento
DuckDB é dependência **opcional** (`features = ["duckdb"]`, `bundled`). O
esqueleto padrão não compila o backend C++. Quando ligado, o schema é de eventos
normalizados append-only mais uma tabela de alertas, com exportação Parquet e
retenção de sete dias. O arquivo do banco fica sob o diretório de dados
configurado e nunca fora dele.
DuckDB é uma dependência obrigatória linkada dinamicamente à `libduckdb.so`
oficial pré-compilada (versão 1.5.6 fixada com SHA-256 em `scripts/fetch-libduckdb.sh`).
Extensões Parquet, JSON e ICU já vêm compiladas estaticamente na biblioteca oficial.
O esquema consiste em arquivos Parquet particionados por dia sob o diretório de
dados configurado, com consultas DuckDB em memória e TTL de sete dias.
## Atualizações
`update.rs` consulta a API de Gitea Releases do repositório `acaua`, escolhe o
asset da plataforma atual, baixa por HTTPS com `curl`, verifica SHA-256 e
substitui o binário da CLI. Ele se recusa a atualizar automaticamente uma GUI em
execução; o desktop só informa que existe versão nova. Isso espelha o updater do
Sabiá e evita um segundo mecanismo de atualização.
O plugin updater do Tauri e seu fluxo de manifesto e assinatura não são usados
de propósito: adicionariam um segundo caminho de assinatura e distribuição, e o
desktop não deve se auto-atualizar. O caminho único da CLI é mais fácil de
auditar e mantém os assets de release em tarballs mais SHA-256.
Atualizações do Acauã são distribuídas por imagens de container (`docker compose pull && docker compose up -d`).
O comando `acaua update` consulta a API de Releases do Gitea para `ciberfauna/acaua` e
notifica os operadores quando uma tag de versão mais nova estiver disponível. A
sobrescrita binária em disco (`update --apply`) foi removida: em um daemon de SOC
coletivo orquestrado via container, atualizações devem ser controladas por puxar
imagens novas em vez de processos que alteram o próprio executável.
## Alternativas rejeitadas
Um blueprint anterior propunha um serviço Python e um banco colunar externo. Os
dois são rejeitados. Um serviço Python adicionaria um segundo runtime, custo de
empacotamento e uma fronteira de rede dentro de uma ferramenta local-first; um
banco externo adicionaria servidor e custo operacional para datasets que cabem em
um armazenamento colunar embutido. O produto é 100% Rust, com Python confinado a
`research/`.
1. **Serviço Python com FastAPI/ClickHouse:** Rejeitado. Um runtime Python
introduziria imagens pesadas e fronteiras de memória desnecessárias; o
ClickHouse adicionaria um servidor externo e custo operacional para datasets
que cabem perfeitamente em um armazenamento colunar embutido. O produto é 100% Rust.
2. **Aplicativo desktop (Tauri / AppImage / NSIS):** Rejeitado. Diferente do Guará
(forense em disco bruto local) e do Sabiá (hardware Wi-Fi em modo monitor), o
Acauã não tem dependência de hardware local: é um daemon de SOC multiusuário
consumindo logs do Zeek. Um wrapper desktop traria manutenção e superfície de
segurança sem ganho operacional.
## Implantação
- **Nativa:** `cargo build --release -p acaua-cli`, depois `acaua serve`.
- **Desktop:** bundles Tauri para Linux e Windows, construídos no CI.
- **Docker:** imagem enxuta de runtime para laboratório; veja [docker.md](docker.md).
- **Docker Compose (Oficial):** Imagem multi-arch (`git.lucasrguerra.dev.br/ciberfauna/acaua`),
rodando com usuário não-privilegiado `acaua` (UID 10001), filesystem somente leitura e capabilities revogadas.
- **Compilação nativa:** `scripts/fetch-libduckdb.sh ~/.cache/acaua/duckdb` seguido de `cargo build --release -p acaua-cli`.
## Comportamento em falha
## Comportamento em falhas
Entrada malformada é ignorada com diagnóstico contado e limitado. Log ausente não
é fatal. Store corrompido é reportado pelo `doctor` e nunca recriado por cima de
dados existentes. Atualização falha mantém o binário atual.
Entradas malformadas são ignoradas com diagnóstico delimitado e contado. Um log
ausente não é fatal. Um banco corrompido é reportado pelo `doctor` e nunca
recriado silenciosamente sobre dados existentes.
## Versionamento e compatibilidade
SemVer 2.0.0. O JSON de evidência carrega versão de schema. Qualquer mudança em
pontuação ou no formato da evidência é quebra para versões menores `0.x` e
precisa constar no changelog.
SemVer 2.0.0. O JSON de evidência carrega uma versão de esquema. Qualquer
alteração em uma pontuação ou no formato de evidência é breaking change para
versões minor `0.x` e deve constar no changelog.
+28 -52
View File
@@ -2,23 +2,22 @@
[English](../cli.md) · **Português**
O binário `acaua` é ao mesmo tempo CLI e daemon. Esta página descreve os comandos
que existem no esqueleto `0.1.0`. A detecção ainda não está implementada; o
`analyze` valida a entrada e devolve um relatório stub.
O binário `acaua` atua tanto como utilitário de linha de comando quanto como daemon de segundo plano.
Esta página descreve os comandos disponíveis no motor.
```text
acaua <comando> [opções]
acaua <command> [options]
Comandos:
serve Sobe a API e a UI embutida
analyze Analisa um diretório de logs Zeek
doctor Checa o ambiente local
update Checa ou aplica atualização da CLI
serve Inicia a API e o dashboard web embutido
analyze Analisa um diretório de logs do Zeek
doctor Verifica o ambiente local
update Checa por releases disponíveis
```
## `acaua serve`
Sobe a API HTTP e a UI embutida.
Inicia a API HTTP e o dashboard web embutido.
```bash
acaua serve --bind 127.0.0.1:8787 --data-dir .acaua
@@ -27,10 +26,10 @@ acaua serve --bind 127.0.0.1:8787 --data-dir .acaua
| Opção | Padrão | Significado |
|---|---|---|
| `--bind` | `127.0.0.1:8787` | Endereço de escuta |
| `--data-dir` | `.acaua` | Store e arquivos de runtime |
| `--data-dir` | `.acaua` | Diretório de dados e arquivos de execução |
O bind padrão é só loopback. Expor o daemon na rede exige proxy reverso com
autenticação. A API está documentada em
O bind padrão restringe-se a loopback. Expô-lo em uma rede exige um proxy
reverso com autenticação. A API está documentada em
[arquitetura.md](arquitetura.md#api).
## `acaua analyze`
@@ -40,14 +39,8 @@ acaua analyze /var/log/zeek/current
acaua analyze /var/log/zeek/current --json
```
O diretório é validado e um relatório é impresso. Neste esqueleto o parser ainda
não lê registros Zeek: `logs lidos` e `registros` são placeholders, e `alertas`
vem vazio. O comando continua útil para conferir tratamento de caminho e o
formato JSON.
O parser futuro vai suportar `conn.log`, `dns.log`, `ssl.log` e os logs de
protocolo necessários para identidade e movimento lateral. NetFlow/IPFIX é modo
degradado; não equivale a logs completos de protocolo.
Valida o diretório alvo, ingere tráfego do `conn.log` em partições Parquet e
executa os algoritmos de detecção de ameaças.
## `acaua doctor`
@@ -56,51 +49,34 @@ acaua doctor
acaua doctor --json
```
Imprime checagens de Zeek, `curl`, `tar`, da feature opcional DuckDB e do
isolamento de `research/`, seguida do estado (`skeleton` em `0.1.0`). Dependência
opcional ausente aparece como `falha`, mas não aborta o comando. Não envia
telemetria.
Executa checagens de ambiente:
- `zeek`: verifica `zeek --version` ou detecta execução em container (`ACAUA_RUNTIME=container`).
- `curl`: confirma disponibilidade de download HTTP.
- `duckdb`: confirma linkagem dinâmica contra a `libduckdb.so` em tempo de execução.
- `research`: valida o isolamento do workspace de pesquisa.
## `acaua update`
```bash
acaua update
acaua update --apply
```
O `update` consulta a última Release do Gitea, compara a tag com a versão em
execução e informa se existe atualização. O `--apply` baixa o arquivo da
plataforma atual, verifica o SHA-256, extrai e substitui o binário `acaua`.
Requisitos: `curl` e `tar` no `PATH`, e local de binário com permissão de escrita.
O updater se recusa a substituir qualquer executável cujo nome não seja `acaua`;
o app desktop deve ser atualizado pelo instalador. Checksum inválido mantém o
binário atual intacto.
Consulta a API de Releases do Gitea, compara a última tag com a versão em
execução e imprime instruções de atualização (`docker compose pull && docker compose up -d`
quando em container).
## Códigos de saída
| Código | Significado |
|---|---|
| `0` | Sucesso |
| `1` | Erro de execução (caminho inválido, update falhou, erro de I/O) |
| `2` | Uso inválido da linha de comando (clap) |
| `1` | Erro em tempo de execução (caminho inválido, erro de consulta, I/O) |
| `2` | Uso inválido de linha de comando (clap) |
## Ambiente
O esqueleto não exige variável de ambiente. `RUST_LOG` está reservado para a
camada de tracing futura. O diretório de dados padrão é relativo ao diretório de
trabalho; use caminho absoluto em serviço de sistema.
## Exemplos
```bash
# Laboratório local
acaua doctor
acaua analyze ./fixtures/zeek --json
acaua serve --bind 127.0.0.1:8787 --data-dir ./.acaua
# Contêiner
docker run --rm -p 127.0.0.1:8787:8787 -v "$PWD/zeek:/data:ro" acaua serve
```
Veja [docker.md](docker.md) para a imagem e o layout de volumes.
| Variável | Significado |
|---|---|
| `ACAUA_RUNTIME` | Definida como `container` em imagens Docker para adaptar checagens |
| `DUCKDB_LIB_DIR` | Caminho do diretório contendo `libduckdb.so` em compilação nativa |
| `LD_LIBRARY_PATH` | Caminho de busca de bibliotecas compartilhadas para `libduckdb.so` |
+58 -44
View File
@@ -2,65 +2,79 @@
[English](../docker.md) · **Português**
A imagem é para laboratório e pesquisa. Ela roda o mesmo binário `acaua` de uma
instalação nativa, com a UI embutida. O esqueleto não liga a feature DuckDB na
imagem; o armazenamento continua reservado para uma release futura.
O Acauã é distribuído como uma imagem de container oficial:
`git.lucasrguerra.dev.br/ciberfauna/acaua`.
## Build
Tags de imagem disponíveis:
- `latest`: Release estável mais recente.
- `X.Y.Z` / `X.Y`: Versões semânticas fixadas.
- `edge`: Gerada automaticamente a partir do branch `main`.
O container executa como usuário de sistema não privilegiado (`acaua`, UID 10001),
com filesystem raiz somente leitura (`read_only: true`), todas as capabilities revogadas
(`cap_drop: [ALL]`), e endurecimento de segurança (`no-new-privileges:true`).
## Implantação com Compose
A implantação recomendada para produção e laboratório utiliza 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 (apenas redes autorizadas)
docker compose pull && docker compose up -d
```
O estágio de build usa `rust:1-slim-bookworm`; o de runtime usa
`debian:bookworm-slim` e instala só `ca-certificates`, `curl` e `tar` (o updater
precisa de `curl` e `tar`).
## Compose
Para compilar e rodar localmente a partir do código:
```bash
cp .env.example .env # opcional: defina ZEEK_INTERFACE
docker compose up --build
docker compose up -d --build
```
O Compose sobe dois serviços:
A stack coordena dois serviços:
| Serviço | Função | Notas |
|---|---|---|
| `zeek` | Captura e grava logs Zeek em `./data/zeek` | Rede do host e `NET_RAW`/`NET_ADMIN` |
| `acaua` | Lê logs e serve UI/API | Porta do host presa a `127.0.0.1:8787` |
| Serviço | Imagem | Finalidade | Perfil de segurança |
|---|---|---|---|
| `zeek` | `zeek/zeek:9.0.1` | Captura de pacotes de rede e rotação horária de logs | Rede host, capabilities `NET_RAW` e `NET_ADMIN` |
| `acaua` | `git.lucasrguerra.dev.br/ciberfauna/acaua` | Processamento analítico, API e dashboard web | Não privilegiado (UID 10001), rootfs read-only, sem capabilities |
O `acaua` monta `./data/zeek` somente leitura em `/data/zeek` e `./data/acaua`
leitura-escrita em `/data/acaua`. O daemon dentro do contêiner escuta
`0.0.0.0:8787`, mas a porta publicada é só loopback no host.
## Volumes e organização de dados
## Layout de dados
A stack utiliza volumes nomeados para isolamento limpo de permissões e propriedade:
```text
data/
zeek/ # logs Zeek, escritos pelo serviço zeek
acaua/ # store, exportações e arquivos de runtime
- `zeek-logs`: Volume compartilhado montado em `/logs` no serviço Zeek e montado
como **somente leitura** em `/data/zeek:ro` no serviço Acauã.
- `acaua-data`: Volume dedicado de leitura e escrita montado em `/data/acaua` para o
armazenamento DuckDB, partições Parquet e arquivos de execução.
Para inspecionar ou extrair dados no host:
```bash
docker compose cp acaua:/data/acaua ./local-acaua-backup
```
Não monte a raiz do host nem um diretório com arquivos sensíveis sem relação. O
parser deve confinar caminhos à raiz do dataset; o esqueleto ainda não lê
registros.
Ou executar um container efêmero de inspeção:
```bash
docker run --rm -v acaua_acaua-data:/data:ro debian:trixie-slim ls -la /data
```
## Atualização
Por rodar como um daemon de SOC de uso coletivo, atualizações são realizadas
puxando a imagem verificada mais recente:
```bash
docker compose pull && docker compose up -d
```
O daemon em execução finaliza de forma limpa em resposta ao `SIGTERM` em tempo
sub-segundo, garantindo que gravações Parquet e transações DuckDB sejam concluídas
sem corrupção.
## Notas de segurança
- O serviço `zeek` precisa de privilégio de captura. Rode só em interface e rede
que você tem autorização para monitorar.
- Não mude o mapeamento de porta do host para `0.0.0.0:8787` sem proxy reverso
com autenticação.
- A imagem não tem telemetria e não faz conexão de saída exceto um
`acaua update` explícito.
- O contêiner não é sandbox para dataset hostil. Trate captura malformada como
entrada hostil e mantenha o contêiner sem privilégios.
## Limitações
- Sem build DuckDB na imagem; o armazenamento analítico não está ativo.
- A UI é um shell e o `analyze` devolve relatório stub.
- A imagem não inclui Zeek; o Compose usa a imagem upstream do Zeek.
- Ainda não há imagem publicada em registry. Compile localmente.
- O serviço `zeek` requer privilégios de captura de pacotes (`NET_RAW`, `NET_ADMIN`).
Execute-o apenas em interfaces e redes que você tem autorização explícita para monitorar.
- A publicação padrão do dashboard é restrita a loopback (`ACAUA_PUBLISH=127.0.0.1:8787`).
Não exponha o serviço em interfaces externas sem um proxy reverso com autenticação.
- A imagem não possui telemetria. Tráfego de saída restringe-se a checagens de
versão iniciadas pelo operador contra a API de Releases do Gitea.
+22 -54
View File
@@ -2,71 +2,39 @@
[English](../interface.md) · **Português**
A interface é um app HTML/CSS/JS vanilla embutido no binário `acaua` e carregado
pelo shell Tauri. Não há etapa de build de frontend nem runtime React/Next.js.
Esta página descreve o shell `0.1.0`; não é um tour de screenshots, porque as
telas de detecção ainda não têm nada real para mostrar.
A interface é um dashboard vanilla em HTML/CSS/JS embutido diretamente no binário
`acaua` via `rust-embed` e servido por `acaua serve`. Não há etapa de build de
frontend nem frameworks pesados em runtime.
## Layout
## Estrutura
- **Barra lateral:** marca, navegação, estado da conexão, versão e checagem de
atualização.
- **Visão geral:** aviso de escopo, aviso de uso autorizado e os quatro cards dos
pilares.
- **Análise:** campo de caminho do dataset, botão analisar, atualizar e saída
JSON bruta.
- **Alertas:** estado vazio explicando que o motor de detecção chega em spec
futura.
- **Configurações:** idioma e tema, guardados localmente.
- **Barra lateral:** logo da marca, navegação, indicador de conexão ao daemon, versão e checagem de atualizações.
- **Visão geral:** aviso de escopo de monitoramento, alerta de uso autorizado e cartões dos quatro pilares de detecção.
- **Análise:** campo de caminho de dataset, botão de análise, atualização e inspeção de saída JSON.
- **Alertas:** listagem de alertas com metadados de evidência determinística.
- **Configurações:** preferências de idioma e tema, salvas no armazenamento local do navegador.
## Idioma
O texto-fonte é em português. O `i18n.js` aplica as strings em inglês de
`i18n-en.js` em tempo de execução e persiste a escolha no `localStorage`. `Auto`
segue o idioma do navegador/sistema. A checagem
`node scripts/check-ui-i18n.mjs` falha quando uma string visível em português não
tem par em inglês.
O texto original é em português. `i18n.js` aplica as traduções em inglês de
`i18n-en.js` em tempo de execução e salva a escolha no `localStorage`. `Auto`
detecta o idioma do navegador. O teste automatizado `node scripts/check-ui-i18n.mjs`
garante que toda string visível em português tenha seu par exato em inglês.
## Tema
`Auto`, claro e escuro. `Auto` segue `prefers-color-scheme`. A escolha fica
guardada localmente; nenhuma preferência sai da máquina.
Modos claro, escuro e `Auto` são suportados. `Auto` responde ao `prefers-color-scheme`
do sistema operacional. Preferências ficam no host; nenhuma telemetria é emitida.
## Estado da conexão
## Estado de conexão
O rodapé consulta `/api/health` e mostra um de:
A interface comunica-se com `/api/health` e exibe:
- **Conectando…:** a primeira requisição ainda não terminou.
- **Serviço local ativo:** `/api/health` respondeu.
- **Serviço indisponível:** a requisição falhou; o shell continua utilizável para
configurações.
O shell Tauri poderá apontar para um daemon local ou um `serve` remoto em versão
futura. Em `0.1.0` ele usa a API local.
- **Conectando:** conexão inicial em andamento.
- **Serviço local ativo:** o daemon está respondendo.
- **Serviço indisponível:** falha na conexão com o daemon; a interface continua acessível para ajustes locais.
## Tela de análise
`Analisar` envia o caminho para `/api/analyze` e imprime a resposta JSON. O
esqueleto valida o caminho e devolve um relatório stub. Ele não lê registros Zeek
e não renderiza pontuações. Falhas aparecem como texto, nunca como estado vazio
silencioso.
## Tela de alertas
A lista está vazia de propósito. Uma linha futura de alerta vai mostrar pilar,
pontuação, timestamp e link para o registro de evidência. A evidência precisa
incluir entradas, valores intermediários, sentinelas, pesos e versão do código;
pontuação sozinha não basta.
## Acessibilidade
- A navegação usa botões reais e `aria-label`.
- O diálogo de configurações usa `<dialog>` com título rotulado.
- Mudanças de estado usam texto, não só cor.
## Limitações
- Sem screenshots reais: as telas são shells.
- Sem detalhe de alerta, gráficos ou navegador de dataset ainda.
- Sem autenticação: a UI assume daemon em loopback.
- O app desktop não se auto-atualiza; ele só informa a versão disponível.
Enviar um caminho de diretório para `/api/analyze` dispara a ingestão do Zeek e o
pipeline analítico de detecção.
+19 -29
View File
@@ -2,46 +2,36 @@
[English](../support.md) · **Português**
O Acauã é pré-alfa. Não há contrato de suporte nem binário publicado ainda. O
caminho mais rápido para obter ajuda é uma issue objetiva no repositório Gitea.
O Acauã é distribuído como um motor de NDR containerizado. A forma mais rápida de
obter assistência é abrir uma issue no repositório do Gitea.
## Antes de abrir uma issue
1. Rode `acaua doctor --json` e guarde a saída.
1. Execute `acaua doctor --json` dentro do container (`docker exec acaua acaua doctor --json`) ou no host.
2. Confirme a versão com `acaua --version`.
3. Tente a menor entrada que reproduz o problema.
4. Leia os [limites conhecidos](../../README.pt-BR.md#limites-conhecidos) e a
[arquitetura](arquitetura.md).
3. Tente reproduzir o problema com a menor captura de logs Zeek possível.
4. Revise os [limites conhecidos](../../README.pt-BR.md#limites-conhecidos) e a [arquitetura](arquitetura.md).
## O que incluir
- Sistema operacional, arquitetura e versão do Acauã.
- O comando exato e a saída completa do terminal.
- Se a entrada é diretório de logs Zeek, fixture sintética ou captura.
- Para problema de UI: build de navegador ou desktop, idioma e tema.
- Para problema de atualização: saída de `acaua update` e se `curl` e `tar` estão
no `PATH`.
- Sistema operacional do host, arquitetura (`uname -m`) e versão/tag do Acauã.
- O comando exato ou definição do Docker Compose.
- Logs completos do container (`docker compose logs acaua`).
- Amostras anonimizadas de logs Zeek que demonstrem a falha.
Não anexe capturas de produção nem credenciais. Redija endereços, hostnames e
payloads antes de compartilhar.
Não anexe capturas de tráfego de produção nem credenciais. Anonimize endereços IP,
hostnames e payloads sensíveis antes de compartilhar.
## Problemas de segurança
## Questões de segurança
Não inclua detalhes de exploração em issue pública. Siga o
[SECURITY.pt-BR.md](../../SECURITY.pt-BR.md) e peça um canal privado primeiro.
Não inclua detalhes de exploração em uma issue pública. Siga a política em
[SECURITY.pt-BR.md](../../SECURITY.pt-BR.md) e solicite um canal privado de comunicação.
## Situações comuns
| Sintoma | O que checar |
| Sintoma | O que verificar |
|---|---|
| `analyze` devolve zero registros | Esperado em `0.1.0`; o parser é stub |
| `serve` inacessível de outra máquina | Ele escuta em loopback por padrão |
| `update` falha | `curl`, `tar`, permissão de escrita e assets da release |
| Build do desktop falha | Dependências de sistema do Tauri para a plataforma |
| UI aparece em português | `Auto` segue o idioma do sistema; escolha English nas configurações |
## Escopo
O suporte cobre o código e a documentação do Acauã. Não cobre configuração de
Zeek ou Suricata, legalidade de captura de rede ou pacotes de distribuição de
terceiros. Use somente em redes próprias ou com autorização para monitorar.
| Container não sobe | Confirme linkagem de `libduckdb.so` via `docker logs` e verifique permissões nos volumes nomeados |
| `serve` inacessível a partir de outro host | O serviço escuta em loopback (`127.0.0.1:8787`) por padrão; verifique o proxy reverso |
| `update` falha | Verifique conectividade de rede com a API de Releases do Gitea ou permissões de pull do registry |
| UI web exibe português | `Auto` segue o idioma do navegador; escolha inglês nas configurações |