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.
This commit is contained in:
CyberMind-FR 2026-06-05 16:33:45 +02:00
parent 2558e28f17
commit 1685cf6c08
4 changed files with 182 additions and 2 deletions

View File

@ -3,6 +3,99 @@
---
## 2026-06-05 — Phase 6 R3 WIREGUARD : MAJOR RELEASE shipped (ref #496) + WAF leak FIXED
Phase 6 (R3 mode = portable WireGuard tunnel + mitm interception from anywhere)
went from rough plumbing this morning to a polished public-grade release by
evening. Branch `feature/496-phase-6-wireguard-mitm-autocert-mode-r3` carries
30 commits, 2918 insertions across 26 files.
### What ships
**R3 architecture** (#496, deployed live on gk2)
* WireGuard server `wg-quick@wg-toolbox` on UDP 51820, multi-peer
* DNS A record `kbin.gk2.secubox.in → 82.67.100.75` provisioned via Gandi API
* Dedicated mitm CA `Gondwana ToolBoX R3 CA` (separate from R1/R2 captive CA)
— final version has no SAN (Android Chrome rendered "émis par null" when SAN
contained spaces) and is served as PEM (/wg/ca.pem), DER (/wg/ca.crt),
Apple mobileconfig (/wg/ca.mobileconfig)
* mitm-wg transparent on 10.99.1.1:8081 with launcher wrapper composing
`--set ignore_hosts=<regex>` from `/var/lib/secubox/toolbox/mitm-bypass.conf`
on every restart (15 patterns default : Signal, WhatsApp, Telegram,
Apple Push, French banks)
* HAProxy vhost `kbin.gk2.secubox.in` with wildcard cert → backend
toolbox_landing → 10.99.0.1:8088 (FastAPI). All endpoints reachable from
Internet without captive constraints.
**R3 first-class identity** (Phase 6.H, commit 2fab850a)
* `mac_hash_of()` is now WG-aware: 10.99.1.x → sha256(peer_pubkey)[:16]
(cached, mtime-reloaded). Cascade fix : all addons (cookies, dpi, ja4,
soc, avatar, inject_banner, local_store) now write R3 events under the
correct stable mac_hash. Backfilled 21 existing peers into the clients
table with level=r3.
**Banner enrichment** (Phase 6.G, commit 67985d93)
* inject_banner now computes per-flow : cookies set+sent count, tracker
domains in body (200kB scan), is_tracker_host flag (1st-party host
matches ads*/pixel/analytics patterns). Display : 🍪 N · 🎯 N ·
⚠ tracker-host. Privacy-safe : counts only, no names embedded.
**Splash R3 detection** (Phase 6.I, commit 13e48c93)
* When request to / comes from 10.99.1.x, splash shows large gradient
"🌐 Mode R3 — Tunnel WireGuard ACTIF" banner + report/PDF/reinstall
links, and HIDES the captive R0/R1/R2 chooser form (useless to R3
clients who are by construction at max-analysis).
**Landing + admin polish** (commits b865636a, d81e16ac, e2b89314)
* Public landing at https://kbin.gk2.secubox.in : 8-icon quicknav grid,
8 live KPI cells (auto-refresh /5s via /cumulative-stats.json with pulse
+ flash animations), 🔬 cert R3 2-step probe (detects tunnel + mitm CA
trust separately), 4-level explanation cards, SVG charts.
* /admin/ webui tabbed (👥 Clients + 🛡 Mitm filtering) with rich client
table, level switch modal, per-row × delete on filter patterns.
* /admin/filter-control on public kbin = READ-ONLY (banner links to private
editor). Edit happens at https://admin.gk2.secubox.in/toolbox/ (SSO-gated)
in a new Filter card added to the existing toolbox webui.
**Multi-OS install** (commit 645ce572)
* /wg/r3-install page with 5 OS tabs (🍎 iOS, 🤖 Android, 🐧 Linux,
💻 macOS, 🪟 Windows), each with copy-paste-ready commands. Android
tab explicitly warns Chrome cannot install + walks Settings → Security
→ Encryption & credentials path.
* Wiki page : https://github.com/CyberMind-FR/secubox-deb/wiki/R3-WireGuard-install
(237 lines, same install matrix + architecture + whitelist + troubleshoot).
### Bugs fixed during the session
* **R3 banner not firing** : inject_banner gate accepted only "r2", not r3 (0a6073d5)
* **/report/me/html 400 on WG** : added ?mh=<hash> bypass (67985d93)
* **iPhone HTTPS broken in R3** : mitm 11 had no CA loaded, served default
CN=mitmproxy null cert (38461de4 → ba7144a3 final clean CA)
* **Android "émis par null"** : CA had SAN with spaces → Chrome parser
failed → cert install dialog showed null. Regenerated CA minimal DN, no
SAN (ba7144a3).
* **mitm-wg restart loop 191x** : `/etc/secubox/toolbox/ca-wg/mitmproxy-ca.pem`
was 0600 root:secubox-toolbox, mitm couldn't read as group member (owner
bit only). Fix : 0640 group-readable (3ba9e4ad).
* **chess.maegia.tv 504 + general perf** : 1) streamlit LXC consuming 15
Python procs stopped + auto-start disabled (saved ~250 MB RAM) ; 2) mitm
WAF leak — pool of upstream keep-alive sockets accumulated 1500+ FDs over
4h → workers saturated → HAProxy 504. Fix : single line in addon
`flow.request.headers["Connection"] = "close"` forces upstream nginx to
close after each response (e2b89314 live + source backport this commit).
Cost: ~1ms loopback TCP handshake per request. FDs 1513→3, scur 812→87.
### What still needs eyes
* iPhone + Android : reinstall the FINAL CA (SHA1
`D5:E4:3A:C1:AD:4E:25:8A:A9:D4:2A:26:52:2C:D8:82:50:63:EA:0E`) and
delete any older "Gondwana ToolBoX..." profile first. Banner appears
on HTTPS pages once new CA is trusted.
* PR #495 (Phase 5 LXC) + PR #496 (Phase 6 WG) to be opened once banner
E2E confirmed on both phones.
---
## 2026-06-02 — Pi 400 BOOTS TO KIOSK + login works (live patches + #442 closed)
The v2.13.10 image flashed yesterday booted but never reached graphical.target.

