mirror of
https://github.com/DaLaw2/NetGuardia.git
synced 2026-08-24 14:10:28 +09:00
* feat: Phase 2-5 — architecture, detection, security, SOAR, operations Architecture: - Hexagonal port traits (10 modules migrated from Arc<Database>) - Domain model types moved to model/ directory - Constants centralized + 7 made runtime-configurable via DB - Dead Error/Log variants cleaned up, SystemLog split Detection (Phase 5): - Detection orchestrator with dedup + enrichment + source attribution - Cross-flow correlation engine: botnet, scan, lateral movement (T9) - Temporal beaconing detector: CV-based C2 periodicity (T10) - LRU flow eviction replacing O(n) min_by_key scan (T12) Security hardening: - 7 fixes: alg:none, config secret leak, HTTPS open redirect, log traversal, HKDF salt, SOAR whitelist+cooldown, operator validation - 4 memory safety fixes: LRU dedup, frequency cleanup, drift cap, clock - Envelope encryption for secrets (AES-256-GCM + HKDF) - 17 new tests (SecretStore + SOAR conditions) SOAR (Phase 3): - Multi-condition playbooks (5 condition types, AND logic) - Playbook update API (PUT + toggle endpoints) Operations (Phase 4): - Dynamic log level, system control APIs (shutdown/restart) - HTTP config hot reload, spawn_blocking for CPU-bound work - CLI encrypt-db / decrypt-db commands - Audit log API Log level audit: - 16 variants adjusted (noisy hot-path → TRACE/DEBUG) - 5 dead variants removed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address Copilot review — 6 issues from PR #18 1. Botnet detector source_ip was set to victim dst_ip, causing SOAR to block the victim instead of the attacker 2. HTTPS redirect host header injection: validate host is private IP, localhost, or .local hostname before constructing redirect URL 3. smtp_password plaintext residue: clear settings table after writing to SecretStore to prevent pre-migration plaintext from persisting 4. install.sh: add apt-get update before install on Debian/Ubuntu 5. download_log OOM risk: add 50MB file size limit before reading 6. update_config restart trigger: check return value, report if shutdown already in progress instead of claiming success Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address Agent Team review — security, perf, correctness Security: - S1: Add RBAC permission check for /api/logs/ and /api/audit/ endpoints (previously any authenticated user could access) - S2/S3: Remove report_dir and log_dir from configurable settings to prevent arbitrary directory write via config API - A2: Pin DNS-resolved IPs in webhook reqwest client to prevent DNS rebinding TOCTOU attack (resolve() instead of re-resolving) Performance: - P7: Add 50K key cap to FrequencyTracker to prevent unbounded growth under DDoS (was unbounded, worst case 1.6GB) - P9: Increase ML alert broadcast capacity 100 → 1024 to prevent lost alerts during DDoS spikes (3 subscribers contend on 100-slot buffer) - P2: Reduce FLOW_MAX_PERIODS 10000 → 1000 (saves 144KB/flow, feature extraction only uses aggregate stats) - P1: Remove unnecessary FlowKey clone on hot path (~1.9MB/s saved) - P5: Beaconing detector: split analyze_and_alert into read-lock scan + selective write-lock update (reduces DashMap contention) Correctness: - A4: Capture correlation counts inside DashMap guard before dropping, eliminating TOCTOU in logged values (botnet, scan, lateral) - A6: Log warning when SOAR playbook action params JSON is malformed instead of silently replacing with empty object Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: add trainer submodule, update frontend submodule - Add net-guardia-trainer submodule (ParrotXray/NetGuardia-Trainer@dalaw2-dev) - Update frontend submodule with code quality fixes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
135 lines
6.5 KiB
Bash
Executable File
135 lines
6.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# install.sh — Install NetGuardia on a fresh system.
|
|
#
|
|
# Usage:
|
|
# install.sh # Download from GitHub Release
|
|
# install.sh --local /path/to/binary # Use a pre-built local binary
|
|
#
|
|
set -euo pipefail
|
|
|
|
# ── Helpers ──────────────────────────────────────────────────────────────────
|
|
info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; }
|
|
warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*"; }
|
|
fatal() { printf '\033[1;31m[FATAL]\033[0m %s\n' "$*" >&2; exit 1; }
|
|
|
|
# ── Defaults ─────────────────────────────────────────────────────────────────
|
|
LOCAL_BINARY=""
|
|
INSTALL_DIR="/opt/netguardia"
|
|
BIN_DIR="${INSTALL_DIR}/bin"
|
|
DATA_DIR="/var/lib/netguardia"
|
|
LOG_DIR="/var/log/netguardia"
|
|
SERVICE_USER="netguardia"
|
|
SERVICE_GROUP="netguardia"
|
|
GITHUB_REPO="dalaw2/NetGuardia"
|
|
|
|
# ── Parse arguments ──────────────────────────────────────────────────────────
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--local)
|
|
[[ -z "${2:-}" ]] && fatal "--local requires a path to the binary"
|
|
LOCAL_BINARY="$2"
|
|
shift 2
|
|
;;
|
|
-h|--help)
|
|
echo "Usage: $0 [--local /path/to/binary]"
|
|
exit 0
|
|
;;
|
|
*)
|
|
fatal "Unknown argument: $1"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# ── Validate local binary (if provided) ─────────────────────────────────────
|
|
if [[ -n "${LOCAL_BINARY}" ]]; then
|
|
[[ -f "${LOCAL_BINARY}" ]] || fatal "Local binary not found: ${LOCAL_BINARY}"
|
|
[[ -x "${LOCAL_BINARY}" ]] || fatal "Local binary is not executable: ${LOCAL_BINARY}"
|
|
info "Using local binary: ${LOCAL_BINARY}"
|
|
fi
|
|
|
|
# ── Must be root ─────────────────────────────────────────────────────────────
|
|
[[ "$(id -u)" -eq 0 ]] || fatal "This script must be run as root"
|
|
|
|
# ── Install runtime dependencies (SQLCipher needs OpenSSL) ──────────────────
|
|
if command -v apt-get &>/dev/null; then
|
|
info "Refreshing apt package metadata"
|
|
DEBIAN_FRONTEND=noninteractive apt-get update >/dev/null 2>&1 || warn "Could not refresh apt metadata"
|
|
info "Installing runtime dependencies (libssl)"
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y libssl3 >/dev/null 2>&1 || warn "Could not install libssl3"
|
|
elif command -v dnf &>/dev/null; then
|
|
info "Installing runtime dependencies (openssl-libs)"
|
|
dnf install -y openssl-libs >/dev/null 2>&1 || warn "Could not install openssl-libs"
|
|
fi
|
|
|
|
# ── Create system user ───────────────────────────────────────────────────────
|
|
if ! id "${SERVICE_USER}" &>/dev/null; then
|
|
info "Creating system user: ${SERVICE_USER}"
|
|
useradd --system --no-create-home --shell /usr/sbin/nologin "${SERVICE_USER}"
|
|
fi
|
|
|
|
# ── Create directories ───────────────────────────────────────────────────────
|
|
info "Creating directories"
|
|
mkdir -p "${BIN_DIR}" "${DATA_DIR}" "${LOG_DIR}"
|
|
chown "${SERVICE_USER}:${SERVICE_GROUP}" "${DATA_DIR}" "${LOG_DIR}"
|
|
|
|
# ── Obtain the binary ────────────────────────────────────────────────────────
|
|
if [[ -n "${LOCAL_BINARY}" ]]; then
|
|
# --local mode: skip download and checksum entirely
|
|
info "Installing local binary to ${BIN_DIR}/net-guardia"
|
|
install -m 0755 "${LOCAL_BINARY}" "${BIN_DIR}/net-guardia"
|
|
else
|
|
# Download from GitHub Release
|
|
info "Fetching latest release from GitHub (${GITHUB_REPO})"
|
|
LATEST_TAG=$(curl -fsSL "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" \
|
|
| grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
|
|
[[ -n "${LATEST_TAG}" ]] || fatal "Could not determine latest release tag"
|
|
info "Latest release: ${LATEST_TAG}"
|
|
|
|
DOWNLOAD_URL="https://github.com/${GITHUB_REPO}/releases/download/${LATEST_TAG}/net-guardia-linux-amd64"
|
|
CHECKSUMS_URL="https://github.com/${GITHUB_REPO}/releases/download/${LATEST_TAG}/SHA256SUMS"
|
|
|
|
TMPDIR=$(mktemp -d)
|
|
trap 'rm -rf "${TMPDIR}"' EXIT
|
|
|
|
info "Downloading binary"
|
|
curl -fSL -o "${TMPDIR}/net-guardia" "${DOWNLOAD_URL}"
|
|
|
|
info "Downloading SHA256SUMS"
|
|
if ! curl -fSL -o "${TMPDIR}/SHA256SUMS" "${CHECKSUMS_URL}"; then
|
|
fatal "SHA256SUMS file not found in release — aborting"
|
|
fi
|
|
|
|
info "Verifying checksum"
|
|
(cd "${TMPDIR}" && sha256sum -c SHA256SUMS)
|
|
|
|
install -m 0755 "${TMPDIR}/net-guardia" "${BIN_DIR}/net-guardia"
|
|
fi
|
|
|
|
# ── Install systemd unit ─────────────────────────────────────────────────────
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
DEPLOY_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
|
|
if [[ -f "${DEPLOY_DIR}/netguardia.service" ]]; then
|
|
info "Installing systemd unit"
|
|
install -m 0644 "${DEPLOY_DIR}/netguardia.service" /etc/systemd/system/netguardia.service
|
|
systemctl daemon-reload
|
|
systemctl enable netguardia.service
|
|
else
|
|
warn "netguardia.service not found at ${DEPLOY_DIR}/netguardia.service — skipping"
|
|
fi
|
|
|
|
# ── Install logrotate config ─────────────────────────────────────────────────
|
|
if [[ -f "${DEPLOY_DIR}/logrotate.conf" ]]; then
|
|
info "Installing logrotate config"
|
|
install -m 0644 "${DEPLOY_DIR}/logrotate.conf" /etc/logrotate.d/netguardia
|
|
else
|
|
warn "logrotate.conf not found — skipping"
|
|
fi
|
|
|
|
# ── Done ─────────────────────────────────────────────────────────────────────
|
|
info "NetGuardia installed successfully"
|
|
info " Binary: ${BIN_DIR}/net-guardia"
|
|
info " Data: ${DATA_DIR}"
|
|
info " Logs: ${LOG_DIR}"
|
|
info " Service: systemctl start netguardia"
|