secubox-deb/secubox.conf.example
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

183 lines
8.1 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# /etc/secubox/secubox.conf — Configuration SecuBox-DEB
# Format TOML — généré par firstboot.sh, éditable ensuite
# Recharger : systemctl restart secubox-\*
# ── Global ────────────────────────────────────────────────────────
[global]
hostname = "secubox-01"
timezone = "Europe/Paris"
board = "mochabin" # mochabin | espressobin-v7 | espressobin-ultra
debug = false
log_level = "warning" # debug | info | warning | error
# ── API / Auth ────────────────────────────────────────────────────
[api]
socket_dir = "/run/secubox" # Dossier des Unix sockets
jwt_secret = "" # Généré au firstboot — ne pas modifier
# Utilisateurs locaux (fallback si pas d'OAuth)
[auth]
[auth.users.admin]
password = "secubox" # À changer impérativement !
# password_hash = "$2b$12$..." # bcrypt recommandé (TODO Phase 5)
# ── CrowdSec ──────────────────────────────────────────────────────
[crowdsec]
lapi_url = "http://127.0.0.1:8080"
lapi_key = "" # Généré par : cscli bouncers add secubox-bouncer
# ── DPI / netifyd ─────────────────────────────────────────────────
[dpi]
mode = "inline" # inline | passive
engine = "netifyd" # netifyd | ndpid
interface = "eth0" # Interface à surveiller (WAN)
mirror_if = "ifb0" # Interface miroir pour DPI inline
# ── WireGuard ─────────────────────────────────────────────────────
[wireguard]
interface = "wg0"
listen_port = 51820
# ── NAC / DHCP ────────────────────────────────────────────────────
[nac]
dhcp_interface = "br-lan"
dhcp_range = "192.168.1.100,192.168.1.254,12h"
dns_servers = ["9.9.9.9", "149.112.112.112"]
# Zones : lan_allowed, iot_zone, guest_zone, quarantine
default_zone = "quarantine" # Nouveaux clients en quarantaine par défaut
# ── QoS / Bandwidth ───────────────────────────────────────────────
[qos]
interface = "eth0" # Interface WAN pour le shaping
upload_mbps = 100
download_mbps = 200
enabled = false
# ── CDN Cache ─────────────────────────────────────────────────────
[cdn]
engine = "nginx" # nginx | squid
cache_dir = "/var/cache/secubox-cdn"
cache_size = "5g"
listen_port = 3128
# ── VirtualHosts ──────────────────────────────────────────────────
[vhost]
nginx_sites_dir = "/etc/nginx/sites-available"
certbot_email = "admin@example.com"
default_ssl_mode = "selfsigned" # selfsigned | letsencrypt
# ── OAuth2 providers (secubox-auth) ───────────────────────────────
[oauth]
# [oauth.google]
# client_id = ""
# client_secret = ""
# [oauth.github]
# client_id = ""
# client_secret = ""
# ── Réseau modes ──────────────────────────────────────────────────
[netmodes]
current_mode = "router"
backup_dir = "/var/lib/secubox/netmodes-backup"
confirm_timeout = 300 # Secondes avant rollback auto si pas confirmé
# ── Notifications ─────────────────────────────────────────────────
[notifications]
# [notifications.email]
# smtp_host = "smtp.example.com"
# smtp_port = 587
# from = "secubox@example.com"
# to = "admin@example.com"
# [notifications.webhook]
# url = "https://hooks.example.com/secubox"
# secret = ""
# ── Remote UI / HyperPixel Dashboard ─────────────────────────────
# Configuration du dashboard kiosk HyperPixel 2.1 Round (480×480 px)
# sur RPi Zero W — Affichage des métriques SecuBox en temps réel.
#
# Déploiement :
# bash remote-ui/round/deploy.sh -h <rpi-ip> --api-url http://<secubox-ip>:8000
#
# Service systemd sur le RPi : secubox-remote-ui.service
# Ressources limitées : MemoryMax=256M, CPUQuota=80%
[remote_ui]
enabled = true
api_base = "/api/v1/system" # Endpoint métriques (servi par secubox-system)
refresh_ms = 5000 # Intervalle de rafraîchissement (ms)
simulate = false # Mode simulation (données fictives)
# Seuils d'alerte — CPU (%)
[remote_ui.thresholds.cpu]
warn = 70 # Niveau warning
crit = 85 # Niveau critique
# Seuils d'alerte — Mémoire (%)
[remote_ui.thresholds.mem]
warn = 75
crit = 90
# Seuils d'alerte — Disque (%)
[remote_ui.thresholds.disk]
warn = 80
crit = 95
# Seuils d'alerte — Température CPU (°C)
[remote_ui.thresholds.temp]
warn = 65
crit = 75
# Seuils d'alerte — WiFi RSSI (dBm, valeurs négatives)
[remote_ui.thresholds.wifi]
warn = -70 # Signal faible
crit = -80 # Signal critique
# Mapping services SecuBox vers les anneaux du dashboard
# Ordre : centre vers extérieur = AUTH → WALL → BOOT → MIND → ROOT → MESH
[remote_ui.modules]
AUTH = "secubox-auth" # Authentification / SSO
WALL = "secubox-crowdsec" # WAF / IDS / CrowdSec
BOOT = "secubox-hub" # Dashboard principal
MIND = "secubox-ai-insights" # IA / Insights
ROOT = "secubox-system" # Système / Métriques
MESH = "secubox-p2p" # Réseau mesh P2P
# Palette de couleurs (hex)
[remote_ui.colors]
AUTH = "#C04E24" # Rouge-orange
WALL = "#9A6010" # Bronze
BOOT = "#803018" # Marron foncé
MIND = "#3D35A0" # Violet/indigo
ROOT = "#0A5840" # Vert foncé
MESH = "#104A88" # Bleu marine
# ─────────────────────────────────────────────────────────────────────────────
# Cookie Audit (issue #156) — RGPD / ePrivacy compliance reconciler
# ─────────────────────────────────────────────────────────────────────────────
# When enabled, the mitmproxy cookie_audit addon writes a JSONL ledger of
# every Set-Cookie observed in transit, and the secubox-metrics
# CookieAuditAggregator reconciles it against browser snapshots posted to
# /api/v1/cookie-audit/ingest.
[cookie_audit]
enabled = false
ledger_path = "/var/log/secubox/cookie-audit/server.jsonl"
ingest_dir = "/var/lib/secubox/cookie-audit/ingest"
max_ingest_age_hours = 24
# When true, the operator patterns below REPLACE the built-in RGPD baseline.
# When false (default), they are merged on top — admins can extend but never
# silently drop the baseline.
classifier_override = false
# Custom classification patterns. Each list is matched (re.search) against
# the cookie name, in this order: strictly_necessary > functional > analytics
# > marketing. First match wins. Unmatched names land in "unclassified" and
# get flagged for review.
[cookie_audit.classifier]
# strictly_necessary = ["^app_session$"]
# functional = ["^app_theme$"]
# analytics = ["^my_analytics_"]
# marketing = ["^my_ad_id$"]