Files
dashboard/backend/main.py
SOC Analyst d4c3512572 feat: 6 améliorations SOC — synthèse IP, baseline, sophistication, chasse proactive, badge ASN, 2 nouveaux onglets rotation
- investigation_summary.py: nouveau endpoint GET /api/investigation/{ip}/summary
  agrège 6 sources (ML, bruteforce, TCP spoofing, JA4 rotation, persistance, timeline 24h)
  en un score de risque 0-100 avec signaux détaillés
- InvestigationView.tsx: widget IPActivitySummary avec jauge Risk Score SVG,
  badges multi-sources et mini-timeline 24h barres
- metrics.py: endpoint GET /api/metrics/baseline — comparaison 24h vs hier
  (total détections, IPs uniques, alertes CRITICAL) avec % de variation
- IncidentsView.tsx: widget baseline avec ▲▼ sur le dashboard principal
- rotation.py: endpoints /sophistication et /proactive-hunt
  Score sophistication = JOIN 3 tables (rotation×10 + récurrence×20 + log(bf+1)×5)
  Chasse proactive = IPs récurrentes sous le seuil ML (abs(score) < 0.5)
- RotationView.tsx: onglets 🏆 Sophistication et 🕵️ Chasse proactive
  avec tier APT-like/Advanced/Automated/Basic et boutons investigation
- detections.py: LEFT JOIN asn_reputation, badge coloré rouge/orange/vert
  selon label (bot/scanner → score 0.05, human → 0.9)
- models.py: ajout champs asn_score et asn_rep_label dans Detection

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-16 00:43:27 +01:00

138 lines
4.4 KiB
Python

"""
Bot Detector Dashboard - API Backend
FastAPI application pour servir le dashboard web
"""
import logging
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
import os
from .config import settings
from .database import db
from .routes import metrics, detections, variability, attributes, analysis, entities, incidents, audit, reputation, fingerprints
from .routes import bruteforce, tcp_spoofing, header_fingerprint, heatmap, botnets, rotation, ml_features, investigation_summary
# Configuration logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Gestion du cycle de vie de l'application"""
# Startup
logger.info("Démarrage du Bot Detector Dashboard API...")
logger.info(f"ClickHouse: {settings.CLICKHOUSE_HOST}:{settings.CLICKHOUSE_PORT}")
logger.info(f"Database: {settings.CLICKHOUSE_DB}")
# Tester la connexion ClickHouse
try:
client = db.connect()
client.ping()
logger.info("Connexion ClickHouse établie avec succès")
except Exception as e:
logger.error(f"Échec de connexion ClickHouse: {e}")
raise
yield
# Shutdown
logger.info("Arrêt du Bot Detector Dashboard API...")
db.close()
# Création de l'application FastAPI
app = FastAPI(
title="Bot Detector Dashboard API",
description="API pour le dashboard de visualisation des détections Bot Detector",
version="1.0.0",
lifespan=lifespan
)
# Configuration CORS
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Enregistrement des routes
app.include_router(metrics.router)
app.include_router(detections.router)
app.include_router(variability.router)
app.include_router(attributes.router)
app.include_router(analysis.router)
app.include_router(entities.router)
app.include_router(incidents.router)
app.include_router(audit.router)
app.include_router(reputation.router)
app.include_router(fingerprints.router)
app.include_router(bruteforce.router)
app.include_router(tcp_spoofing.router)
app.include_router(header_fingerprint.router)
app.include_router(heatmap.router)
app.include_router(botnets.router)
app.include_router(rotation.router)
app.include_router(ml_features.router)
app.include_router(investigation_summary.router)
# Route pour servir le frontend
@app.get("/")
async def serve_frontend():
"""Sert l'application React"""
frontend_path = os.path.join(os.path.dirname(__file__), "..", "frontend", "dist", "index.html")
if os.path.exists(frontend_path):
return FileResponse(frontend_path)
return {"message": "Dashboard API - Frontend non construit. Voir /docs pour l'API."}
# Servir les assets statiques
assets_path = os.path.join(os.path.dirname(__file__), "..", "frontend", "dist", "assets")
if os.path.exists(assets_path):
app.mount("/assets", StaticFiles(directory=assets_path), name="assets")
# Health check
@app.get("/health")
async def health_check():
"""Endpoint de santé pour le health check Docker"""
try:
db.connect().ping()
return {"status": "healthy", "clickhouse": "connected"}
except Exception as e:
return {"status": "unhealthy", "clickhouse": "disconnected", "error": str(e)}
# Route catch-all pour le routing SPA (React Router) - DOIT ÊTRE EN DERNIER
# Sauf pour /api/* qui doit être géré par les routers
@app.get("/{full_path:path}")
async def serve_spa(full_path: str):
"""Redirige toutes les routes vers index.html pour le routing React"""
# Ne pas intercepter les routes API
if full_path.startswith("api/"):
raise HTTPException(status_code=404, detail="API endpoint not found")
frontend_path = os.path.join(os.path.dirname(__file__), "..", "frontend", "dist", "index.html")
if os.path.exists(frontend_path):
return FileResponse(frontend_path)
return {"message": "Dashboard API - Frontend non construit"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"main:app",
host=settings.API_HOST,
port=settings.API_PORT,
reload=True
)