View File

@ -1,10 +1,31 @@
# TODO — SecuBox-DEB Backlog
*Mis à jour : 2026-06-02*
*Mis à jour : 2026-06-05*
---
## 🔥 P0 — Immediate (in flight)
### Phase 6 R3 WireGuard ✅ MAJOR RELEASE shipped 2026-06-05 (ref #496)
- [x] **#496 Phase 6** R3 portable WG tunnel + mitm + multi-OS install — branch
`feature/496-phase-6-wireguard-mitm-autocert-mode-r3` (30 commits, 2918 lines, 26 files).
Live on gk2 + wiki + landing public kbin.gk2.secubox.in.
- [x] **mitm WAF leak fix** (Connection: close upstream) — FDs 1513→3, scur 812→87.
Live + backported `packages/secubox-mitmproxy/addons/secubox_waf.py`.
- [x] **Kbin filter-control READ-ONLY** + admin.gk2 toolbox webui editable card.
- [ ] **iPhone + Android E2E confirm** : reinstall NEW CA
(SHA1 `D5:E4:3A...`), test banner sur HTTPS, validate "Mon rapport" link
→ kbin/?mh= ouverture rapport perso.
- [ ] **Merge** branche feature/496-... → master + push.
- [ ] **PR #495** (Phase 5 LXC) + **PR #496** (Phase 6 WG) à ouvrir après E2E confirmé.
### Phase 6 follow-ups
- [ ] threat_counts dict cleanup périodique dans secubox_waf.py (mineur leak)
- [ ] WAF leak fix : backporter aussi `packages/secubox-waf/mitmproxy/secubox_waf.py`
(le 2e fichier mitmproxy addon en sync, currently 756 lines vs 930 dans secubox-mitmproxy)
- [ ] Investigate mitm-wg CPU > 30% au repos (idle keep-alives ?)
### Release pipeline ✅ v2.13.4 APT GREEN + v2.13.12 rpi400 kiosk SALON-READY
- [x] **v2.13.4** APT publish vert (chaîne #425 + #427/PR #428 + #431/PR #432).

View File

@ -1,5 +1,62 @@
# WIP — Work In Progress
*Mis à jour : 2026-06-02*
*Mis à jour : 2026-06-05*
---
## 🔄 2026-06-05 : Phase 6 R3 WireGuard — MAJOR RELEASE shipped (ref #496)
### ✅ Done
* **WG server** `wg-quick@wg-toolbox` UDP 51820 multi-peer, NAT via pure nft,
DSL port-forwarded, `kbin.gk2.secubox.in` DNS A record via Gandi API.
* **mitm-wg transparent** sur 10.99.1.1:8081, launcher wrapper compose
`--set ignore_hosts=<regex>` from `/var/lib/secubox/toolbox/mitm-bypass.conf`
(15 patterns defaults : Signal/WhatsApp/Telegram/Apple Push/banks FR).
* **Dedicated R3 CA** `Gondwana ToolBoX R3 CA` (final : pas de SAN — Android
Chrome ne supporte pas SAN avec espaces, affichait "émis par null").
Serve `/wg/ca.pem`, `/wg/ca.crt` (DER), `/wg/ca.mobileconfig`.
* **R3 first-class identity** : `mac_hash_of()` WG-aware (10.99.1.x →
sha256(pubkey)[:16]). Cascade fix tous addons + `/wg/profile/new`
enregistre peer in `clients` table level=r3. 21 peers backfilled.
* **Banner enrichi** : 🍪 cookies (set+sent) + 🎯 trackers (body scan 200kB)
+ ⚠ tracker-host (1st-party). URL "Mon rapport" dynamique kbin public.
* **Splash R3 detection** : large banner violet pour 10.99.1.x source, masque
R0/R1/R2 chooser (useless en R3).
* **Landing public** kbin : 8-icon quicknav, 8 live KPI cells /5s, 🔬 cert
2-step probe (tunnel + CA trust), 4-level cards, SVG charts.
* **Admin webui** : tabs 👥 Clients + 🛡 Mitm filtering, rich client table,
level switch modal, inline pattern add/delete.
* **Kbin filter-control = READ-ONLY**, edit déplacée vers
`admin.gk2.secubox.in/toolbox/` (SSO-gated, new Filter card).
* **Multi-OS install** : `/wg/r3-install` 5 tabs (iOS/Android/Linux/macOS/Win)
avec copy-paste commands. Wiki page complète.
* **mitm WAF leak FIXÉ** : root cause = pool keep-alive upstream qui jamais
shrink, 1500+ FDs après 4h → 504. Fix 1 ligne :
`flow.request.headers["Connection"] = "close"` dans SecuBoxWAF.request.
Before/after : FDs 1513→3, scur 812→87, /toolbox/ 504→200/31ms.
Backporté dans `packages/secubox-mitmproxy/addons/secubox_waf.py`.
* **Bugs résolus** :
- mitm-wg crash-loop 191x (mitmproxy-ca.pem 0600 → 0640)
- banner gate accepted only r2 (now r2+r3)
- /report/me/html 400 sur WG (ajout ?mh= bypass)
- streamlit LXC bouffait 250MB + 15 procs (stopped + auto-start off)
### ⬜ Next up
* **iPhone + Android E2E retest** : réinstaller CA Gondwana NEW
(SHA1 `D5:E4:3A:C1:AD:4E:25:8A:A9:D4:2A:26:52:2C:D8:82:50:63:EA:0E`),
supprimer ancien profil d'abord, vérifier banner R3 + cookies + trackers
visibles sur HTTPS pages.
* **Merge branche feature/496-phase-6-wireguard-mitm-autocert-mode-r3 →
master** (30 commits, 2918 lignes, branche prête).
* **Ouvrir PR #495** (Phase 5 LXC) + **PR #496** (Phase 6 WG) une fois
banner E2E confirmé.
### 📌 Follow-ups potentiels
* Threat_counts dict cleanup périodique (mineur leak, ~1 entrée/IP unique)
* Investigation : pourquoi mitm-wg garde CPU > 30% au repos (idle keep-alives ?)
* WAF leak fix : appliquer aussi à secubox-mitmproxy-deb (LXC template)
---

View File

@ -741,6 +741,15 @@ class SecuBoxWAF:
pass
def request(self, flow: http.HTTPFlow):
# Connection close (Phase 6.J leak fix, ref #496) — prevents mitmproxy
# from accumulating idle keep-alive sockets to upstream backends.
# Without this, the per-server connection pool grows ~1 entry per
# unique upstream host and never shrinks; after a few hours we
# observed 1500+ FDs, 800+ ESTAB sockets, worker queue saturation,
# HAProxy timeouts → HTTP 504 on every WAF-routed vhost.
# Cost : 1 TCP handshake per request to upstream (~1ms loopback).
flow.request.headers["Connection"] = "close"
# Pre-route guard: a Host header that is one of this box's own
# listening IPs and is not explicitly mapped in haproxy-routes
# would loop (HAProxy default_backend mitmproxy_inspector ->