Real-Time Network Intrusion Detection System — a production-grade Deep Packet Inspection pipeline in C++, a live SOC dashboard in React, and a Streamlit DPI analyzer — all deployed.
| Service | URL | What it does |
|---|---|---|
| Dashboard | netsentry-two.vercel.app | Live SOC — world threat map, real-time alert feed, attack charts |
| DPI Analyzer | netsentry-dpi-adi.streamlit.app | Paste any payload → classified with entropy analysis |
| API Health | netsentry-api.onrender.com/api/health | WebSocket + REST API status |
The Render free tier sleeps after 15 minutes of inactivity. First request after sleep takes ~30 seconds to wake up — subsequent requests are instant.
NetSentry inspects network packets at wire speed, classifies them with signature matching + entropy analysis, and streams every threat to a global threat dashboard in real time.
- Aho-Corasick multi-pattern automaton matches thousands of Snort signatures in a single O(n) pass over packet payloads
- Shannon entropy profiling over 128-byte sliding windows detects encrypted C2 beaconing that evades signature-based IDS
- MATLAB
wavedec(H, 4, "db4")wavelet decomposition reveals periodic high-entropy bursts invisible to FFT — the core research contribution - Bloom filter IP reputation pre-filter rejects 99.9% of benign IPs in ~5 ns before the full rule engine runs
- Lock-free SPSC ring buffer transfers packets from capture to dispatcher with zero locks, zero allocation
- WebSocket fan-out streams alerts to all connected dashboard clients in <5 ms
Text version of the architecture (click to expand)
Network / NIC
│
▼ AF_XDP / libpcap — zero-copy capture
┌─────────────────────────────────────────────┐
│ C++ DPI Engine │
│ ├─ Lock-free SPSC ring buffer │
│ ├─ 5-tuple dispatcher → N worker threads │
│ ├─ Aho-Corasick pattern matcher │
│ ├─ Trie protocol parser │
│ ├─ Shannon entropy scorer │
│ ├─ Bloom filter IP reputation │
│ └─ Rule engine → {BLOCK, ALERT, LOG} │
└──────────────┬──────────────────────────────┘
│ JSON lines → stdout / Unix socket
▼
┌─────────────────────────────────────────────┐
│ Node.js API · Port 3001 │
│ ├─ WebSocket server (ws.Server) │
│ ├─ REST API GET /api/alerts /stats │
│ ├─ POST /api/classify (Streamlit demo) │
│ └─ In-memory alert store (ring, 1000 max) │
└──────┬──────────────────────┬───────────────┘
│ WebSocket │ REST
▼ ▼
┌─────────────────┐ ┌──────────────────────┐
│ React Dashboard│ │ Streamlit Analyzer │
│ ├─ Leaflet map │ │ ├─ Payload input │
│ ├─ Alert feed │ │ ├─ Entropy gauge │
│ └─ Recharts │ │ └─ Byte freq chart │
└─────────────────┘ └──────────────────────┘
| Structure | Used in | Complexity | Why |
|---|---|---|---|
| Aho-Corasick automaton | DPI core — payload pattern match | O(n+m) build, O(n) search | Match thousands of Snort rules in a single pass over payload |
| Deterministic Trie | L4–L7 protocol parser | O(k) per lookup | Prefix-based protocol ID, no backtracking |
| Cuckoo hash (per-thread) | Flow state table (5-tuple key) | O(1) avg lookup | Zero cross-thread locking — each worker owns its table |
| Bloom filter | IP reputation pre-filter | O(k) · 4 MB | Rejects 99.9% of benign IPs in ~5 ns |
| Lock-free SPSC ring | Capture → dispatcher queue | O(1) wait-free | Zero allocation, zero CAS on the hot path |
| Michael-Scott MPSC queue | Worker threads → alert relay | O(1) lock-free | Multiple producers, single consumer, guaranteed progress |
Traditional signature-based DPI (Snort, Suricata) is blind to encrypted command-and-control traffic. NetSentry adds a novel detection layer:
- Shannon entropy
H(X) = −Σ p(x) log₂(p(x))computed over 128-byte payload windows per flow - The resulting entropy time-series is passed to MATLAB
wavedec(H, 4, "db4")— a 4-level Daubechies-4 Discrete Wavelet Transform - Level-1 and level-2 detail coefficients reveal periodic high-entropy spikes — the signature of C2 beaconing
- The discriminator is timing regularity, not entropy alone — benign TLS is also high-entropy, but only a beacon calls home on a regular cadence (low coefficient of variation)
Method: A flow is flagged as C2 only when it is both encrypted (mean entropy ≥ 6.5 bits) and periodic (inter-arrival regularity ≥ 0.55). This catches Cobalt Strike / Sliver-style beacons that bypass signature-based tools.
📊 See BENCHMARKS.md for detection accuracy, latency percentiles, and the full Snort comparison.
🔬 The full reproducible experiment harness lives in research/ — run python research/selftest.py to validate the detector, then point it at real Stratosphere IPS captures.
git clone https://github.com/gitadi2/netsentry.git
cd netsentry
chmod +x start.sh && ./start.shOpen http://localhost:5173 — dashboard is live with the built-in simulator.
# Terminal 1 — API
cd netsentry\api
npm install
npm start
# Terminal 2 — Dashboard
cd netsentry\frontend
npm install
npm run dev
# Terminal 3 — Streamlit Analyzer
cd netsentry\streamlit
pip install -r requirements.txt
python -m streamlit run app.pycd cpp
mkdir build && cd build
# macOS / dev mode (no libpcap)
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j4
./netsentry --sim
# Linux — live packet capture (requires libpcap + root)
sudo apt install libpcap-dev
cmake .. -DCMAKE_BUILD_TYPE=Release -DWITH_PCAP=ON
make -j$(nproc)
sudo ./netsentry --iface eth0Once built, the Node API auto-detects the binary and pipes its JSON output instead of the JS simulator:
[NetSentry] C++ engine connected at /path/to/cpp/build/netsentry
The C++ core is covered by a 31-test GoogleTest suite spanning the Aho-Corasick matcher, Bloom filter, entropy function, and the classify rule engine.
cd cpp
cmake -B build -DBUILD_TESTS=ON
cmake --build build
./build/netsentry_tests # Windows: .\build\netsentry_tests.exeGoogleTest is fetched automatically via CMake FetchContent — no manual install needed.
# Start the API locally, then in another terminal:
pip install aiohttp numpy matplotlib requests
python benchmark/detection_test.py # detection accuracy vs Snort
python benchmark/load_test.py # latency / throughput percentiles
python benchmark/plot_latency.py # render the latency chartFull results, methodology, and the Snort comparison are in BENCHMARKS.md.
docker compose up --build- Dashboard →
http://localhost:5173 - API →
http://localhost:3001 - Streamlit →
http://localhost:8501
- New → Web Service → connect GitHub repo
- Root Directory:
api - Build:
npm install - Start:
node server.js - Instance: Free
- New Project → import repo
- Root Directory:
frontend - Framework Preset: Vite (auto-detected)
- Environment variables:
VITE_API_URL=https://netsentry-api.onrender.comVITE_WS_URL=wss://netsentry-api.onrender.com
- New app → repo →
streamlit/app.py - Secrets:
NETSENTRY_API = "https://netsentry-api.onrender.com" NETSENTRY_DASH = "https://netsentry-two.vercel.app"
Every push to main auto-redeploys all three services.
netsentry/
├── .github/
│ └── workflows/
│ └── ci.yml ← GitHub Actions — build, lint, health check
├── cpp/
│ ├── src/
│ │ ├── netsentry.h ← AhoCorasick · BloomFilter · entropy · FlowTable
│ │ └── main.cpp ← simulator + libpcap capture + JSON stdout
│ ├── tests/
│ │ └── test_netsentry.cpp ← GoogleTest suite (31 tests)
│ └── CMakeLists.txt ← engine build + BUILD_TESTS / COVERAGE options
├── api/
│ ├── server.js ← Express + ws + REST + built-in JS simulator
│ └── package.json
├── frontend/
│ ├── src/
│ │ ├── App.jsx ← WebSocket client, state, layout
│ │ ├── index.css ← pure black SOC theme + Leaflet overrides
│ │ └── components/
│ │ ├── ThreatMap.jsx ← Leaflet map · radar sweep · animated arcs
│ │ ├── AlertFeed.jsx ← scrollable alert list · country leaderboard
│ │ ├── StatsBar.jsx ← header · live counters
│ │ └── Charts.jsx ← alerts/s timeline · threat donut
│ └── vite.config.js
├── streamlit/
│ ├── app.py ← DPI analyzer · entropy gauge · byte freq chart
│ └── requirements.txt
├── benchmark/
│ ├── detection_test.py ← accuracy harness vs Snort baseline
│ ├── load_test.py ← latency / throughput harness
│ └── plot_latency.py ← renders the latency percentile chart
├── research/
│ ├── c2_detect.py ← entropy + db4 wavelet + IAT-regularity classifier
│ ├── selftest.py ← synthetic labeled flows → validates the detector
│ ├── run_pcap.py ← runs detection on real pcaps (Stratosphere IPS)
│ ├── plot_c2.py ← renders the beacon-vs-benign figure
│ ├── requirements.txt ← scapy · numpy · scipy · matplotlib · PyWavelets
│ └── README.md ← full reproducible experiment workflow
├── docs/
│ ├── system-design.png ← architecture diagram (this README)
│ ├── system-design.svg ← vector source for slides / print
│ ├── latency-percentiles.png
│ └── c2-detection.png ← C2 beacon vs benign timing comparison
├── Dockerfile.api
├── Dockerfile.frontend
├── Dockerfile.cpp
├── docker-compose.yml
├── start.sh ← one-command dev launcher
├── BENCHMARKS.md
└── README.md
| Layer | Technology |
|---|---|
| DPI Engine | C++17 · CMake · libpcap · std::atomic · pthread |
| Algorithms | Aho-Corasick · Shannon entropy · MATLAB db4 wavelet · FNV-1a · MurmurHash3 |
| Data Structures | Bloom filter · Trie · Cuckoo hash · SPSC/MPSC lock-free queues |
| API | Node.js 20 · Express 4 · ws (WebSocket) |
| Frontend | React 18 · Vite 5 · Leaflet · Recharts |
| Analyzer | Streamlit · Plotly · NumPy |
| Research | Python · SciPy · PyWavelets · scapy |
| Testing | GoogleTest (C++) · GitHub Actions CI |
| Infra | Docker · docker-compose · Nginx · GitHub Actions |
| Deploy | Vercel · Render · Streamlit Cloud · GitHub |
- C++ DPI core with Aho-Corasick, Bloom filter, entropy
- Node.js WebSocket API with built-in simulator fallback
- React dashboard with live Leaflet threat map
- Streamlit DPI analyzer with entropy gauge
- Docker deploy for all services
- Cloud deploy (Vercel + Render + Streamlit Cloud)
- Benchmark suite + document vs Snort
- GoogleTest unit tests for C++ core (31 tests)
- C2 detection research harness (entropy + wavelet + IAT regularity)
- Jest integration tests for the API
- Prometheus
/metricsendpoint + Grafana dashboard - JWT authentication + rate limiting on the API
- Kubernetes manifests (Deployment, Service, HPA)
- Real AF_XDP integration (currently libpcap fallback)
| Symptom | Fix |
|---|---|
| Dashboard shows RECONNECTING | Wake the Render API — visit /api/health directly, then refresh |
| Streamlit shows OFFLINE | Check the NETSENTRY_API secret on Streamlit Cloud — no trailing slash, https:// prefix |
| Map tiles don't load | Check internet — CartoDB tiles need network |
| WebSocket disconnects on Render | Render free tier sleeps after 15 min — upgrade to Starter ($7/mo) for always-on |
| C++ fails to compile | Need CMake ≥ 3.16, GCC ≥ 11, and libpcap-dev on Linux |
| Vercel build fails | Root directory must be frontend, not /frontend |
MIT — use freely for portfolio, interviews, research, or commercial projects.
ADITYA SATAPATHY

