Skip to content

SpoonerBoy/Proxy-Traffic-Visualizer

Repository files navigation

Proxy Traffic Visualizer

A real-time security and traffic dashboard for Nginx Proxy Manager. Reads NPM access logs, geolocates source IPs, classifies threats, and streams everything live to a modern dark-mode dashboard.

Dashboard Preview

Features

  • Live Traffic Feed — scrolling table of every request with IP, method, status code, path, and threat level
  • Security Alerts — dedicated panel that isolates high-threat requests (XSS, SQLi, path traversal, Log4Shell, .env probes, and more)
  • Geo Intelligence Map — world map with glowing dots plotted from real IP geolocation data
  • 13 built-in threat rules covering the most common attack patterns
  • WebSocket streaming — sub-second latency from log write to dashboard update
  • Docker-first — single docker compose up -d --build deployment

Tech Stack

Layer Technology
Backend Python 3.12, FastAPI, Uvicorn, aiofiles
Geolocation MaxMind GeoLite2-City (free)
Frontend React 19, Vite, Tailwind CSS v4
Map d3-geo + world-atlas
Transport WebSockets
Serving nginx (Alpine)
Deployment Docker Compose

Quick Start

Prerequisites

1. Clone the repo

git clone https://github.com/SpoonerBoy/Proxy-Traffic-Visualizer.git
cd Proxy-Traffic-Visualizer

2. Configure environment

cp .env.example .env

Edit .env and set:

Variable Description Example
NPM_LOG_DIR Host path to NPM logs directory /home/pi/nginx-proxy-manager/data/logs
NPM_LOG_FILE Active access log filename default-host_access.log
GEOIP_DB_PATH Host path to GeoLite2-City.mmdb /opt/geoip/GeoLite2-City.mmdb
FRONTEND_PORT Dashboard port 3002
DEMO_MODE Use synthetic traffic (no NPM needed) false

Finding your active log file:

ls -lht /path/to/nginx-proxy-manager/data/logs/

The file with the most recent timestamp and non-zero size is your active log.

3. Build and run

docker compose up -d --build

Open http://<your-host>:3002 — the dashboard connects automatically.

4. Verify

# Check both containers are running
docker compose ps

# Stream backend logs
docker logs proxy-visualizer-backend -f

You should see:

GeoIP database loaded from '/geoip/GeoLite2-City.mmdb'.
Ingest loop started (demo_mode=False).
Tailing log file '/npm-logs/default-host_access.log'.
Application startup complete.

Demo Mode

To run without a real NPM instance (useful for testing):

DEMO_MODE=true

This generates synthetic traffic with realistic IPs, paths, and ~15% threat events.

Threat Detection Rules

Rule Pattern Level
env_file_leak /.env, /.env.backup etc. HIGH
git_exposure /.git/, /.svn/ HIGH
wp_admin_probe /wp-admin, /wp-login.php HIGH
directory_traversal ../, %2f.. HIGH
sql_injection UNION SELECT, OR 1=1 HIGH
xss_probe <script>, javascript: HIGH
log4shell ${jndi:ldap://} HIGH
shell_injection ;, |, `, && in URL HIGH
aws_metadata 169.254.169.254 HIGH
config_file_probe phpinfo.php, web.config HIGH
remote_file_include ?file=http:// HIGH
common_shell_backdoor c99.php, webshell HIGH
admin_panel_probe /admin, /phpmyadmin MEDIUM
scanner_ua Nikto, sqlmap, Nmap UA MEDIUM
backup_file_probe .bak, .old, .swp MEDIUM
excessive_404 HTTP 404 responses MEDIUM

API Reference

Endpoint Method Description
/ GET Health check and server stats
/api/history GET Last N buffered log entries
/ws/traffic WebSocket Live stream of enriched log events

WebSocket message schema

{
  "id": "monotonic-ns-timestamp",
  "ip": "185.220.101.47",
  "timestamp": "2026-05-23T19:15:30+00:00",
  "method": "GET",
  "path": "/.env.backup",
  "status": 404,
  "bytes_sent": 150,
  "user_agent": "curl/7.88",
  "lat": 52.6171,
  "lon": 13.1207,
  "country": "DE",
  "country_name": "Germany",
  "city": "Brandenburg an der Havel",
  "threat_level": "high",
  "matched_rule": "env_file_leak",
  "threat_description": "Attempt to read .env or environment config",
  "tags": ["env_file_leak"]
}

Project Structure

Proxy-Traffic-Visualizer/
├── backend/
│   ├── config.py           # Pydantic-Settings configuration
│   ├── log_parser.py       # Nginx combined-log-format regex parser
│   ├── geoip_lookup.py     # MaxMind GeoIP2 wrapper
│   ├── threat_analyzer.py  # Rule-based security classification engine
│   ├── log_reader.py       # Async file tailer + demo traffic generator
│   └── main.py             # FastAPI app, WebSocket fan-out, REST endpoints
├── frontend/
│   └── src/
│       ├── components/
│       │   ├── Header.jsx          # Stats bar + connection indicator
│       │   ├── TrafficFeed.jsx     # Live scrolling request table
│       │   ├── SecurityAlerts.jsx  # High-threat event panel
│       │   ├── GeoMap.jsx          # d3-geo world map with live dots
│       │   └── StatusBadge.jsx     # Threat / method / status badges
│       ├── hooks/
│       │   └── useTrafficStream.js # WebSocket client + state management
│       └── App.jsx                 # Root layout
├── Dockerfile.backend
├── Dockerfile.frontend
├── docker-compose.yml
├── nginx.conf              # nginx reverse proxy config (serves + proxies /ws/)
├── requirements.txt
└── .env.example

Updating

After pulling new code, rebuild both images:

git pull
docker compose up -d --build

License

MIT

About

Real-time security and traffic dashboard for Nginx Proxy Manager (and any standard Nginx deployment).

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors