Commit Graph

1756 Commits

Author SHA1 Message Date
CyberMind
dc6505a2f2
Merge pull request #552 from CyberMind-FR/feature/551-android-apk-zero-tap-auto-run-silent-onb
Some checks are pending
License Headers / check (push) Waiting to run
Android: zero-tap auto-run silent onboarding on root (#551)
2026-06-13 13:16:59 +02:00
CyberMind
51ed62f10a
Merge pull request #548 from CyberMind-FR/feature/547-linux-firefox-installer-script-for-the-t
Linux Firefox fast installer/launcher for the ToolBoX extension (#547)
2026-06-13 13:16:53 +02:00
CyberMind
dfa7e34ad0
Merge pull request #550 from CyberMind-FR/feature/549-social-tracker-domain-rollup-history-tim
Social: tracker domain-rollup + history + target↔tracker correlation (#549)
2026-06-13 13:16:17 +02:00
2a51348b9d feat(toolbox): tracker domain-rollup + history + target↔tracker correlation (closes #549)
fetch_graph() gains three additive, read-time keys (no schema change,
d3 /social/graph contract untouched):
- by_domain: trackers rolled up under their registrable parent (eTLD+1,
  all *.doubleclick.net → doubleclick.net) with tracker_count/hits/sites/vendors
- targets: inverse map — per 1st-party site, the trackers + parent domains
  watching it
- history: per-UTC-day timeline (hits/trackers/sites) from social_edges
stats gains total_domains; local _registrable_domain helper (no publicsuffix
dep). Integration-tested (rollup, inversion, history). secubox-toolbox 2.6.17.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 13:16:06 +02:00
CyberMind
4cb8fb87fa
Merge pull request #546 from CyberMind-FR/feature/545-injected-banner-neon-tube-redesign-for-r
Neon-tube injected banner for R3 (+ R4-ready theme) (#545)
2026-06-13 13:15:19 +02:00
8d48d86bcd feat(toolbox): neon-tube injected banner for R3 (+R4-ready theme) (closes #545)
_LEVEL_THEME map drives the banner look per opt-in level: R3 (and the
planned R4) get a neon-tube treatment — dark glass bar, glowing tube
border (layered box-shadow) and neon text-shadow on the title — while R2
keeps the original amber flat bar. _banner_html_dynamic() now takes the
level and themes both the CSP-strict (JS-less) and JS (dismissible)
variants; all inline CSS, no injected <style>/@keyframes, ASCII/NCR-clean.
R4 theme is defined but inert until _client_level() returns 'r4'.
secubox-toolbox 2.6.16.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 13:14:56 +02:00
CyberMind
7a651f360d
Merge pull request #544 from CyberMind-FR/feature/543-kbin-landing-radical-simplify-livelier-f
kbin landing: radical-simplify redesign (#543)
2026-06-13 13:14:08 +02:00
81da97e53e feat(android): zero-tap auto-run silent onboarding on root (closes #551)
On a rooted device the app now runs the full silent onboarding on launch
with no taps: a LaunchedEffect auto-starts the root sequence once when
root is detected and this host hasn't been onboarded yet. The root-auto
logic is extracted into a reusable runRootAuto lambda (shared by the
auto-launch and the  button, which remains for re-runs). An onboarded
flag is persisted per host in SharedPreferences so reopening doesn't redo
it. versionName 0.2.0 / versionCode 2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 13:13:02 +02:00
2647cfffa1 feat(webext): Linux Firefox fast installer/launcher script (closes #547)
install-firefox-linux.sh: one call grabs the ToolBoX .xpi (from a cabine
host, --release, or --local) and launches Firefox with it loaded via
'web-ext run' (temporary, works unsigned — fastest), opening /social/me.
Falls back to opening the .xpi for the install prompt when web-ext/npx
is absent, with the unsigned-install note. Detects firefox/-esr/-bin/flatpak.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 13:04:01 +02:00
e4d59569eb feat(toolbox): kbin landing radical-simplify redesign (closes #543)
Animated hero (gazing eye + floating tracker dots) + one big 'Protège-moi
(R3)' CTA + the auto-detected install panel up front. KPIs, cert-probe,
pitch, R0-R3 levels, charts, architecture, open-source and contact are
folded behind an 'En savoir plus' <details>. Quick-nav trimmed: dropped
the CA iPhone / CA Android / QR profil cards (now inside the per-platform
install panel); kept R3 Install / Mon rapport / Ma carto / Wiki / Cabine.
Count-up animation on the live KPIs. All Jinja vars + live-stats and
cert-probe scripts preserved. secubox-toolbox 2.6.15.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 12:52:34 +02:00
CyberMind
d2cb735f09
Merge pull request #542 from CyberMind-FR/feature/532-plan-browser-xpi-webextension-emancipate
Some checks are pending
License Headers / check (push) Waiting to run
docs: webext .xpi published + tag-pinned release note (#532)
2026-06-13 12:48:03 +02:00
9b7c6f67f1 fix(webext): 'redeclaration of const ext' SyntaxError + PNG icons, v0.1.1 (ref #532)
Real cause of the broken extension: api.js and background.js BOTH did
`const ext = …`. In a Firefox event page the background.scripts array
loads them into one shared scope (same via importScripts in a Chromium
SW), and popup.js's `const ext` collided with api.js's in the popup
page realm too — 'redeclaration of const ext' aborts the script. web-ext
lint misses it because it never concatenates/executes the scripts.
Now only api.js declares `const ext`; background.js and popup.js use
`api.ext`.

Also (defensive + Chromium-correct): replace the SVG action/extension
icon with rasterised PNGs (48/128) and keep the SVG out of the package,
so Firefox never renders SVG in chrome UI. Bump to v0.1.1; the
/wg/toolbox.xpi endpoint + fetch helper + docs point at webext-v0.1.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 12:32:17 +02:00
4289f8ff3c docs: webext .xpi published/downloadable + tag-pinned release note (ref #532)
README + wiki Browser-Extension: add the direct release download URL,
document make_latest:false / tag-pinned design. TODO/WIP: mark the
webext-v0.1.0 release published (downloadable, verified) and note the
remaining board deploy of secubox-toolbox 2.6.14.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 11:29:06 +02:00
CyberMind
008da01444
Merge pull request #541 from CyberMind-FR/feature/532-plan-browser-xpi-webextension-emancipate
Some checks are pending
License Headers / check (push) Waiting to run
Tag-pinned .xpi release URL — don't steal "latest" from the APK (#532)
2026-06-13 10:57:16 +02:00
68e2723747 fix(webext): tag-pinned .xpi release URL + make_latest:false (ref #532)
Publishing webext-v* with the default make_latest would steal the
"latest" release pointer from the Android APK release, breaking the
APK endpoint's /releases/latest/download/secubox-toolbox-android.apk
fallback. Publish the webext release with make_latest:false and point
the /wg/toolbox.xpi endpoint + fetch helper at the tag-pinned download
URL instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 10:45:40 +02:00
CyberMind
b8da257b83
Merge pull request #540 from CyberMind-FR/feature/532-plan-browser-xpi-webextension-emancipate
Some checks are pending
License Headers / check (push) Waiting to run
Browser extension: emancipate R3 toolbox cartographie live (#532)
2026-06-13 10:33:01 +02:00
b2ee2a97ef fix(webext): clean web-ext lint — drop unused optional_host_permissions, ignore build.sh/README (ref #532)
web-ext lint: 0 errors, 2 benign warnings (AMO data-collection
declaration is submission-time, tied to the signing follow-up;
service_worker-ignored is the intentional cross-browser pattern).
optional_host_permissions needed FF128 and was unused at MVP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 10:21:45 +02:00
c77e6250a9 feat(webext): browser extension — emancipate R3 cartographie live (ref #532)
New client clients/webext-toolbox/ (WebExtension MV3, Firefox .xpi +
Chromium): surfaces the toolbox live tracker analysis in the browser.

- manifest.json MV3, cross-browser background (service_worker + scripts
  for Firefox 115+ event page); host_permissions *.secubox.in only
- api.js: shared client over /wg/r3-check, /social/me (pair → HMAC token),
  /social/graph/{token}, /social/wipe/{token}
- background.js: toolbar badge = live tracker count, silent re-pair on
  token expiry, colour escalates gold → anti-bot → operator-grade
- popup: 4 stat tiles + dependency-free mini Round-Eye SVG graph + top
  trackers tagged CDN/anti-bot/operator-grade + cartographie/PDF/RGPD-wipe
- options: host / analysis window / manual token
- build.sh + build-webext.yml (web-ext lint + build, release on webext-v*)

Serve from the toolbox (2.6.14):
- GET /wg/toolbox.xpi (local file, else 302 → latest release asset)
- '🧩 Extension navigateur' button on both onboard panels
- sbin/secubox-toolbox-fetch-xpi + postinst serve dir + rules install

No server-side CORS needed (MV3 host_permissions). MVP polls /social/graph
and computes the delta client-side; SSE /social/live is a follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 10:08:06 +02:00
CyberMind
e7a84f0380
Merge pull request #491 from CyberMind-FR/feature/490-phase-2c-toolbox-receiving-modules-actua
Some checks are pending
License Headers / check (push) Waiting to run
feat(phase-2c): receiving modules enrichment (nDPI-style classify, JA4 fingerprint, providers, avatar)
2026-06-13 08:19:50 +02:00
e67baf4cd7 feat(secubox-core+5modules+toolbox): Phase 2c receiving modules enrichment (ref #490)
Phase 2b (#488/#489) wired mitm addons to 5 receiving modules but events
were persisted raw. This phase implements actual enrichment in each module
via the enrich_hook param, plus aggregator merge so reports show meaningful
data (YouTube/Signal/iPhone/Safari/JA4 fingerprints) instead of raw bytes.

  - host_app.py  : 60+ host patterns -> app + category + emoji
  - cookie.py    : 40+ cookie tracker patterns -> provider + category + emoji
  - avatar.py    : UA + Client Hints -> device + browser + OS + emoji
  - ja4.py       : NEW. Deterministic JA4-style fingerprint hash from
                   cipher_suites + alpn + extensions. Lookup table for
                   known JA4 fingerprints (empty for now, Phase 3 will
                   populate). 12-char hex (SHA256 truncated).

The host_app/cookie/avatar are copies of the secubox-toolbox classifiers
moved to secubox-core so all 5 receiving modules can import them. The
secubox-toolbox-local ones stay as-is to avoid breaking changes — Phase 3
will consolidate.

  - secubox-dpi             : host/SNI -> {app, category, emoji}
  - secubox-cookies         : cookie names -> {providers{}, categories{}}
  - secubox-avatar          : UA + CH -> {device, browser, os_label}
  - secubox-threat-analyst  : ClientHello -> {ja4_fingerprint, known_client}
  - secubox-soc             : indicators -> {total_weight, band, kinds}

Each is ~25 lines, called by mount_ingest_routes BEFORE persistence.
Enriched output joins the raw event under the 'enriched' key.

_pull_mitm_module_events() now also calls _summarize_enriched(kind, events)
to consolidate per-module enrichment :

  - dpi             : top_apps[] aggregated from enriched.app counts
  - cookies         : top_providers[] from enriched.providers + tracker_total
  - avatar          : devices{} + browsers{} from enriched.{device,browser}
  - threat-analyst  : top_fingerprints[] grouped by JA4 hash
  - soc             : total_weight + max_band + indicator_kinds

These appear under mitm_modules.<kind>.enriched_summary in the /report JSON.

POST realistic payloads to all 5 sockets :
  - YouTube host -> dpi/enriched.app = 'YouTube' (streaming)
  - GA + FB Pixel cookies -> cookies/providers : GA x3, FB x1, total 4
  - iPhone Safari UA -> avatar/device='iPhone' (📱 iOS 17.4) + Safari (🧭)
  - facebook.com ClientHello -> threat-analyst/ja4 = '7175ee3a68f0'
  - 2 indicators (weight 15+25) -> soc/band='medium', total=40, kinds=[dga, suspicious]

  - secubox-dpi : call live nDPI/netifyd socket (currently pattern-match only)
  - secubox-threat-analyst : implement full FoxIO JA4 string format (currently
    deterministic SHA256 trunc which is JA4-like but not the canonical format)
  - secubox-soc : threat-intel feed lookup (currently just sums static weights)
  - secubox-avatar : screen/timing fingerprinting via WebGL hash (currently UA only)
  - Reports (PDF + HTML) : surface mitm_modules.enriched_summary in the report UI
2026-06-13 08:00:18 +02:00
CyberMind
110133bee9
Merge pull request #539 from CyberMind-FR/feature/538-android-app-root-mode-fully-automated-si
Some checks are pending
License Headers / check (push) Waiting to run
Android root-mode fully-automated silent R3 onboarding (#538)
2026-06-13 07:47:00 +02:00
ac14e65353 docs: wiki/README/WIP/TODO/HISTORY for Android ToolBox app + root-mode (ref #538)
- new wiki page Android-ToolBox.md (install via /wg/toolbox.apk, manual +
  root onboarding flows, CI build, endpoints) + sidebar link
- README: document the root-mode silent path + revised constraints
- WIP/TODO/HISTORY: Android client section (#531/#536/#538)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 07:46:50 +02:00
1351054927 feat(android): root-mode fully-automated silent R3 onboarding (ref #538)
Add an optional one-tap, zero-interaction onboarding path for rooted
devices. When root is detected the app can:

- install the village3b CA into the SYSTEM trust store (bind-mount over
  /system/etc/security/cacerts + conscrypt APEX, SELinux ctx restored),
  so every app trusts the cabine CA — not just user-CA opt-in apps;
- bring the WireGuard tunnel up natively via the kernel module
  (ip link add … type wireguard + wg set), no WireGuard app needed;
- verify R3 reachability automatically.

Falls back to the existing manual handoff (KeyChain CA prompt + WG app)
when the kernel lacks WireGuard. All root actions are gated behind an
explicit ' Installation automatique (root)' tap — nothing runs as root
without the operator choosing it on their own device.

New: RootShell (su wrapper), RootOnboard (silent sequence + subject_hash_old
in pure Kotlin). MainActivity gains a RootAuto step with a streaming log.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 07:40:58 +02:00
CyberMind
46dfd781d3
Merge pull request #537 from CyberMind-FR/feature/536-serve-the-android-toolbox-apk-from-the-t
Some checks are pending
License Headers / check (push) Waiting to run
feat(toolbox): serve Android APK from /wg/toolbox.apk + onboard button (#536)
2026-06-12 23:46:50 +02:00
cf3aef48c8 feat(toolbox): serve Android APK from /wg/toolbox.apk + onboard button (#536)
Follow-up to #531 — one-tap APK install from the cabine.
  - api.py GET /wg/toolbox.apk: serve local APK (android content-type),
    302 → latest GitHub release asset if absent (never dead-ends).
  - /wg/onboard Android panels (inline + _install_panels): 📱 Installer
    l'app ToolBoX (1-tap) button.
  - sbin/secubox-toolbox-fetch-apk: pull latest release asset into the
    serve path (best-effort + APK magic check); postinst creates the dir
    + first fetch.
  - build-android-apk.yml: publish APK as release asset
    secubox-toolbox-android.apk on android-v* tags (contents:write).
  - changelog 2.6.13.

Live on gk2: /wg/toolbox.apk 302 → release (fallback, no release yet),
serve dir created, onboard button rendered.
2026-06-12 23:46:29 +02:00
CyberMind
198fecea11
Merge pull request #535 from CyberMind-FR/feature/531-plan-android-apk-one-tap-toolbox-r3-clie
Some checks are pending
License Headers / check (push) Waiting to run
feat(android): one-tap toolbox R3 installer scaffold + CI (#531)
2026-06-12 23:27:34 +02:00
ab67c981dd feat(android): scaffold one-tap toolbox R3 installer + CI (ref #531)
Kotlin/Jetpack-Compose app under clients/android-toolbox/ replacing the
manual Android onboarding tutorial. 5-step flow:
  discover -> install CA (KeyChain intent) -> import WG profile (handed
  to the WireGuard app via FileProvider) -> verify (/wg/r3-check) ->
  live cartographie sociale (/social/me).

  - ToolboxApi: plain HttpURLConnection client for /wg/ca.crt,
    /wg/profile/new, /wg/r3-check, /social/me (no Retrofit/OkHttp —
    minimal deps + CI).
  - MainActivity: Compose stepper UI, palette-matched (cosmos/gold/cyan),
    FR copy. Intents for CA install + WireGuard handoff + Play fallback.
  - Gradle (AGP 8.5.2 / Kotlin 1.9.24 / Compose BOM 2024.06), minSdk 26,
    targetSdk 34, package in.secubox.toolbox. No wrapper jar committed.
  - res: adaptive launcher icon (vector eye glyph), theme, file_paths,
    strings — all text/XML, no binaries.
  - .github/workflows/build-android-apk.yml: setup-android + setup-gradle
    8.9 build assembleDebug -> APK artifact (sideloadable).
  - README documents the flow, build, and the Android user-CA-trust
    constraint (MVP guides manual confirm; release signing is follow-up).

Closes the scaffold half of #531; CI produces the debug APK.
2026-06-12 18:15:46 +02:00
CyberMind
92dee2d2d0
Merge pull request #534 from CyberMind-FR/feature/529-admin-wireguard-tunnel-wg-admin-for-secu
Some checks are pending
License Headers / check (push) Waiting to run
feat: admin WireGuard tunnel (wg-admin) + SSH hardening (#529)
2026-06-12 17:45:16 +02:00
CyberMind
a3666c4ba4
Merge pull request #533 from CyberMind-FR/fix/530-threatfox-feed-ingests-0-iocs-export-end
fix(threat_intel): ThreatFox ioc_value field — 0 → 5000 IOCs (#530)
2026-06-12 17:44:38 +02:00
e128505dfb fix(threat_intel): read ThreatFox ioc_value field — 0 IOCs → 5000 (closes #530)
The export/json/recent/ endpoint renamed the IOC field ioc → ioc_value;
the parser still read e.get('ioc') and skipped every entry, ingesting 0
for weeks and starving Phase 13.B DNS-guard of domain IOCs. Now reads
ioc_value or ioc. Verified live on gk2: threatfox 0 → 5000 ingested
(2935 domains + 1613 ips + 32 sha256). changelog 2.6.12.
2026-06-12 17:39:55 +02:00
725de94548 docs: WIP — admin WireGuard tunnel + SSH hardening (#529)
Some checks are pending
License Headers / check (push) Waiting to run
2026-06-12 15:09:46 +02:00
154872da9f feat(scripts): add idempotent 'harden' subcommand — key-only sshd + nft SSH-guard (ref #529)
After the wg-admin tunnel is confirmed working, 'harden' closes the
public SSH brute-force surface:
  - sshd drop-in: PasswordAuthentication no + PermitRootLogin
    prohibit-password (refuses if no root authorized_keys — no lockout).
  - nft SSH-guard: drop tcp/22 from sources outside the LAN (192.168.1.0/24)
    + 10.x tunnels, inserted BEFORE the blanket 'iif eth1 accept' so the
    router's port-forwarded public SSH (real public src IP, DNAT no-SNAT)
    is dropped while LAN + wg-admin stay reachable. Persisted in
    /etc/nftables.conf + applied live without flushing other tables.

Applied + verified on gk2: tunnel SSH (10.98.0.1) key-only works; public
admin.gk2.secubox.in:22 now times out. Tables (blacklist/wg) intact.
2026-06-12 15:09:00 +02:00
3c289c50b9 fix(scripts): local loop vars in write_server_conf so client $pip isn't clobbered (ref #529)
The while-read in write_server_conf reused the global pip/ppub names, so
after it ran the caller's $pip (the new peer IP for the client config)
was wiped to empty — the emitted client config showed 'Address = /32'.
The provisioned server state was always correct; only the printed config
was wrong. Loop now uses local _pn/_pip/_pub.
2026-06-12 14:49:38 +02:00
8f2a5c1608 feat(scripts): admin WireGuard tunnel setup script (wg-admin, ref #529)
Idempotent provisioner for a dedicated out-of-band admin tunnel,
distinct from wg-toolbox:
  - wg-admin UDP 51821, server 10.98.0.1/24, peers 10.98.0.2+/32.
  - generates server+peer keys once (0600, never in repo), writes
    /etc/wireguard/wg-admin.conf from a peers state file.
  - installs /etc/nftables.d/secubox-admin-wg.nft (allow udp/51821,
    persistent) — ADDITIVE, does not touch sshd or existing rules.
  - 'add <name>' mints a client .conf + QR (split-tunnel, endpoint
    admin.gk2.secubox.in:51821).
sshd hardening (key-only + restrict 22) is a deliberate separate step.
2026-06-12 14:47:21 +02:00
9a275e2355 docs: WIP repo-clean state, drop Round Eye item
Some checks failed
License Headers / check (push) Has been cancelled
2026-06-11 07:46:12 +02:00
2dab321e36 docs: Phase 12.C + Phase 13 (protection enforcement plane) complete — v2.13.16-19
- Phase 12.C operator-grade detection (#518, v2.13.16).
  - Phase 13 A/B/C/D enforcement plane complete (#519-#528, v2.13.17-19):
    nft blacklist spine + DNS-guard + per-device attribution/quarantine +
    detection→enforcement feedback loop (all escalation default OFF).
  - override_dh_strip drift bug fixed (#521).
  - Phase 14 deception-proxy idea captured (#525) for later.
2026-06-11 07:42:42 +02:00
CyberMind
982176209a
Merge pull request #528 from CyberMind-FR/feature/527-phase-13-d-feedback-loop-social-mapping
Phase 13.D — detection→enforcement feedback loop (#527)
2026-06-11 07:40:32 +02:00
de8e6de23c feat(toolbox): Phase 13.D — detection→enforcement feedback loop (ref #527)
Completes Phase 13 (protection enforcement plane). ALL SOURCES DEFAULT OFF.

  - escalate.py: evaluator reads social-mapping (by_opgrade/by_antibot)
    + device-blocks aggregates, applies operator-tunable thresholds:
      * operator-grade data-broker hosts over threshold → resolve IPs →
        blacklist_v4/v6 (+ optional cscli decision for audit/TTL),
      * anti-bot vendors over threshold → flag only (legit infra),
      * devices over DoH threshold → 13.C quarantine.
    Every action append-logged to /var/log/secubox/audit.log (CSPN),
    reversible (nft/cscli TTL + operator unban).
  - sbin/secubox-escalate + .service/.timer (10min); sources opted in
    via SECUBOX_ESCALATE_* drop-in.
  - api.py GET /admin/escalate: policy flags + last-cycle summary.
  - changelog 2.6.11.

Live on gk2: timer active, default-off cycle takes 0 actions; synthetic
test with SECUBOX_ESCALATE_DEVICE_DOH=1 quarantined a device over
threshold + wrote the audit entry. Detection stays factual; escalation
is separate, logged, reversible, opt-in (#519 doctrine).
2026-06-11 07:40:15 +02:00
CyberMind
ffa75bbe9d
Merge pull request #526 from CyberMind-FR/feature/524-phase-13-c-dhcp-wg-per-device-attributio
Phase 13.C — DHCP/WG per-device attribution + quarantine (#524)
2026-06-11 07:35:10 +02:00
9697ea05a9 feat(toolbox): Phase 13.C — DHCP/WG per-device attribution + quarantine (ref #524)
Turns the enforcement counters into per-device intelligence.

  - secubox-blacklist.nft: quarantine_v4/v6 sets + quarantine-first drop
    in the enforce chain (a quarantined device's saddr is fully cut off).
    Rate-limited log prefixes SBX-BL-DROP (enforce) + SBX-DOH (doh_watch,
    ct state new) for attribution.
  - device_blocks.py: device resolver (R3 WG peer hash / dnsmasq-lease
    MAC hashed with rotating salt / IP fallback) + device_blocks SQLite
    aggregate + retention. Anonymous, same mac_hash model as social.
  - sbin/secubox-blacklist-attrib: cursor-based journald kernel-log
    tailer buckets SBX-BL-DROP / SBX-DOH by source IP -> device ->
    device_blocks. 2-min timer.
  - api.py: GET /admin/device-blocks, POST /admin/quarantine/{ip} +
    /admin/unquarantine/{ip}.
  - app.py: device_blocks 7-day retention.
  - index.html operator tab: per-device blocked-attempts card + one-click
    quarantine.
  - changelog 2.6.10.

Live on gk2: enforce chain quarantine-first + drop logs, attrib timer
active, quarantine add/remove via API verified, device resolver maps
10.99.1.60 -> 9433ceb90895a075 (WG hash), record+aggregate green.
Auto-quarantine NOT wired (operator-manual this pass; threshold = #519 Q2).
2026-06-11 07:32:43 +02:00
CyberMind
f34dc633a8
Merge pull request #523 from CyberMind-FR/feature/522-phase-13-b-dns-guard-resolve-blocklisted
Some checks are pending
License Headers / check (push) Waiting to run
Phase 13.A + 13.B — protection enforcement spine + DNS-guard (#521 #522)
2026-06-11 07:25:58 +02:00
1063c91815 feat(toolbox): Phase 13.B — DNS-guard (resolve blocklisted domains + DoH/DoT detection) (ref #522)
Closes the DoH / hardcoded-IP bypass gap on top of 13.A.

  - secubox-blacklist-sync: Source 3 resolves threat_intel domain IOCs
    (ioc_type='domain') to A/AAAA via getent (2s per-lookup timeout,
    2000-domain cap) and pushes the IPs into blacklist_v4/v6 — a device
    that resolves a known-bad domain out-of-band (DoH / hardcoded IP) is
    still dropped at forward. Writes /run/secubox/blacklist-sync.json.
  - secubox-blacklist.nft: doh_detect_v4/v6 sets + count-only doh_watch
    chain (priority -11) countering device egress to known DoH/DoT
    providers (Cloudflare/Google/Quad9/AdGuard/OpenDNS/CleanBrowsing/
    Control-D/NextDNS) on tcp 443/853. Made the drop-in IDEMPOTENT via
    the create-or-replace idiom (table{} ; delete table ; table{...}) so
    nft -f reloads don't append duplicate rules.
  - secubox-blacklist-sync: populates DoH sets each cycle;
    SECUBOX_DOH_BLOCK=1 also enforce-drops them (forces devices back
    through Vortex DNS). Default off — intrusive, gated per #519 Q1.
  - api.py /admin/blacklist: doh_detect counts, doh_hits, resolved_domains,
    doh_block flag.
  - changelog 2.6.9.

Live on gk2: idempotency verified (enforce=4 / doh_watch=2 rules after
double reload), endpoint shows v4_count 20 + doh_detect 15 v4 / 6 v6,
doh_block false. resolved_domains 0 (threat_intel has no domain IOCs
yet — threatfox feed currently returns 0; path is correct).
2026-06-11 07:24:24 +02:00
a5c07c3d50 feat(toolbox): Phase 13.A — unified nft blacklist enforcement spine (ref #521)
First track of the protection enforcement plane (#519). Pure netfilter,
additive drops, DEFAULT-DROP doctrine preserved.

  - nftables.d/secubox-blacklist.nft: table inet secubox_blacklist with
    blacklist_v4/v6 sets (interval,timeout) + a single forward-hook
    chain (priority -10, policy accept) counter-dropping any routed
    packet whose saddr OR daddr is blacklisted. One rule set covers
    every device egress path (captive/WG/br-lxc/LAN), no per-iface logic.
  - sbin/secubox-blacklist-sync: unions CrowdSec ban decisions (cscli)
    + threat-intel C2 IPs (threat_intel ip IOCs) into the sets, 2h
    per-element timeout (auto-expire on stale feeds), 50k cap, idempotent
    add (no flush race with CrowdSec's own table).
  - systemd sync .service + .timer (5min + OnBootSec 90s).
  - postinst: install drop-in, reload nft, enable+start timer, first sync.
  - api.py GET /admin/blacklist: element counts + drop counters (nft -j).

  - debian/rules FIX: moved the whole override_dh_strip body into
    execute_after_dh_auto_install. dh_strip is NOT in the binary-indep
    sequence for an Architecture: all package, so override_dh_strip
    silently never ran — the nft drop-ins / unbound / nginx / perf
    drop-ins (and now the blacklist files) had stopped shipping in the
    .deb and gk2 was running stale on-disk copies (the live-config-drift
    we kept hitting). Now they all ship again.

  - changelog 2.6.8.

Live on gk2: table loaded, first sync populated 18 v4 C2 IPs with 2h
timeouts, enforce chain active (4 drop rules, counters wired), timer
enabled, /admin/blacklist returns active:true.
2026-06-11 07:16:35 +02:00
CyberMind
febf58fd27
Merge pull request #520 from CyberMind-FR/feature/518-phase-12-c-operator-grade-state-adjacent
Some checks are pending
License Headers / check (push) Waiting to run
Phase 12.C — operator-grade / state-adjacent identity detection (#518)
2026-06-10 14:51:58 +02:00
0d1d3475db feat(toolbox): Phase 12.C — operator-grade / state-adjacent identity detection (ref #518)
Extends Phase 8 Utiq (#500) into a general top-severity identity detector.
Passive detection only — no bypass.

  - social_graph.py detect_operator_grade(): telco header-enrichment
    (MSISDN/x-acr/WAP-bearer), operator-consortium IDs (Utiq/TrustPid),
    data-broker / state-adjacent hosts (LiveRamp/BlueKai/Acxiom/Neustar/
    Tapad/Experian/Palantir-class). Returns (vendor, category).
  - social.py: social_host_meta.opgrade_vendor+category; social_opgrade
    per-client table; record_host_opgrade + record_opgrade_event +
    opgrade_for_client; fetch_graph/aggregate/wipe wired.
  - social.js: top-tier void-purple lens (above anti-bot) + pulsing
    double ring +  banner; node-detail vendor+category.
  - index.html operator tab: opgrade breakdown card.
  - social_report.py: operator-grade evidence section in the PDF.
  - i18n FR/EN + cache-bust ?v=26c. changelog 2.6.7.

Live on gk2: social_opgrade table created, detect matrix green
(msisdn/x-acr/utiq/liveramp/bluekai/palantir/none), aggregate by_opgrade
+ opgrade_clients present, per-client stats populate, PDF 42777 valid.
Factual network-surface flagging only, no entity qualification.
2026-06-10 14:36:02 +02:00
66b608d760 docs: update WIP/HISTORY/TODO for Phase 11 complete + Phase 12.A/B + v2.13.15
Some checks are pending
License Headers / check (push) Waiting to run
- Phase 11 A/B/C + toolbox tabs (#513) + Phase 12.A CDN (#515) + 12.B
    anti-bot (#516) all merged via PR #517, secubox-toolbox 2.6.6, tag
    v2.13.15.
  - Round Eye: USB TX wedge diagnosed, needs physical Pi power-cycle.
  - Next: Phase 12.C operator-grade; 12.B bypass + 12.D noise gated
    behind doctrine.
2026-06-10 14:25:26 +02:00
CyberMind
3a0d60c588
Merge pull request #517 from CyberMind-FR/feature/516-phase-12-b-anti-bot-prove-you-re-human-c
Phase 11 (social mapping A/B/C) + Phase 12.A/B (CDN + anti-bot) + toolbox sub-tabs
2026-06-10 14:23:05 +02:00
8bf5fe4f9a fix(toolbox): Carto operator link redirects to absolute kbin URL (ref #516)
The Clients-tab 🕸️ Carto link 303'd to a relative /social/{token}, but
that route is only served on the kbin vhost — from admin.gk2 it hit the
aggregator's 'missing module' page. admin_client_social() now swaps the
leading admin. host label for kbin. and redirects to the absolute URL.

Live: 303 -> https://kbin.gk2.secubox.in/social/{token} -> 200. changelog 2.6.6.
2026-06-10 14:22:16 +02:00
9f850bef53 feat(toolbox): Phase 12.B — anti-bot detection + visible ring levels + per-client operator tools (ref #516)
Anti-bot / 'prove you're human' DETECTION (bypass stays gated behind doctrine):
  - social_graph.py detect_antibot(): reCAPTCHA/hCaptcha/Turnstile/Datadome/
    PerimeterX-HUMAN/Arkose/Kasada/Akamai-BotManager from URL+cookies+headers.
  - social.py: social_host_meta.antibot_vendor + social_antibot per-client
    challenge table; fetch_graph/aggregate/wipe_mac carry it.
  - social.js: cinnabar severe lens + spinning warning ring + 🤖 label +
    'challenged your humanity' alert banner; node-detail vendor.
  - operator social tab: anti-bot breakdown card.

Fix the ring-level visibility the user reported missing:
  - radial force now DOMINANT (strength 0.9) with weak charge/links, plus
    dashed ring guides (inner=sites, outer=trackers); assets cache-busted
    ?v=264b so the new layout actually loads.

Per-client operator tools in the Clients tab:
  - 🕸️ Carto link → GET /admin/clients/{mac}/social mints a token + opens
    that client's graph.
  - ↺ Reset (RAZ) → POST /admin/clients/{mac}/reset wipes social + events +
    consents + reports and zeroes score (store.reset_client + social.wipe_mac).

changelog 2.6.5. Live on gk2: both new tables created, detect_antibot matrix
green, aggregate by_antibot/antibot_clients present, reset endpoint 200, graph
nodes carry antibot_vendor, served assets contain the ring + cache-bust.
2026-06-10 14:22:16 +02:00
a93d949ede feat(toolbox): Phase 12.A — CDN detection + Round-Eye central-hotspot graph (ref #515)
First passive track of the #514 anti-human-detection platform.

  - social_graph.py: detect_cdn() classifies the edge network fronting
    each 3rd-party host from response headers (Cloudflare/Fastly/Akamai/
    CloudFront/Google/Vercel/Netlify/BunnyCDN/KeyCDN/Sucuri/Imperva +
    generic edge-cache). Host-stable, recorded off-thread. Also deduped
    a stray duplicate _ja4_hash left by the 11.C edit.
  - social.py: new social_host_meta table; fetch_graph LEFT JOINs
    cdn_vendor/cache_status onto nodes; aggregate adds by_cdn.
  - social.js: per-client graph re-centred on a Round-Eye hotspot —
    device = pulsing eye at centre, sites orbit on inner forceRadial
    ring, trackers push to outer ring (densest clusters = hot spots).
    Tracker nodes tinted by CDN vendor; node-detail shows CDN/cache.
  - social.css: eye halo/sclera/iris/pupil + breathing anim + cinnabar
    spokes.
  - index.html: operator social tab gains a CDN/edge breakdown card.
  - i18n: node_detail_cdn FR/EN. changelog 2.6.4.

Live on gk2: social_host_meta table created, addon loads detect_cdn,
detect_cdn matrix green (CF/Fastly/Akamai/CloudFront/none), end-to-end
read path proven (synthetic Cloudflare record -> graph node cdn_vendor
-> aggregate by_cdn). Populates from live traffic.
2026-06-10 14:22:16 +02:00