secubox-deb/common/secubox_core/classifiers/host_app.py
CyberMind-FR dca7006ad0 feat(secubox-toolbox): DPI classifier 57→147 patterns + fix R3 metrics aggregation (ref #496)
User : 'dpi icons emoji des application et services web' + 'metrics realtime
toolbox dashboard and splash shows only cookies, no more connexions and others'.

## Two fixes

### 1. DPI classifier extended : 57 → 147 patterns (+ 27 categories)

Mirror in both source locations :
  packages/secubox-toolbox/secubox_toolbox/dpi_class.py   (canonical, 147 patterns)
  common/secubox_core/classifiers/host_app.py             (new file, imports
    from secubox_toolbox.dpi_class so toolbox edits propagate automatically)

New categories with emoji :
  news       📰 — Le Monde, BBC, NYT, Guardian, Reuters, AFP, France Médias, Mediapart
  knowledge  📚 — Wikipedia, Wiktionary, Wikidata, Internet Archive
  ai         🤖 — OpenAI/ChatGPT, Anthropic/Claude, Mistral, Gemini, Copilot,
                  Hugging Face, Perplexity, Ollama, Midjourney, Stable Diffusion
  ecommerce  📦 — Amazon, eBay, Etsy, AliExpress, Shopify, Vinted, Leboncoin
                  Cdiscount, Fnac, Darty
  travel     🚆 — Booking, Airbnb, BlaBlaCar, SNCF, RATP
  gov-fr     🇫🇷 — Service Public, Impôts, ANTS, Ameli, CAF, France Travail
  productivity 📝 — Notion, Slack, Discord, MS Teams, Zoom, Jitsi, BBB,
                    Trello, Asana, Atlassian, Figma, Canva
  maps       🗺 — Google Maps, OpenStreetMap, Mapbox, Waze, Citymapper
  gaming     🎮 — Steam, Epic, PlayStation, Xbox, Nintendo, Battle.net,
                  Minecraft, Roblox, Riot
  crypto     ₿  — Binance, Kraken, Coinbase, Crypto.com, OKX, Blockchain,
                  MetaMask 🦊
  ads        🎯 — Google Ads, ComScore, Hotjar/Mixpanel/Amplitude, Criteo,
                  Adnxs, Rubicon, Taboola, Outbrain
  monitor    📊 — NewRelic, Datadog, Sentry

Plus expanded existing CDN category with OVH, Hetzner, Scaleway, DigitalOcean.

Smoke test verified :
  lemonde.fr → 📰 Le Monde news
  chatgpt.com → 🤖 OpenAI / ChatGPT ai
  vinted.fr → 👕 Vinted ecommerce
  ameli.fr → 🏥 Assurance Maladie gov-fr
  discord.com → 🎮 Discord productivity

### 2. R3 metrics aggregation : merge BOTH mitm units

_aggregate_session() journalctl call read only secubox-toolbox-mitm
(captive R2). R3 clients (which generate logs in secubox-toolbox-mitm-wg)
saw connections/successful/tls_pinned = 0.

Fix : -u secubox-toolbox-mitm -u secubox-toolbox-mitm-wg.

Cookies counts came from SQLite events (correct mac_hash) and worked
already, hence 'only cookies showing'.

### 3. inject_banner classifier import chain

Previously banner imported secubox_core.classifiers.host_app with NO fallback.
That module existed on board (debian package) with only 57 patterns and
shadowed dpi_class. Now :
  try secubox_core.classifiers.host_app
  fallback to secubox_toolbox.dpi_class (147 patterns)

Plus the new common/secubox_core/classifiers/host_app.py source FILE
re-exports from dpi_class so the source-of-truth stays in toolbox.

## Live verification

  patterns count : 147 (was 57)
  categories     : 27 (was 14)
  R3 client report : metric widgets populated (was empty for connexions/
                     hôtes/successful/tls_pinned)
2026-06-06 06:55:10 +02:00

64 lines
3.0 KiB
Python

# SPDX-License-Identifier: LicenseRef-CMSD-1.0
# Copyright (c) 2026 CyberMind — Gérald Kerma <devel@cybermind.fr>
# Source-Disclosed License — All rights reserved except as expressly granted.
# See LICENCE-CMSD-1.0.md for terms.
"""
SecuBox-Deb :: host_app classifier
Maps a hostname to a (category, app, emoji) triplet for banner injection
and DPI reports. Mirror of packages/secubox-toolbox/secubox_toolbox/dpi_class.py
kept here so packages that depend on secubox-core (cookies, dpi, soc) can
import classify_host directly without pulling the whole toolbox.
Phase 6.L (#496) : extended from 57 to 147 patterns covering streaming,
social, messaging E2E, search, cloud, dev, banking FR/intl, email, Apple,
Tor/VPN, news FR/intl, Wikipedia, AI/LLM, e-commerce, travel/SNCF,
gouv.fr, productivity, maps, gaming, crypto exchanges, ads/tracking,
APM monitoring, and CDN/cloud infra.
"""
from __future__ import annotations
import re
# Single source of truth : import the pattern list from secubox_toolbox.dpi_class
# at runtime when available, so toolbox edits propagate automatically.
# Falls back to a static copy here when secubox_toolbox isn't on the path.
try:
import sys as _sys
_sys.path.insert(0, "/usr/lib/secubox/toolbox")
from secubox_toolbox.dpi_class import APP_PATTERNS, CATEGORY_EMOJI
from secubox_toolbox.dpi_class import classify_host, analyze_hosts # noqa: F401
_SOURCE = "secubox_toolbox.dpi_class"
except ImportError:
# Static fallback : minimal pattern set. The full list lives in
# secubox-toolbox. Keep this list short — it's just a smoke test
# for environments where toolbox isn't installed.
APP_PATTERNS = [
(re.compile(r"(^|\.)youtube\.com$|googlevideo\.com$"), "streaming", "YouTube", "📺"),
(re.compile(r"(^|\.)netflix\.com$"), "streaming", "Netflix", "🎬"),
(re.compile(r"(^|\.)facebook\.com$"), "social", "Facebook", "👥"),
(re.compile(r"(^|\.)wikipedia\.org$"), "knowledge", "Wikipedia", "📚"),
(re.compile(r"(^|\.)google\.[a-z.]+$"), "search", "Google", "🔍"),
(re.compile(r"(^|\.)github\.com$"), "dev", "GitHub", "🐙"),
(re.compile(r"(^|\.)signal\.org$"), "messaging-e2e", "Signal", "🔒"),
]
CATEGORY_EMOJI = {
"streaming": "📺", "social": "👥", "messaging-e2e": "🔒",
"messaging": "💬", "search": "🔍", "knowledge": "📚",
"dev": "💻", "other": "",
}
_SOURCE = "host_app.fallback"
def classify_host(host: str) -> dict:
if not host:
return {"category": "other", "app": "?", "emoji": ""}
h = host.lower()
for pattern, category, app, emoji in APP_PATTERNS:
if pattern.search(h):
return {"category": category, "app": app, "emoji": emoji}
return {"category": "other", "app": "?", "emoji": ""}
def analyze_hosts(hosts):
return {"top_apps": [], "by_category": {}, "category_emoji": CATEGORY_EMOJI}