A real-time, rule-based Intrusion Detection System written in Python. It inspects network traffic packet-by-packet, detects common attack patterns, persists alerts to SQLite, and streams everything to a live web dashboard.
Works two ways:
- Live mode — sniffs a real network interface with Scapy (needs root).
- Simulation mode — a built-in traffic generator produces realistic benign traffic interleaved with scripted attacks, so you can run the full system and dashboard on any machine, no root required.
Live demo — the dashboard detecting attacks in real time:
| Detector | What it catches | Severity |
|---|---|---|
| Port scan | One source probing many distinct ports in a short window | HIGH |
| Brute force | Repeated connection attempts to an auth port (SSH, RDP, …) | HIGH |
| Traffic spike | Volumetric flood from a single source (possible DoS) | MEDIUM |
| SYN flood | Many half-open (SYN-only) TCP connections | CRITICAL |
- ⚡ Real-time detection with per-source sliding-window analysis
- 🗄️ SQLite persistence — every alert logged with timestamp, type, severity, source/target
- 📊 Live Flask dashboard — throughput chart, alert feed, severity tiles (auto-refresh, zero external JS libraries)
- 🔁 Alert de-duplication with a configurable cooldown so one attack doesn't flood the feed
- 🎛️ Fully configurable thresholds in a single
config.py - 🧪 Simulation mode for safe, reproducible demos
┌──────────────┐ ┌──────────────────┐
live traffic → │ LiveCapture │ │ TrafficSimulator │ ← synthetic
(Scapy) │ (Scapy) │ │ (benign+attacks)│
└──────┬───────┘ └────────┬─────────┘
│ PacketMeta │
└────────────┬─────────────┘
▼
┌─────────────────────┐
│ DetectionEngine │ 4 sliding-window detectors
│ (port scan, brute │
│ force, spike, SYN) │
└──────────┬───────────┘
│ Alert
┌──────────▼───────────┐
│ SQLite Database │
└──────────┬───────────┘
│ JSON API
┌──────────▼───────────┐
│ Flask Dashboard │
└───────────────────────┘
A normalized PacketMeta object decouples the detectors from Scapy, so the
exact same detection code serves both live capture and the simulator.
# 1. Install dependencies
pip install -r requirements.txt
# 2. Run in simulation mode (no root needed) — opens the dashboard automatically
python run.py --mode sim
# 3. Open the dashboard (if it didn't auto-open)
# http://127.0.0.1:5000# Requires root/administrator privileges to sniff the interface
sudo python run.py --mode live --iface eth0python run.py --mode sim --speed 3 # faster simulation for a quick demo
python run.py --mode sim --no-dashboard # headless: console alerts only
python run.py --mode sim --port 8080 # custom dashboard port
python run.py --help # all optionsAll thresholds live in ids/config.py. For example:
port_scan_threshold: int = 15 # distinct ports…
port_scan_window: float = 5.0 # …within this many seconds
brute_force_threshold: int = 10 # connection attempts…
brute_force_window: float = 10.0 # …within this many secondsTune these to your environment's normal traffic profile to balance sensitivity against false positives.
network-ids/
├── run.py # CLI entry point
├── requirements.txt
├── ids/
│ ├── config.py # detection thresholds & settings
│ ├── database.py # SQLite persistence (thread-safe)
│ ├── detectors.py # the 4 sliding-window detectors
│ ├── capture.py # live packet capture (Scapy)
│ ├── simulator.py # synthetic traffic + attack generator
│ └── engine.py # orchestrates source → detectors → DB
├── dashboard/
│ ├── app.py # Flask app + JSON API
│ └── templates/
│ └── index.html # live single-page dashboard
└── tests/
└── test_detectors.py # deterministic detection-rule tests
Each detector keeps a small sliding window of recent activity per source IP and raises an alert when a threshold is crossed:
- Port scan — counts distinct destination ports per source. Many ports in a few seconds = reconnaissance.
- Brute force — counts SYN attempts from one source to the same auth port.
- Traffic spike — counts total packets per source; a sudden volume from one host suggests a (D)DoS.
- SYN flood — counts pure SYN packets (SYN set, ACK unset), i.e. half-open connections that never complete the TCP handshake.
The design is intentionally explainable — every alert states exactly why it fired, which matters for a real security audit.
The detection rules are covered by a deterministic test suite — packets are constructed with controlled timestamps, so the tests run in milliseconds without touching the network.
pip install -r requirements-dev.txt
pytest tests/ -vBeyond checking that each detector fires, the suite pins down the behaviour that actually matters in production — that it stays quiet when it should:
| Guarantee | Why it matters |
|---|---|
| Hammering a single port is not flagged as a port scan | Reconnaissance means many distinct ports |
Completed handshakes (SYN-ACK) are not flagged as a SYN flood |
Only half-open connections indicate a flood |
| Load spread across many hosts is not flagged as a spike | Counting is per source, not global |
| Attempts spread over time fall out of the sliding window | Prevents slow-scan false positives |
| A busy, ordinary network raises zero alerts | The false-positive guard |
| One ongoing attack produces one alert, not hundreds | Cooldown keeps the feed readable |
- GeoIP enrichment of source addresses
- Email / Slack / webhook alerting
- Signature-based detection (Suricata-style rules)
- Anomaly detection with a baseline traffic model (ML)
This tool is for educational purposes and monitoring networks you own or are authorized to test. Only capture traffic you have permission to inspect.
MIT

