Skip to content

Latest commit

 

History

76 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NetFlare

NetFlare

Real-time cyber-attack visualization on a 3D globe.

Python FastAPI React Vite


Overview

NetFlare pulls malicious IPs from AbuseIPDB, resolves them to coordinates with MaxMind GeoLite2, and streams them to a React client that plots each hit on an interactive globe. Global attack trends come from the Cloudflare Radar API.

Attacks are cached in SQLite and drip-fed over a WebSocket, so the globe stays live without hammering the upstream APIs.

Features

  • Live globe — attack arcs and impact points rendered with react-globe.gl
  • WebSocket stream — new events pushed to every connected client
  • Trends panel — Cloudflare Radar layer-7 timeseries, top origin and target countries
  • Event ticker — scrolling feed of recent IPs with click-to-focus on the globe
  • Threat audio — ambient severity cues driven by the current threat level
  • Persistent cache — SQLite store survives restarts; upstream APIs polled on a schedule

Demo

  • Watch demo on YouTube by Clicking Below

NetFlare Video Overview

Architecture

---
config:
  layout: elk
---
flowchart TB
    subgraph EXT["🌐 External Data Sources"]
        A1["AbuseIPDB API<br>(blacklist endpoint)<br>malicious IPs + confidence scores"]
        A2["Cloudflare Radar API<br>attack trends + traffic spikes"]
        A3["GeoLite2 DB (MaxMind)<br>local IP → lat/lon lookup"]
    end

    subgraph BE["⚙️ Backend — FastAPI"]
        B1["Scheduler (APScheduler)<br>polls APIs every 5 min"]
        B2["Ingestion Service<br>httpx async fetchers"]
        B3["ML Classifier<br>Random Forest / XGBoost<br>DDoS likelihood score"]
        B4["Geolocation Service<br>geoip2 lookup"]
        B5[("Cache / Store<br>Redis or SQLite")]
        B6["REST endpoint<br>GET /attacks"]
        B7["WebSocket endpoint<br>/ws — live event push"]
    end

    subgraph FE["🖥️ Frontend"]
        C1["Globe.gl (Three.js)<br>3D globe with arcs &amp; pulses"]
        C2["Trends Panel<br>charts from Radar data"]
        C3["WebSocket client<br>receives live events"]
    end
    A1 -- "IP list + abuse scores" --> B2
    A2 -- "attack trend data" --> B2
    B1 -- "triggers" --> B2
    B2 -- "raw IP records" --> B3
    B3 -- "high-confidence DDoS IPs" --> B4
    A3 -. "offline lookup" .-> B4
    B4 -- "(lat, lon, score, country)" --> B5
    B5 --> B6
    B5 -- "new events" --> B7
    B6 -- "initial load (JSON)" --> C1
    B7 -- "live updates" --> C3
    C3 -- "spawn arcs + ripples" --> C1
    B6 -- "trend stats" --> C2
    style EXT fill:none,stroke:#4A5568,stroke-width:2px,stroke-dasharray: 4 4,color:#2D3748
    style BE fill:none,stroke:#4A5568,stroke-width:2px,stroke-dasharray: 4 4,color:#2D3748
    style FE fill:none,stroke:#4A5568,stroke-width:2px,stroke-dasharray: 4 4,color:#2D3748
    style A1 fill:#FF6B6B,stroke:#C53030,stroke-width:2px,color:#000000
    style A2 fill:#FF8E53,stroke:#C53030,stroke-width:2px,color:#000000
    style A3 fill:#FFA8A8,stroke:#C53030,stroke-width:2px,color:#000000
    style B1 fill:#4ECDC4,stroke:#2B6CB0,stroke-width:2px,color:#000000
    style B2 fill:#45B7D1,stroke:#2B6CB0,stroke-width:2px,color:#000000
    style B3 fill:#96CEB4,stroke:#2B6CB0,stroke-width:2px,color:#000000
    style B4 fill:#82C91E,stroke:#2B6CB0,stroke-width:2px,color:#000000
    style B5 fill:#4DABF7,stroke:#2B6CB0,stroke-width:2px,color:#000000
    style B6 fill:#339AF0,stroke:#2B6CB0,stroke-width:2px,color:#000000
    style B7 fill:#74C0FC,stroke:#2B6CB0,stroke-width:2px,color:#000000
    style C1 fill:#CC5DE8,stroke:#6B46C1,stroke-width:2px,color:#000000
    style C2 fill:#B197FC,stroke:#6B46C1,stroke-width:2px,color:#000000
    style C3 fill:#DA77F2,stroke:#6B46C1,stroke-width:2px,color:#000000 

Loading
Job Interval Purpose
refresh_attack 6 hours Fetch AbuseIPDB blacklist, geolocate, store
refresh_trends 1 hour Fetch Cloudflare Radar trends
replay_random_attack 3 seconds Queue a stored attack to keep the feed live

Getting Started

Prerequisites

Server

cd server
pip install -r requirements.txt          # or: uv sync

Place GeoLite2-City.mmdb in server/data/, then create server/.env:

ABUSEIPDB_KEY=your_key_here
CLOUDFLARE_TOKEN=your_token_here
ALLOWED_ORIGINS=http://localhost:5173

Run it:

uvicorn main:app --reload

The API is live at http://localhost:8000.

Client

cd client
npm install
npm run dev

The app is live at http://localhost:5173.

To point the client at a deployed backend, create client/.env:

VITE_API_URL=https://your-server.onrender.com
VITE_WS_URL=wss://your-server.onrender.com/ws

API Reference

Method Endpoint Description
GET / Health check
GET /attacks 200 most recent attacks (lat, lng, score, country)
GET /trends Cached Cloudflare Radar trend data
GET /debug/fake Queue a synthetic event (development only)
WS /ws Live attack event stream

Configuration

Variable Side Default Description
ABUSEIPDB_KEY server required AbuseIPDB API key
CLOUDFLARE_TOKEN server required Cloudflare Radar API token
ALLOWED_ORIGINS server http://localhost:5173 Comma-separated CORS origins
PORT server 8000 Listen port
VITE_API_URL client http://localhost:8000 REST base URL
VITE_WS_URL client ws://localhost:8000/ws WebSocket URL

Deployment

The server ships with a render.yaml and a Procfile for Render — set ABUSEIPDB_KEY, CLOUDFLARE_TOKEN, and ALLOWED_ORIGINS in the dashboard.

The client is a static Vite build (npm run build) and deploys to any static host (Vercel, Netlify, Cloudflare Pages).

Note: SQLite lives on the container filesystem. On ephemeral hosts the cache resets on redeploy and repopulates on first boot.

Project Structure

NetFlare/
├── client/
│   ├── public/            # logo, icons, favicon
│   └── src/
│       ├── components/    # GlobeView, Ticker, TrendsPanel, StatusBar, Legend, BootOverlay
│       ├── hooks/         # useAttacks, useLiveEvents, useTrends
│       └── audio/         # threat-level audio cues
├── server/
│   ├── main.py            # FastAPI app, scheduler, WebSocket
│   ├── db.py              # SQLite schema, upserts, trend storage
│   ├── radar.py           # Cloudflare Radar client
│   ├── connection_manager.py
│   └── data/              # GeoLite2 DB + SQLite cache
└── render.yaml

Acknowledgements

License

MIT

About

NetFlare pulls malicious IPs from AbuseIPDB, resolves them to coordinates with MaxMind GeoLite2, and streams them to a React client that plots each hit on an interactive globe. Global attack trends come from the Cloudflare Radar API. Attacks are cached in SQLite and drip-fed over a WebSocket, so the globe stays live without hammering the upstream

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages