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
No files matched your search
@@ -1,24 +0,0 @@
|
||||
[package]
|
||||
name = "acaua-gui"
|
||||
description = "Acauã: graphical network threat hunting interface"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
authors = ["Acauã contributors"]
|
||||
repository = "https://git.lucasrguerra.dev.br/ciberfauna/acaua"
|
||||
rust-version = "1.80"
|
||||
|
||||
[workspace]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2", features = [] }
|
||||
|
||||
[dependencies]
|
||||
acaua-core = { path = "../../../crates/acaua-core" }
|
||||
serde_json = "1"
|
||||
tauri = { version = "2", features = [] }
|
||||
|
||||
[profile.release]
|
||||
lto = "thin"
|
||||
codegen-units = 1
|
||||
strip = true
|
||||
@@ -1,5 +0,0 @@
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=../../../logo.png");
|
||||
let _ = std::fs::copy("../../../logo.png", "../ui/logo.png");
|
||||
tauri_build::build();
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Main window permissions",
|
||||
"windows": ["main"],
|
||||
"permissions": ["core:default", "core:window:allow-destroy", "core:window:allow-close"]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 452 KiB |
@@ -1,62 +0,0 @@
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
use acaua_core::{doctor, update, zeek};
|
||||
|
||||
#[tauri::command]
|
||||
fn app_info() -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"version": env!("CARGO_PKG_VERSION"),
|
||||
"mode": "desktop",
|
||||
"status": "skeleton"
|
||||
})
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn doctor_report() -> Result<serde_json::Value, String> {
|
||||
serde_json::to_value(doctor::run()).map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn analyze_dataset(path: String) -> Result<serde_json::Value, String> {
|
||||
let report = zeek::analyze_dir(&path).map_err(|error| error.to_string())?;
|
||||
serde_json::to_value(report).map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn list_alerts() -> serde_json::Value {
|
||||
serde_json::json!([])
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn update_check() -> Result<serde_json::Value, String> {
|
||||
let status = update::check(env!("CARGO_PKG_VERSION")).map_err(|error| error.to_string())?;
|
||||
serde_json::to_value(status).map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn update_apply(app: tauri::AppHandle) -> Result<String, String> {
|
||||
use tauri::Emitter;
|
||||
let exe = std::env::var_os("APPIMAGE")
|
||||
.map(std::path::PathBuf::from)
|
||||
.filter(|p| p.is_file())
|
||||
.or_else(|| std::env::current_exe().ok())
|
||||
.unwrap_or_else(|| std::path::PathBuf::from("acaua-gui"));
|
||||
update::apply_desktop_with_progress(&exe, move |phase| {
|
||||
let _ = app.emit("update-progress", serde_json::json!({ "phase": phase }));
|
||||
})
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
app_info,
|
||||
doctor_report,
|
||||
analyze_dataset,
|
||||
list_alerts,
|
||||
update_check,
|
||||
update_apply
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("failed to run Acauã");
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "Acauã",
|
||||
"version": "0.1.0",
|
||||
"identifier": "dev.acaua.app",
|
||||
"build": {
|
||||
"frontendDist": "../ui"
|
||||
},
|
||||
"app": {
|
||||
"withGlobalTauri": true,
|
||||
"windows": [
|
||||
{
|
||||
"title": "Acauã",
|
||||
"width": 1280,
|
||||
"height": 820,
|
||||
"minWidth": 460,
|
||||
"minHeight": 600,
|
||||
"resizable": true
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "default-src 'self'; img-src 'self' data:; connect-src 'self' ipc: http://ipc.localhost; style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'none'"
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"category": "Utility",
|
||||
"shortDescription": "Caça a ameaças em rede",
|
||||
"longDescription": "Acauã é uma ferramenta de caça a ameaças em rede com evidência determinística, processamento local e sem IA opaca.",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import { setLang, tr } from './i18n.js';
|
||||
|
||||
const $ = (selector) => document.querySelector(selector);
|
||||
const tauriInvoke = window.__TAURI__?.core?.invoke;
|
||||
|
||||
const connection = $('#connection');
|
||||
const connectionText = $('#connectionText');
|
||||
@@ -30,7 +29,6 @@ async function fetchJson(path, options = {}) {
|
||||
}
|
||||
|
||||
async function call(command, args = {}) {
|
||||
if (tauriInvoke) return tauriInvoke(command, args);
|
||||
switch (command) {
|
||||
case 'app_info':
|
||||
return fetchJson('/api/status');
|
||||
|
||||