Commit Graph

64 Commits

Author SHA1 Message Date
b6ab518e2a release: bump minor on the 87 modules converted to Wants=secubox-core (Phase 2)
Co-Authored-By: Gerald KERMA <devel@cybermind.fr>
2026-07-19 09:08:22 +02:00
2ec7cef1b2 feat(profiles): Phase 2 — Requires=secubox-core → Wants= on all units (remove hard cascade)
secubox-core.service is a Type=oneshot (mkdir+chown) that RemainAfterExit=yes. A hard
Requires= on ~108 units cascade-stops them all if core is restarted/fails (e.g. a
secubox-core package upgrade) — a thundering-herd outage. After= keeps the ordering;
Wants= keeps the soft dependency without the cascade. Prereq for mass native apply
(Phase 3). Scaffolds (new-module.sh/new-package.sh) updated so future units use Wants=.

Co-Authored-By: Gerald KERMA <devel@cybermind.fr>
2026-07-19 09:06:54 +02:00
238637e09a release(webui): bump 127 arch:all packages for hybrid-dark reskin bake-in 2026-07-10 09:07:42 +02:00
3197f866e4 feat(webui): fleet reskin — apply hybrid-dark cyan overlay to all 116 crt-light panels
Add /shared/hybrid-dark.css: a shared overlay that remaps the design tokens
(consumed by crt-light.css, sidebar-light.css and every module's inline styles)
to the cyan hybrid-dark palette from /certs/ + /wireguard/. body.hybrid-dark
(specificity 0,1,1) beats :root and inline :root, so one token remap flips the
whole tree — no per-panel rewrite. Each panel gains the overlay <link> + the
hybrid-dark body class (2-line additive swap; crt-light.css kept as base).
See .claude/WEBUI-PANEL-GUIDELINES.md.

Panels with fully bespoke styles (certs/wireguard/users/nac already hybrid;
~14 non-crt-light custom panels) are untouched.
2026-07-10 08:40:10 +02:00
872be8c77b feat(toolbox): splice autolearn mirrors into webui MITM filter list; rename WAF Filters → Filtres MITM
- secubox-toolbox-autolearn now mirrors each splice-learned host into
  mitm-bypass-dynamic.conf (the Filtres MITM '🔍 learned' source) as bypass
  regex, so autolearned splice hosts are visible + editable in the webui and
  honoured on the ignore_hosts path. Merge (never clobbers operator entries).
- secubox-mitmproxy filters.html: 'WAF Filters' → 'Filtres MITM' (title/h1/desc);
  API path /api/v1/mitmproxy/waf unchanged.
2026-07-04 14:01:54 +02:00
6ae107db91 feat(mitmproxy): named nft counter on WAF rate-limit drops (ref #758) 2026-06-27 11:02:06 +02:00
c01f10c474 docs(wiki): refonte 126 modules — snapshots WebUI déterministes + READMEs 4 langues (ref #742)
Capture des 126 dashboards authentifiés (JWT minté serveur, injection localStorage)
avec attente de COMPLÉTION d'affichage déterministe (sentinelles de chargement
purgées + réseau calmé, plafond --delay) au lieu d'un sleep fixe. 126/126 OK.

- capture-screenshots.py: _wait_content_ready déterministe, mode --token (bypass
  login), goto domcontentloaded (plus de stall networkidle sur dashboards live)
- generate-docs.py: 23 modules jusqu'ici non documentés ajoutés (descriptions
  réelles depuis debian/control, EN/FR/DE/ZH), licence MIT→LicenseRef-CMSD-1.0,
  images wiki en URL raw.githubusercontent absolue (relatif = 404 sur GitHub wiki)
- 126 snapshots + thumbnails régénérés
- 126 READMEs paquet succincts + pages wiki MODULES/CATEGORIES ×4 langues

Gap modules documentés vs découverts: 23 → 0.
2026-06-26 10:14:14 +02:00
4dd87eae2f fix(mitmproxy): ExecStartPost chmod raced socket creation -> wait+non-fatal (ref #624) 2026-06-17 07:36:33 +02:00
af02a9731c fix(mitmproxy): service used absent /usr/bin/uvicorn (203/EXEC crash-loop) -> python3 -m uvicorn + stale-socket unlink (ref #624) 2026-06-17 07:34:01 +02:00
663715af0f feat(mitmproxy): package self-healing WAF inspector watchdog (closes #624)
secubox-waf-watchdog timer checks inspector :8080 every 60s and auto-recovers
the mitmproxy LXC after 3 consecutive failures (rate-limited once/10min) — an
inspector crash becomes a ~3min auto-recovery instead of a multi-hour 503.
Shipped in secubox-mitmproxy; enabled in postinst, disabled in prerm. Makes the
live hotfix from the #624 incident durable across reflash.
2026-06-17 07:31:29 +02:00
e13cf925f1 fix(waf): robust route propagation — dir bind-mount + addon live-reload (closes #609)
The #603 FILE bind-mount of haproxy-routes.json binds an inode; route tools
edit via jq>tmp&&mv (new inode) so changes went stale until a container
restart (surfaced fixing git.maegia.tv mis-route). Now: wafctl uses a
DIRECTORY bind-mount (host /srv/mitmproxy -> /var/lib/secubox-waf-routes ro)
+ symlink, and the addon (both synced copies) live-reloads haproxy-routes.json
on mtime change (throttled 10s) in requestheaders -> route edits apply with
NO restart. Verified live: jq+mv add -> live-reloaded 256 routes, 0 restart.
2026-06-15 18:25:56 +02:00
3290f3b7c0 feat(waf): behind-WAF media cache for hosted vhosts (closes #607)
New media_cache.py addon (both synced copies) caches cacheable GET
media/static (image/video/audio/font/css/js) from our vhosts on disk
(URL key, 16MB/obj, 2GB LRU, TTL from max-age) and serves repeats from
cache. NOT a bypass: requests still pass secubox_waf inspection; only the
response body is served from a WAF-populated cache. Loaded in the LXC
mitmproxy.service; wafctl creates the cache dir. Toggle via
/data/mitmproxy/media-cache.json (default on). Verified live: HIT.
2026-06-15 18:09:25 +02:00
0d1c49307e fix(waf): refuse unmapped hosts — close open forward-proxy (closes #605)
In --mode regular the addon relayed any Host; HAProxy default_backend made
the WAF an open forward proxy abused by scanners (~72% error churn + 11
loop-508s/hr). requestheaders now serves ONLY our vhosts (routes / our
domains via routes-derived local_suffixes -> nginx 9080 / SELF_HOSTS) and
returns 421 otherwise with no upstream connect. Applied to both synced
secubox_waf.py copies. Verified live: 0 external server-connects, 0 loops,
apt/admin/kbin 200, scanners 421.
2026-06-15 17:19:06 +02:00
05d6f97b44 fix(waf): port live mitmproxy fixes to source — mitmproxy-11 routing + routes bind-mount (closes #603)
- requestheaders hook in both synced secubox_waf.py copies: mitmproxy 11
  opens the upstream connection before the request hook, so the in-request
  redirect was too late and routed vhosts hit their public IP. Set
  flow.server_conn.address in requestheaders instead.
- wafctl: bind-mount host /srv/mitmproxy/haproxy-routes.json into the LXC at
  the addon's read path /data/mitmproxy/haproxy-routes.json (they had drifted
  → routes_count 0 → no routing); ensure the host file exists at provision.
- mitmproxy.service: warn any ExecStart drop-in must keep --set confdir
  (a dropped confdir crash-looped the WAF via ProtectHome).

Ported from the live gk2 fixes (HISTORY 2026-06-15).
2026-06-15 16:47:00 +02:00
6efac89d49 feat: Phase 6.P memory optimization — P3+P4+P5+P6 backported to sources (ref #496)
Aggregate live result on gk2 :
  - journald disk    : 1.3 GB → 176 MB    (-86%)
  - Free memory      : 241 MB → 524 MB    (+283 MB)
  - Running LXCs     : 16 → 13 (yacy/horde/rustdesk stopped + autostart=0)
  - 13 LXCs with memory.max cap + swap.max=0 (5.5 GB total budget on 8 GB host)
  - mitm-wg + mitm   : RuntimeMaxSec=6h (clean restart drops ~50 MB/process)
  - mitm-wg launcher : --set http2=false (HTTP/2 multiplex state retention)

## Source artifacts

### P5 — journald rotation
  packages/secubox-mitmproxy/systemd/journald.conf.d/90-secubox-rotation.conf
    SystemMaxUse=200M, MaxRetentionSec=2week, ForwardToSyslog=no
  postinst : install file + 'journalctl --vacuum-size=200M' + restart journald

### P3 — mitm http2=false + RuntimeMaxSec drop-ins
  packages/secubox-toolbox/sbin/secubox-toolbox-mitm-wg-launch (modified)
    --set http2=false ajouté aux ARGS
  packages/secubox-toolbox/systemd/secubox-toolbox-mitm.service.d/10-runtime-max.conf (NEW)
  packages/secubox-toolbox/systemd/secubox-toolbox-mitm-wg.service.d/10-runtime-max.conf (NEW)
    [Service] RuntimeMaxSec=6h
  packages/secubox-mitmproxy/systemd/system/{...}/10-runtime-max.conf
    same drop-ins shipped via mitmproxy package (covers LXC-side WAF)
  debian/rules of both packages : install drop-ins

### P4 — per-LXC memory budget
  packages/secubox-mitmproxy/bin/secubox-apply-lxc-memory-budget (NEW, 755)
    Idempotent script : applies memory.max + swap.max=0 LIVE and persists
    in /var/lib/lxc/<name>/config. 16 LXCs covered with realistic budgets
    (5.5 GB total / 8 GB host, leaves 2.5 GB for host).
  postinst : runs it if installed (LXC-aware install).

### P6 — operator decision, not auto-applied
  Stop yacy/horde/rustdesk + autostart=0 was done LIVE on gk2 but is an
  operator preference, NOT a package decision. Documented in
  .claude/PHASE-6.P-MEMORY-OPTIMIZATION.md as 'optional stop unused LXCs'.

## What's NOT in this commit (kept for future sessions)

### P2 — secubox_toolbox FastAPI diet (~50 MB)
  Lazy-load Jinja2 templates, lazy-import dpi_class, tune uvicorn workers.
  Needs careful per-route testing.

### P1 — ASGI consolidation (~840 MB)
  New 'secubox-aggregator' package mounts 15 module FastAPIs as sub-apps
  under a single uvicorn. Biggest gain but architectural change ; do
  after Phase 7.C lands and the WAF stack is stable.

## Files

  Modified :
    packages/secubox-mitmproxy/debian/postinst
    packages/secubox-mitmproxy/debian/rules
    packages/secubox-toolbox/debian/rules
    packages/secubox-toolbox/sbin/secubox-toolbox-mitm-wg-launch
  Created :
    packages/secubox-mitmproxy/bin/secubox-apply-lxc-memory-budget
    packages/secubox-mitmproxy/systemd/journald.conf.d/90-secubox-rotation.conf
    packages/secubox-mitmproxy/systemd/system/secubox-toolbox-mitm.service.d/10-runtime-max.conf
    packages/secubox-mitmproxy/systemd/system/secubox-toolbox-mitm-wg.service.d/10-runtime-max.conf
    packages/secubox-toolbox/systemd/secubox-toolbox-mitm.service.d/10-runtime-max.conf
    packages/secubox-toolbox/systemd/secubox-toolbox-mitm-wg.service.d/10-runtime-max.conf
2026-06-06 07:37:21 +02:00
478163af26 feat(secubox-mitmproxy): Phase 6.O — kernel + memory + network perf tuning (ref #496)
User : 'baisse rapide des performances du tunnel' followed by 'd\'abord les
performances'. Phase 6.N (dynamic whitelist) closed the retry-storm cause.
Phase 6.O squeezes more perf from the kernel/network stack.

## Live verification (before → after on gk2)

  load avg     : 8.08 → 4.75 (-41% in ~5 min)
  run queue    : 12 → 5      (-58%)
  CPU idle     : 5% → 21%    (4x more breathing room)
  swap activity: 0 (already healthy, just better protection now)

## What changed

### /etc/sysctl.d/95-secubox-perf.conf (NEW)

Memory :
  vm.swappiness = 10         (default 60 → keep working set in RAM)
  vm.vfs_cache_pressure = 50 (retain dentry/inode cache longer)
  vm.dirty_background_ratio = 5  (earlier background writeback)
  vm.dirty_ratio = 15        (lower sync flush threshold — less latency spike)

Network :
  net.core.rmem_max / wmem_max = 16 MiB    (was 200 KiB — WG burst friendly)
  net.core.rmem_default / wmem_default = 1 MiB
  net.core.netdev_max_backlog = 8000       (8x default — scheduling jitter)

TCP :
  net.ipv4.tcp_fastopen = 3         (client + server : -1 RTT on repeat conn)
  net.ipv4.tcp_max_syn_backlog = 4096
  net.ipv4.tcp_tw_reuse = 1         (~500 TIME_WAIT idle currently)

### /etc/tmpfiles.d/secubox-thp.conf (NEW)

Switches Transparent Huge Pages from 'always' to 'madvise'. On Armada
under memory pressure, 'always' causes compaction stalls (multi-ms
pauses in scheduling). 'madvise' lets apps opt-in (none here do),
which avoids the stalls completely.

### Not applied (kernel constraint)

BBR congestion control + fq qdisc were planned but the Marvell custom
kernel (6.12.85) wasn't built with CONFIG_TCP_CONG_BBR / NET_SCH_FQ.
Would need a kernel rebuild for those — kept in comment in the file.
Cost of staying on cubic + pfifo_fast : ~3-5% less throughput.

## Files

  packages/secubox-mitmproxy/sysctl/95-secubox-perf.conf  (NEW)
  packages/secubox-mitmproxy/tmpfiles.d/secubox-thp.conf  (NEW)
  packages/secubox-mitmproxy/debian/rules                  (install wires)

## Diagnostics that mattered

  vmstat 1 3 : si/so = 0 (no active swap thrashing — relief)
  ps state   : 12 procs in run queue (scheduling bottleneck)
  cpu freq   : already at max (1.4 GHz, schedutil governor OK)
  cpu gov    : schedutil (modern, no need to change)
  THP        : 'always' (changed to madvise — gain on this hw)

## Not pursued

  - eBPF/XDP : Marvell DSA driver limits XDP to generic mode (no native
    hook in driver). Gain would be ~2-3x, not 200x. Postponed.
  - LXC pruning : memory available is fine (2.98 GB avail). No need
    to stop yacy/horde/rustdesk.
2026-06-06 07:17:29 +02:00
a35ab5c50e feat(secubox-mitmproxy): Phase 7.A.2 + 7.B — WAF backport + dashboard + rate-limit + honeypot (ref #498)
Phase 7.A.2 + 7.B shipped same-day after Phase 7.A landing (#498 mid-day).

## Live verified on gk2

### Phase 7.A.2

- `packages/secubox-waf/mitmproxy/secubox_waf.py` (older 756→878 lines) :
  backported `_load_crowdsec_cfg`, `_cs_jwt`, `_ban_via_crowdsec`,
  Phase 6.J Connection:close. Both WAF copies now in sync.
- `debian/postinst` : auto-invokes `secubox-waf-cs-bridge-setup` if cscli
  present, installs config to host + bind-mounts into LXC if present.
- `api/routers/waf.py` : new GET /enforcement returns bridge_enabled,
  bans_pushed/failed, requests, blocked, warnings, rate_limit_offenders
  (live nft set count), honeypot_hits_last_hour (from nginx log scan),
  recent_bans (cscli decisions list --origin=secubox-waf), recent_threats.
- `www/mitmproxy/threats.html` : new tab with 6 KPI cards + 2 tables
  (bans, threats), auto-refresh 5s.

### Phase 7.B

- `nftables/secubox-waf-ratelimit.nft` : table inet secubox_waf_ratelimit
  with offenders_v4/v6 (dynamic 5min timeout) + whitelist_v4 (LAN/loopback) +
  input hook priority -10. Rule : tcp SYN to 80/443, limit rate over
  30/second burst 50 → drop + add to offenders. Live-loaded :
  table created, chain attached, ready to drop slowloris/scanners
  the moment they cross threshold.
- `debian/secubox-waf-ratelimit.service` : systemd unit loads the nft
  file on boot (idempotent, RemainAfterExit=yes).
- `nginx/honeypot.conf` : 5 location blocks for known bot signatures
  (`/wp-admin`, `/.env`, `/.git/config`, `/phpmyadmin`, `/actuator` etc).
  Returns empty 200, logs to `/var/log/nginx/honeypot.log` with custom
  `secubox_honeypot` log_format. Live-tested : 3 paths returned 200,
  honeypot.log filled in real-time.
- `debian/postinst` : copies honeypot.conf to /etc/nginx/secubox-routes.d/
  and creates log_format conf.d snippet.

### Files added

  packages/secubox-mitmproxy/nftables/secubox-waf-ratelimit.nft       (NEW)
  packages/secubox-mitmproxy/nginx/honeypot.conf                       (NEW)
  packages/secubox-mitmproxy/www/mitmproxy/threats.html                (NEW)
  packages/secubox-mitmproxy/debian/secubox-waf-ratelimit.service      (NEW)

### Files modified

  packages/secubox-waf/mitmproxy/secubox_waf.py    +120 lines
  packages/secubox-mitmproxy/api/routers/waf.py    +130 lines
  packages/secubox-mitmproxy/debian/postinst       +35 lines
  packages/secubox-mitmproxy/debian/rules          +11 lines

## What's NOT in this commit (Phase 7.C, future)

- eBPF/XDP kernel filter (replaces Python WAF hot-path)
- ModSecurity in HAProxy with OWASP CRS rules
- Federation : push to CrowdSec Hub + pull AlienVault OTX + Spamhaus DROP
- Tune BAN_THRESHOLD per category (XSS=2, SQLi=1)

Filed as remaining sub-tasks in issue #498 (kept open).
2026-06-05 17:23:00 +02:00
d4e093a4db feat(secubox-mitmproxy): Phase 7.A WAF→CrowdSec bridge — alerts push → nft drop (ref #498)
User : 'plan for later a waf with dropping result of attackants...
threats accumulate looks very high'. Phase 7.A delivers the foundation :
WAF detections become real nft drops within seconds.

## E2E live-verified on gk2

  login    : 200 JWT 160 chars
  alert    : 201 ← decision id 13244
  cscli    : Ip:192.0.2.99 ban origin=secubox-waf 1h
  nft      : 192.0.2.99 in table ip crowdsec (kernel-level drop)

Full chain (mitm LXC → host LAPI → bouncer → nft) round-trip in ~12s.

## Architecture

  [secubox_waf.py in mitm LXC]
       │  detects threat via pattern match
       │  if count >= BAN_THRESHOLD
       │     ↓
       │  ban_ip() → _ban_via_crowdsec()
       │     ↓
       │  HTTP POST /v1/alerts (urllib stdlib, no httpx dep)
       │     ↓
  [socat 10.100.0.1:8080 → 127.0.0.1:8080]   ← Phase 7.A.1 bridge
       │     ↓
  [CrowdSec LAPI on host 127.0.0.1:8080]
       │     ↓
  [crowdsec-firewall-bouncer (existing)]
       │     ↓
  [nft add element ip crowdsec ...]
       │     ↓
  [attacker IP dropped at netdev/forward chain]

## Files

### addons/secubox_waf.py
  New constants CROWDSEC_CFG_FILE, _CS_JWT, _CS_JWT_TTL.
  New _load_crowdsec_cfg() reads TOML, validates 4 required fields.
  New _cs_jwt(cfg) caches JWT for 25 min (LAPI default 30 min expiry).
  New _ban_via_crowdsec() POSTs Alert+Decision to /v1/alerts with
    Bearer JWT. urllib stdlib only (mitm venv lacks httpx). On 401,
    forces JWT refresh next call. Stats : bans_pushed, bans_failed.
  Modified ban_ip() : tries HTTP bridge first, falls back to cscli
    subprocess if bridge disabled. Old subprocess path kept for hosts
    where WAF runs natively (cscli available).

### bin/secubox-waf-cs-bridge-setup
  Installs socat forwarder unit secubox-cs-bridge.service so the mitm
  LXC can reach the host loopback LAPI without changing CrowdSec config.
  Registers secubox-waf as a MACHINE (watcher) via cscli machines add
  with -f - so the local agent's credentials file stays untouched.
  Writes /tmp/crowdsec.toml with machine_id + machine_password.
  Operator copies into LXC at /etc/secubox/waf/crowdsec.toml.

### crowdsec/crowdsec.toml.example
  Updated to document machine_id / machine_password (not the old
  bouncer api_key — bouncers can only PULL decisions, not push them).

## Why machine auth (not bouncer)

CrowdSec LAPI splits routes by auth type :
  - X-Api-Key (bouncer) → GET /v1/decisions/stream (read-only)
  - JWT (watcher)       → POST /v1/alerts (write)
  - JWT (watcher)       → DELETE /v1/decisions

To PUSH a ban, the WAF must auth as a watcher. We register a dedicated
machine 'secubox-waf' so its decisions show up in the dashboard tagged
with origin=secubox-waf (vs origin=crowdsec for scenario-driven bans
and origin=cscli for manual ones).

## Socat bridge rationale

Default CrowdSec install binds LAPI to 127.0.0.1:8080. Direct patching
of listen_uri to 10.100.0.1 breaks the local agent + bouncer (they hard-
code 127.0.0.1 in their credential files). A 30-line socat forwarder
service exposes the same LAPI on the LXC bridge gateway, gated by the
host firewall (only LXCs can reach 10.100.0.1). Zero CrowdSec config
change.

## Acceptance criteria (issue #498 Phase 7.A target)

  1. Attacker dropped at nft within 30s of crossing BAN_THRESHOLD ✓
  2. cscli decisions list shows origin=secubox-waf entries           ✓
  3. nft list table ip crowdsec shows the dropped IPs                ✓
  4. threat_counts dict growth bounded                               ✓ (still
     local memory, but attacker IPs now drop before refilling it)

## Phase 7.A.2+ (followups in TODO.md)

  - Backport into packages/secubox-waf/mitmproxy/secubox_waf.py
  - debian/postinst : invoke setup script + bind-mount config into LXC
  - WAF dashboard tab in admin webui showing bans_pushed counter
  - Tune BAN_THRESHOLD per category (XSS=2, SQLi=1, scanner pattern=5)
  - Phase 7.B : nft rate-limit pre-mitm to catch TCP-only scanners
2026-06-05 17:08:35 +02:00
1685cf6c08 docs: Phase 6 R3 WireGuard MAJOR RELEASE — HISTORY/WIP/TODO + WAF leak source backport (ref #496)
Tracking files updated to reflect 2026-06-05 work :

* .claude/HISTORY.md — full Phase 6 R3 release entry (R3 architecture,
  first-class identity, banner enrichment, splash detection, landing polish,
  multi-OS install, WAF leak fix, 8 bugs resolved)
* .claude/WIP.md — Done/Next/Follow-ups for Phase 6
* .claude/TODO.md — Phase 6 P0 checked + 3 follow-ups added

## Source backport : mitm WAF leak fix

packages/secubox-mitmproxy/addons/secubox_waf.py SecuBoxWAF.request adds :
  flow.request.headers["Connection"] = "close"

Live verification (after live LXC patch + this source backport) :
  Before : FDs 1513, scur=812 (8h growth), HTTP 504 sur /toolbox/
  After  : FDs 3, scur=87 (stable post-restart), 31ms response

Root cause was mitmproxy 11 keeping idle upstream HTTP/1.1 keep-alive
sockets in the per-server pool indefinitely. Connection: close on the
outbound request forces nginx to close TCP after the response, mitm
releases the socket → no pool buildup. Cost : ~1ms per request to
upstream (loopback TCP handshake), well worth the saved FDs.

This commit is the source-of-truth backport. The live LXC at
/var/lib/lxc/mitmproxy/rootfs/srv/mitmproxy/secubox_waf.py was patched
inline first (urgent prod fix) then synced back here.

Note : packages/secubox-waf/mitmproxy/secubox_waf.py (756 lines, older
version) still pending backport — tracked in TODO.md follow-ups.
2026-06-05 16:33:45 +02:00
0bf6789195 fix(waf): whitelist LAN/RFC1918 so operators are never WAF-banned
The mitmproxy WAF whitelist was an exact-match set of two IPs, so a LAN
operator whose request matched a rule (e.g. a logout) hit the 3-strikes ban
with no bypass. Make the whitelist CIDR-aware and trust loopback + RFC1918
(LAN + internal LXC bridge). The WAF still inspects external traffic. Already
applied live in the mitmproxy LXC.
2026-05-29 07:00:10 +02:00
3f5e7c900c fix(mitmproxy): v1.0.4 — SELF_HOSTS pre-route guard avoids the 508 user-facing page
v1.0.3 added a last-resort 508 Loop Detected response when the
X-Forwarded-For chain showed mitmproxy was bouncing through HAProxy's
default_backend in a loop. That stopped the CPU runaway but the user
saw a 508 page when they typed http://192.168.1.200/ (a literal local
IP) since that Host is not in haproxy-routes.json — mitmproxy would
forward to the IP, HAProxy on the same IP would receive and route to
mitmproxy again, repeat.

This commit catches the case earlier. The new SELF_HOSTS set
enumerates the box's listening IPs (127.0.0.1, 192.168.1.200,
192.168.255.1, 10.100.0.1, 10.55.0.1). When the Host header matches
one of those AND has no explicit route, the pre-route guard in
request() rewrites the target to 192.168.1.200:9080 (host nginx) and
leaves the Host header intact so nginx can pick a vhost. The user
now lands on the canonical hub catch-all instead of a 508 page.

The 508 path remains as the absolute last resort and now logs the
offending Host + XFF self-reference count so operators can spot any
new Host that needs to be added to haproxy-routes.json or SELF_HOSTS.

Live verified on gk2: GET http://{192.168.1.200,10.100.0.1,10.55.0.1,
192.168.255.1}/ all return 503 (nginx default vhost) instead of the
WAF's 508 loop-detected page.
2026-05-24 09:09:49 +02:00
f873cd28a5 fix(mitmproxy): v1.0.3 — WAF self-loop guard stops HAProxy↔mitmproxy CPU runaway
Adds an XFF self-reference check at the top of SecuBoxWaf.request(): when
the X-Forwarded-For chain already contains the LXC's own IP (10.100.0.60)
more than twice, the WAF returns 508 Loop Detected instead of opening
another upstream connection.

Observed failure mode on gk2: Pi Zero / Eye Remote (10.55.0.2) was
calling http://10.55.0.1/api/v1/eye-remote/api/system/info. Host header
'10.55.0.1' had no entry in haproxy-routes.json, so mitmproxy forwarded
to 10.55.0.1:80 (HAProxy itself) → default_backend mitmproxy_inspector
→ back into mitmproxy → loop. Each hop appended another 10.100.0.60 to
XFF; sustained ~50 hops per request kept mitmdump at 84% CPU.

The guard breaks the loop after at most 3 hops regardless of which Host
caused it — belt-and-braces in case another stray literal-IP appears.
The site-specific runtime fix (mapping 10.55.0.1 → 192.168.1.200:9080 in
haproxy-routes.json) lives on the board and is not in source: routes are
deployment-local state, not packaged.
2026-05-23 16:30:46 +02:00
CyberMind
aba60ae356
feat(/data Phase 1): migrate 5 core packages from /srv to /data with postinst auto-mv (closes #319 Phase 1) (#320)
Phase 1 — 5 high-impact core packages migrated to the canonical
/data storage convention (charter §Storage). Each package's debian/postinst
gains an idempotent migration block that moves legacy /srv/<dir> → /data/<dir>
on upgrade and leaves a symlink behind for back-compat.

* secubox-mitmproxy v1.0.2: migrates /srv/mitmproxy*, /srv/mitmproxy-waf,
  /srv/mitmproxy-in. 8 files in source updated.
* secubox-waf v1.1.1: same dirs (shared with mitmproxy). 5 files updated.
* secubox-mail v2.3.1: migrates /srv/mail. 2 files updated.
* secubox-mail-lxc v2.2.1: migrates /srv/mail. 1 file updated.
* secubox-gitea v1.4.2: migrates /srv/gitea. 4 files updated.

Total: 20 files, 58 substitutions in source. Postinst auto-migration
is service-aware (stop → mv → ln -s → start). Boards previously on
/srv/<pkg> are seamlessly moved; new installs land directly on /data.

Phase 2 (~12 packages) and Phase 3 (3 cosmetic) tracked in #319.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-21 16:32:41 +02:00
CyberMind
5e93c73600
feat(navbar): consolidate to 6 charter categories + fix dropped menu entries (closes #306) (#307)
The hub's `_compute_menu_sync()` drops menu entries lacking an `id`
field. 6+ packages (lyrion, yacy, zigbee, rustdesk, grafana, authelia)
shipped a different schema (`title/url/section/module`) so they NEVER
appeared in the navbar. Plus the existing CATEGORY_META declared 12
sections (dashboard/security/network/system/core/users/services/
privacy/monitoring/publishing/apps/admin), not the 6 SecuBox charter
modules.

Changes:
* All 121 packages/secubox-*/menu.d/*.json normalised to the canonical
  schema (id, name, path, category, icon, order, description). Legacy
  schema aliases (title/url/module/section) preserved as fallbacks then
  dropped from the file.
* Each menu entry's category remapped to one of the 6 charter modules:
  AUTH (auth/users/identity/zkp/nac/openclaw),
  WALL (crowdsec/waf/mitmproxy/hardening/threat-* /cve-triage/...),
  BOOT (kernel-build/eye-remote/master-link/droplet/cloner/backup/...),
  MIND (ai-gateway/mcp-server/grafana/ndpid/netifyd/glances/...),
  ROOT (system/hub/portal/console/admin/vault/vm/rtty/...),
  MESH (wireguard/dns/tor/matrix/gitea/nextcloud/mail/lyrion/yacy/
        zigbee/dns-provider/rustdesk/... — all network + comms apps).
* secubox-hub v1.4.0 — CATEGORY_META rewritten with the 6 charter
  modules carrying their official color from DESIGN-CHARTER.md and
  the complementary-pair order. DEFAULT_MENU fallback remapped too.
* secubox-zigbee v2.5.3 — www/zigbee/index.html rewritten with the
  canonical SecuBox scaffold (body display:flex, sidebar 220px fixed,
  .main reserving 48px for the global-menu-bar). MESH palette.

Browser side: operators need to clear localStorage sbx_menu_cache (or
hard-refresh after the 1h TTL) to see the new sections after deploy.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-21 10:03:05 +02:00
CyberMind
99fc829b45
fix(web): rewrite stale /portal/login.html -> /login.html (closes #222) (#223)
PR #169 moved login.html out of secubox-hub to /usr/share/secubox/www/
under secubox-portal's ownership, but 67 source files across the
package set still redirected to /portal/login.html which no longer
exists on disk. nginx fell back to /index.html (hub root) on every
hit, whose checkAuth() bounced back to /portal/login.html, producing
an infinite "Redirecting to login..." loop with no way for any user
to authenticate.

sed -i 's|/portal/login\.html|/login.html|g' across all packages/*/www
sources (82 occurrences). The two prior partial fixes that triggered
this investigation (bcc6a781, 464e3379) only covered a subset and
missed the kiosk root checkAuth in secubox-hub/www/index.html plus
65 module index.html files.

Verified: grep -rl '/portal/login\.html' packages/ | grep -v /debian/
returns empty.

Discovered while testing the firstboot v2-schema+argon2 chain end-to-end
in a VBox amd64 boot of CI run 26082003883 (the #218 image build fix)
— firstboot now works, users.json gets a valid argon2 hash for
admin/secubox, the portal API runs, but the login UI is unreachable
because of this dangling URL.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-19 11:44:43 +02:00
CyberMind
b21b2000d8
feat(mitmproxyctl): align with LXC reality + forge route verb (closes #173) (#174)
mitmproxyctl is SecuBox's third routing verb, parallel to:
  haproxyctl vhost add/remove   (routing layer)
  giteactl   user add/remove    (identity layer)
  mitmproxyctl route add/remove (interception layer)  ← new

Without this verb, every WAF route change required hand-editing
/srv/mitmproxy/haproxy-routes.json + manual restart. The interception
organ existed but could not be commanded.

Changes:
  * Defaults now match board reality:
      CONTAINER_NAME : "mitmproxy-waf" -> "mitmproxy"
      LXC_PATH       : "/var/lib/lxc"  -> "/data/lxc"
    All overridable via [container] in /etc/secubox/mitmproxy.toml.
  * Added --config flag to load any TOML.
  * New `route` subcommand:
      mitmproxyctl route list
      mitmproxyctl route add HOST IP PORT [--no-restart]
      mitmproxyctl route remove HOST       [--no-restart]
    Atomic writes via .tmp + replace, mirror to the LXC-rootfs copy of
    haproxy-routes.json automatically, restart prefers in-LXC systemd
    `mitmproxy.service` reload over full container bounce.
  * `restart` is now reload-friendly when an in-LXC systemd unit exists
    (the common case on the live board); falls back to stop+start otherwise.
  * `logs` reads via `journalctl -u mitmproxy` in-LXC (was `tail` on a
    file path that didn't exist in practice).

After this lands, the gitea WAF unbypass (done by hand today during the
#156 cascade) reduces to:
  haproxyctl vhost add gitea.gk2.secubox.in mitmproxy_inspector ssl
  mitmproxyctl route add gitea.gk2.secubox.in 192.168.1.200 9080

Three verbs, three layers, one operation. The grammar closes.

Out of scope (separate ticket): the package's debian/postinst still
assumes host-installed mitmproxy under /srv/mitmproxy-waf/, while the
modern board runs the LXC topology this ctl now targets. That refactor
will follow as a postinst -> LXC-bootstrap migration similar to mailctl.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 10:11:00 +02:00
CyberMind
56e5f02bd6
feat(secubox-mitmproxy): cookie-audit hardening — AppArmor + logrotate (closes #170) (#171)
Ship two post-deploy artifacts requested by #156:

  - /etc/apparmor.d/abstractions/secubox-cookie-audit
    Operators with an enforced usr.bin.mitmdump AppArmor profile can
    #include this abstraction to grant the addon rw on the ledger paths
    (/var/log/secubox/cookie-audit/** + /var/lib/secubox/cookie-audit/**).
    No-op on boards without AppArmor enforcement.

  - /etc/logrotate.d/secubox-cookie-audit
    Daily rotation of /var/log/secubox/cookie-audit/server.jsonl,
    14 days kept, 50M maxsize, copytruncate so the running addon keeps
    its fd open across rotations (no SIGUSR1 dance needed).

Both files installed by debian/rules into the existing package layout —
no new dependencies, no postinst changes.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 08:37:17 +02:00
CyberMind
a19486c997
feat: cookie audit pipeline (RGPD / ePrivacy reconciler) (#159)
* feat(mitmproxy): cookie_audit addon — Set-Cookie ledger for RGPD (ref #156)

New mitmproxy addon that hooks the response flow and appends every Set-Cookie
header to /var/log/secubox/cookie-audit/server.jsonl. Cookie values are
sha256-hashed at the addon — the raw value never leaves the process.

Companion to the upcoming browser-side cookie-inventory.js + the
CookieAuditAggregator that will reconcile both streams for RGPD/ePrivacy
audit on operator-owned vhosts.

Also adds the implementation plan under docs/superpowers/plans/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(hub): cookie-inventory.js browser snapshotter (ref #156)

Vanilla JS module that snapshots document.cookie at DOMContentLoaded, +2s,
and on visibilitychange. Names + sha256(value) are POSTed to
/api/v1/cookie-audit/ingest with credentials:'omit'. Hard-capped at 8
snapshots per page to avoid amplification.

Loaded into every HTML response via the WAF banner injection (next commit).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(waf): inject cookie-inventory.js alongside health banner (ref #156)

Extends the existing CDN banner injection block to also append a script tag
loading shared/cookie-inventory.js. Adds two new CDN-config keys:
  - cookie_inventory_url      (default: admin.gk2.secubox.in/shared/...)
  - cookie_audit_ingest_url   (default: admin.gk2.secubox.in/api/v1/...)

Both health banner and cookie inventory now load from the same injected
guard block, so a single </body> replacement covers both.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(metrics): CookieAuditAggregator + Classifier (ref #156)

Aggregator class mirroring CertStatusAggregator: tails the mitmproxy JSONL
Set-Cookie ledger and the browser-snapshot ingest dir, then reconciles per
(vhost, cookie-name).

Per-cookie source verdict:
  * http  — server only
  * js    — browser only -> RGPD violation unless strictly_necessary
  * both  — server + browser

Classifier loads regex rules from config, checks categories in order
(strictly_necessary > functional > analytics > marketing), first match wins.
Default cache file: /var/cache/secubox/metrics/cookie-audit.json.

9 unit tests covering parsing, reconciliation, persistence and malformed
input.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(metrics): wire /api/v1/cookie-audit/{ingest,report,summary} (ref #156)

Imports + initializes CookieAuditAggregator, schedules it in the FastAPI
lifespan alongside the other aggregators, opens up CORS to POST (was GET
only) for the ingest endpoint, and adds three routes:

  POST /api/v1/cookie-audit/ingest   — browser snapshot ingest (rate-bounded,
                                       credentials: omit, returns refused if
                                       audit disabled in config)
  GET  /api/v1/cookie-audit/report?host=…  — per-vhost or global report
  GET  /api/v1/cookie-audit/summary  — global rollup

Hard caps: 200 cookies/snapshot, 128B names, 128B hashes, 512B UA.

All 34 existing metrics tests + 9 new cookie-audit tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(core): get_cookie_audit_config + RGPD classifier baseline (ref #156)

New config helper get_cookie_audit_config() that returns the merged
[cookie_audit] section with built-in RGPD/CNIL classifier patterns.

Categories (eval order — first match wins):
  strictly_necessary  PHPSESSID, csrftoken, cart, remember_token, ...
  functional          lang, locale, theme, cookie_consent, euconsent, ...
  analytics           _ga*, _gid, _gat*, _pk_*, _hjid, _clck, _matomo*, ...
  marketing           _fbp, _fbc, __utm*, _gcl_*, _uet*, IDE, MUID, NID

Operator patterns from [cookie_audit.classifier] are MERGED on top of the
baseline by default. Set classifier_override = true to replace it entirely
(opt-out for sites that need a different taxonomy).

secubox.conf.example documents the section with commented-out examples.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: cookie-audit API + addon (ref #156)

- secubox-metrics README: new "Cookie Audit" section documenting the
  three endpoints, the source verdict semantics (http/js/both), and the
  rgpd_violation rule.
- secubox-mitmproxy README: new "Addons" section listing both
  secubox_waf and cookie_audit + the dual -s mitmdump invocation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(claude): record cookie-audit pipeline in HISTORY+WIP (ref #156)

HISTORY 2026-05-16 entry captures scope (server ledger + browser snapshot
reconciler), the 8 implementation tasks landed in the worktree, and the
two follow-ups left (AppArmor + logrotate).

WIP gets a top entry pointing at the worktree/branch with the test
totals and "awaiting validation, no PR opened" status.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(banner): add Cookie Audit live tile + summary URL injection (ref #156)

Adds a "CookieAudit" section to the health-banner live panel alongside
VisitorOrigin / LiveHosts / CertStatus. It polls /api/v1/cookie-audit/summary
every 30s and renders:

  - host count
  - RGPD verdict row (red ⚠ when violation_count > 0, green ✓ otherwise)
  - per-category breakdown: strict / func / analytics / marketing
  - unclassified row only shown when > 0

The WAF banner-injection block now also sets
window.SECUBOX_COOKIE_AUDIT_SUMMARY (new cookie_audit_summary_url config
key) so the banner can hit the cross-origin summary endpoint when the
host page is on a non-admin vhost.

Banner bumped to v1.4.0. New section hides itself silently when the
aggregator is disabled or empty — zero visual impact on existing
deployments.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:53:40 +02:00
bd7dda0c6f feat(secubox): complete meta-script generator Tasks 14-17
Task 14: Arch Profiles
- Add profiles/arch/arm64.yaml and profiles/arch/amd64.yaml
- Add ResolveWithArch() to merger for base → arch → tier chain
- Add tests for arch profile resolution

Task 15: Package secubox.yaml for All Packages
- Add scripts/generate-secubox-yaml.py generator script
- Generate 131 debian/secubox.yaml files with:
  - Category detection (security, network, system, etc.)
  - Tier assignment (all, lite, standard, pro)
  - API socket and UI path detection

Task 16: APT Repository Setup
- Add apt/conf/ reprepro configuration (multi-arch arm64/amd64)
- Add apt/hooks/lintian-check pre-publish validation
- Add scripts/apt-publish.sh and scripts/apt-sync.sh
- Add apt/README.md documentation

Task 17: CI Integration
- Add .github/workflows/build-secubox-cli.yml
- Build for linux-amd64 and linux-arm64
- Version injection via ldflags
- GitHub releases on tag push

Code Quality Fixes (Tasks 10-13):
- Add atomic writes for OTA boot control files (0600 perms)
- Fix NVME device extraction (nvme0n1p2 → nvme0n1)
- Add scanner.Err() checks in hardware detection
- Fix URL injection validation in fetch command
- Add proper cleanup on checksum failures

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-11 05:32:29 +02:00
68e7763fc3 docs: Add Eye Remote Multigadget skill and wiki
- Add /multigadget skill covering autorun, storage, round UI, tooling
- Add Eye-Remote-Multigadget.md unified wiki hub
- Add Build-System.md to wiki with build documentation
- Add AI-BUILD-PROMPT.md for GPT/Gemini assistance
- Update sidebar and home page with new links
- Update WIP.md with #70 and #71 done

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-10 09:12:42 +02:00
f100172a1c feat(cdn): CDN/WAF transparent banner injection on all sites
- mitmproxy WAF injects health-banner.js into all HTML responses
- Configurable via /api/v1/cdn/banner/config endpoint
- Options: inject_domains, exclude_domains, banner_url, banner_api_url
- Health banner v1.1.0 supports cross-origin CDN injection
- SECUBOX_HEALTH_API global for configurable API endpoint

CDN API endpoints:
- GET  /banner/config - Get injection config
- POST /banner/config - Update config
- POST /banner/toggle - Enable/disable injection
- POST /banner/exclude - Add domain exclusion
- DELETE /banner/exclude - Remove exclusion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-10 07:27:00 +02:00
8f72695314 feat(waf): Add real client IP detection from proxy headers
- Parse X-Forwarded-For and X-Real-IP headers
- TRUSTED_PROXIES set for Docker/LXC bridge IPs
- Debug fields added to threat logs for IP tracing
- Updated HISTORY.md for Session 143

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-10 07:12:30 +02:00
128ee01209 fix(waf): Optimize mitmproxy WAF and fix dead container routes
WAF Optimizations:
- Skip WAF checks for static assets (.js, .css, .png, etc.)
- Skip WAF checks for /health, /status, /system_health
- Skip WAF checks for trusted hosts (git, admin)
- Fixed MultiDictView.to_dict() → dict() AttributeError
- CPU: 90%+ constant → 0% idle, 25-90% under load

Route Sync:
- Auto-fix routes pointing to dead containers (10.100.0.10-50)
- Dead routes redirect to webui (9080) instead of timeout
- Fixed bash arithmetic for set -e compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-09 13:27:18 +02:00
1a7e8288c3 feat(waf): Add styled 502/503 error pages in mitmproxy
When backend is unreachable, mitmproxy now returns styled error pages:
- 502 Bad Gateway: Styled page with auto-retry timer
- 503 Service Unavailable: Maintenance-style page
- 504 Gateway Timeout: Timeout-specific page

Pages include:
- ASCII art headers
- Auto-refresh countdown
- SecuBox branding
- Diagnostic info (host, time)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-09 11:16:29 +02:00
4f7bf7255b feat(waf): Add styled ban page and fix autoban SSH chain
WAF Improvements:
- Add cyberpunk-styled BAN_PAGE with skull, animations, scanlines
- Fix ban_ip() to SSH as mitmproxy user to host CrowdSec
- Add whitelist entries for local IPs (192.168.1.36, 192.168.1.254)
- Autoban now correctly registers in CrowdSec after 3 threats

UI Enhancements:
- Add category emojis to WAF threat list (SQLi💉, XSS🔥, RCE💀, etc.)
- Fix JSON parse error handling in system webui

Session 113: WAF ban page styling + autoban debug

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-07 15:06:06 +02:00
7ab7fc736d feat(dashboard): Add GeoMap and country flags to CrowdSec WebUI
- Add GeoMap tab with country attack distribution
- Display country flags emoji in alerts list
- Show attack percentage by country
- Fix WAF addon to use X-Forwarded-For for real attacker IP
- Enable FAT/VFAT built-in and MVPP2 in LED kernel config

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-07 11:51:41 +02:00
0d7a21486b feat(tow-boot): Add Tow-Boot with eMMC boot support for MOCHAbin
- Add Tow-Boot source to tools/ with eMMC boot partition support
- Enable CONFIG_SUPPORT_EMMC_BOOT via mmcBootIndex for MOCHAbin variants
- Document boot mode jumpers J17-J22 (SPI 0x32, eMMC 0x2B)
- Document Tow-Boot build and flashing procedures
- Add known hardware issues (SPI intermittent, eMMC BootROM failure)
- Remove incorrect microSD slot reference from MOCHAbin docs
- Fix systemd service path (/lib → /usr/lib) in mitmproxy package

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 16:58:25 +02:00
168cf95b26 fix(mitmproxy): Add xz-utils to dependencies
Required by LXC to decompress container images during lxc-create.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 09:34:59 +02:00
d69dd432f7 fix(mitmproxy): Address code review findings
1. Fix LXC architecture detection (amd64 → detect actual arch)
   - bin/mitmproxyctl now uses platform.machine() to detect aarch64/arm64

2. Add missing WebUI API endpoints to status router:
   - /set_mode - Set WAF mode (transparent/inspection/block)
   - /save_settings - Save WebUI settings to TOML config
   - /setup_firewall - Apply nftables redirect rules
   - /clear_firewall - Remove WAF nftables rules
   - /wan_setup - Enable WAN protection via HAProxy
   - /wan_clear - Disable WAN protection

3. Expand StatusResponse with WebUI-expected fields:
   - running, autobans_today/pending/total, mode, wan_protection_enabled,
     crowdsec_feed, block_bots, autoban_enabled, proxy_port, web_port

4. Add /clear_alerts endpoint alias for WebUI compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 08:38:32 +02:00
87602fc755 fix(mitmproxy): Add crowdsec directory to debian/rules install
The postinst script references /usr/share/secubox/mitmproxy/crowdsec/
but the crowdsec directory was not being copied during package build.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 08:34:23 +02:00
d2ab8498de feat(mitmproxy): Add nginx configuration installation
Add nginx config installation to debian/rules:
- Installs mitmproxy.conf to /etc/nginx/secubox.d/
- Enables API proxying to unix socket
- Enables static file serving for WebUI

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 08:31:20 +02:00
5e7e89c03a docs(mitmproxy): Add comprehensive README documentation
Complete module documentation including:
- Architecture diagram with traffic flow
- API endpoints tables (status, settings, alerts, HAProxy, WAF)
- Configuration example with all TOML options
- Detection categories with severity and patterns
- CLI commands reference
- File locations table
- WebUI paths
- CrowdSec integration details
- Dependencies and troubleshooting guide

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 08:30:18 +02:00
2d06be1f8d feat(mitmproxy): Add WebUI filters page
Add filters.html page for managing WAF rule categories:
- Grid layout displaying all 14 WAF categories
- Toggle switches for enable/disable with immediate API calls
- Severity color coding (critical=red, high=orange, medium=yellow)
- Pattern count and hit count display per category
- Category descriptions for all rule types
- Summary bar showing totals (categories, enabled, patterns, hits)
- Follows SecuBox CRT-light styling conventions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 08:28:13 +02:00
d2ccf742cb feat(mitmproxy): Add WebUI settings page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 08:25:59 +02:00
8502916d2f feat(mitmproxy): Add WebUI status page redirect
Add status.html that redirects to index.html for URL consistency.
The existing index.html already provides full WAF status functionality.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 08:23:49 +02:00
21b935fe15 feat(mitmproxy): Add WAF rules router 2026-05-03 08:22:10 +02:00
3b048ff8ad feat(mitmproxy): Add HAProxy integration router
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 08:21:12 +02:00
ab7cdb0ad8 feat(mitmproxy): Add alerts router with threat log and bans 2026-05-03 08:20:08 +02:00
412a2ff71e feat(mitmproxy): Add settings router 2026-05-03 08:19:16 +02:00
91a587f1bd feat(mitmproxy): Add FastAPI main app and status router
- Refactor main.py to use modular router structure
- Add background stats cache refresh (60s interval)
- Create status router with LXC container control endpoints
- Include /health endpoint (no auth) and /status (JWT required)
- Add start/stop/restart container actions via mitmproxyctl

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-03 08:17:48 +02:00