Home / SOHO Network Security Monitor — Real-time visibility into every LAN device's outbound connections
Is your smart TV phoning home to unexpected servers? Are your IP cameras, IoT appliances, or NAS boxes making connections you never authorised? EgressView answers these questions by passively monitoring every outbound connection from every device on your LAN, then turning that data into an investigation workflow: Graph Map and Statistics for the big picture, Connection Log and Devices for drill-down analysis — with automatic threat detection.
No new hardware. No inline traffic interception. Works via the NAT session tables of your existing Yamaha RTX and/or Cisco IOS routers. AI assistants such as AWS Kiro, Anthropic Claude, and Anysphere Cursor can query EgressView directly via the built-in MCP server — just ask in natural language.
🇯🇵 日本語版 README はこちら | 🌐 Project Page
EgressView is production-oriented for home/SOHO networks using Yamaha RTX or Cisco IOS. ASUS AP support and optional data sources are maintained as companion integrations.
Version 1.7.0 opens EgressView to the internet safely. Browser sessions now carry least-privilege roles (viewer, operator, admin) instead of every authenticated session holding full access, and the single permanent admin token is joined by scoped API identities with an expiry and independent revocation. The MCP server gained an OAuth 2.1 Resource Server mode with per-subject rate limits and its own append-only audit trail, so a remote AI assistant can be reached over the internet without sharing one static token. EGRESSVIEW_OFFLINE_MODE covers the opposite case: an air-gapped deployment where every internet-dependent feature is disabled before startup rather than attempted and timed out — the map assets are now self-hosted, so an ordinary page load makes no third-party request either.
Existing databases migrate automatically to schema v12. Startup creates and verifies a complete backup first, and stops without changing the database if free-space, checkpoint, copy, or integrity verification fails. Existing OIDC sessions are revoked once so their role is derived from a newly verified allowlist match; local sessions keep administrator access.
Modern home and SOHO networks run 20–40 devices: smart TVs, IP cameras, NAS drives, Wi-Fi speakers, printers, network switches, PCs, and smartphones. Many of these — especially IoT equipment — update infrequently and have unknown outbound behaviors. Any of them can be silently compromised and begin exfiltrating data or relaying traffic for a botnet.
EgressView answers the question most home users can't ask: what is each device on my network actually connecting to?
- Passive, zero-impact monitoring — reads the router's NAT session table over SSH; no inline tap, no throughput penalty, no latency added
- Per-device visibility — every connection tagged to the source device (vendor, model, hostname) via OUI, mDNS, SSDP, and NetBIOS
- Automatic threat detection — every connection checked in real time against Feodo Tracker, ThreatFox, URLhaus, and Spamhaus DROP
- Manual threat investigation — explicitly query AbuseIPDB, VirusTotal, or AlienVault OTX with server-side caching and rate limits (guide)
- Linux conntrack preview — collect from Linux-based routers over SSH; Docker integration verified, hardware validation pending (setup)
- Mobile monitoring view — check router health, Graph Map, Statistics, Connection Log, Devices, and Detection Log from a phone on your VPN/private network
- AI Insights start page — opens with collection health, connections, devices, destinations, threats, and previous-period comparisons. Manual analysis/chat can use bounded device inventory and ASUS node summaries through Ollama, Anthropic, OpenAI, or Amazon Bedrock, with versioned-catalog monthly tokens/estimated cost, explicit partial totals for unpriced models, and per-answer model/cost metadata. Optional event notifications add off-by-default daily/weekly reports and bounded threat-change analysis to append-only UI history or Slack (setup guide, Bedrock production setup)
- Instant Slack alerts — DM the moment any device connects to a known C2 server or malware distribution host. Threat detection and new node detection each have independent Slack and UI-history switches under the Notifications settings tab
- No hardware changes — runs on any Mac, PC, or Raspberry Pi alongside your existing Yamaha RTX or Cisco IOS routers
- Connects to Yamaha RTX and Cisco IOS routers via SSH and reads their NAT session tables every 60 seconds
- Registers up to 10 routers in any Yamaha/Cisco mix, isolates polling failures per router, and deduplicates the same connection while retaining every observing router
- [INSPECT] syslog supplement — tails the Yamaha syslog in real time to capture short-lived TCP sessions that complete within the 60-second polling gap
- dnsmasq DNS query log — tails the EC2/server-side dnsmasq log to resolve destination IPs to meaningful domain names (e.g.
example.com) per client device; forward DNS names take priority over PTR reverse lookups - [DHCPD] syslog tracking — tails Yamaha DHCP events (Allocates/Extends) for real-time IP→MAC mapping
- Threat intelligence: matches all connections against Feodo Tracker, ThreatFox, URLhaus, and Spamhaus DROP feeds (auto-refreshed hourly)
- Slack notifications: sends a DM when a threat is detected (configurable cooldown, language-aware)
- Identifies local devices using OUI vendor lookup, mDNS/Bonjour, SSDP, NetBIOS, and an Apple model dictionary (resolves down to "iPhone 15 Pro")
- Enriches each destination IP with reverse DNS, RDAP (organization name), and GeoIP (latitude/longitude/city)
- Uses Graph Map and Statistics for whole-network overview, then Connection Log and Devices for per-session and per-device drill-down
- Optionally connects to an ASUS WiFi access point (used as AP/mesh, not as a router) to get WiFi client details (band, signal strength, traffic rates, AiMesh topology)
- Keeps a connection history in SQLite (WAL mode, crash-safe; configurable retention up to 2 years)
- Inventories normal and pre-migration backups, warns when the next migration lacks disk headroom, and offers dry-run cleanup that preserves verified restore points
- Connection log: sortable/searchable table of all sessions with threat status badges; App column infers the application or service name from port number and destination hostname (APNs, FCM, AirPlay, MQTT/TLS, QUIC, iCloud, YouTube, AWS, Slack, Zoom, Tuya Smart, Gaijin/DCS, and more)
- 🔔 Detection Log — persistent history of all threat detections and new-device alerts, with per-column filter, sort, and click-to-detail popup; logged regardless of Slack configuration
- 📡 Data Sources tab — configure each data source (dnsmasq / [INSPECT] / [DHCPD]) independently from the settings UI
- 🤖 AI Agent access (MCP) — built-in Model Context Protocol server exposes 11 tools (traffic summary, threat connections, top destinations, device list, device notes, and more) to AI assistants such as AWS Kiro, Anthropic Claude, and Anysphere Cursor; supports stdio/HTTP and both the
2025-11-25and2026-07-28protocol eras - Single-page dark-themed UI with ✦ AI Insights as the leftmost start page, plus Graph Map, Statistics, Connection Log, Devices, Detection Log, and Settings
egressview-redacted-stats-first.mov
UI language: English / Japanese selectable
Graph Map and Statistics give you the network-wide overview: device/destination patterns, session trends, and noisy endpoints — all updating in real time.
Connection Log and Devices let you drill down into suspicious destinations, noisy devices, beacon candidates, notes, and device history: see the pattern, filter the time range, inspect sessions, then pivot to the device.
For component boundaries, multi-router data flow, persistence safety, and security boundaries, see the Architecture Guide. For automation and integration, see the REST API Reference.
┌─────────────────┐ SSH (NAT) ┌──────────────────────┐ WebSocket ┌──────────────────┐
│ Yamaha RTX │◄───────────►│ │◄────────────►│ Browser │
│ [INSPECT] log │ syslog/UDP │ EgressView Server │ MCP ├──────────────────┤
│ [DHCPD] log │────────────►│ (Node.js) │◄────────────►│ AI Assistant │
└─────────────────┘ │ │ stdio/HTTP │ (Kiro, Claude…) │
┌─────────────────┐ SSH (NAT) │ Pollers: │ └──────────────────┘
│ Cisco IOS │◄───────────►│ • yamaha (SSH) │
│ (supported) │ │ • cisco (SSH) │
└─────────────────┘ │ • asus (HTTP) │
┌─────────────────┐ HTTP │ • inspect-syslog │
│ ASUS WiFi AP │◄───────────►│ • dhcpd-syslog │
│ (Client list) │ │ • dnsmasq-log │
└─────────────────┘ │ │
┌─────────────────┐ tail -F │ │
│ dnsmasq │────────────►│ │
│ query log │ └──────────┬───────────┘
└─────────────────┘ │
┌───────────────────┼───────────────┐
│ │ │
┌─────┴─────┐ ┌─────────┴───┐ ┌───────┴───┐
│ Enrichment│ │ Threat Intel│ │ SQLite │
│ • dnsmasq │ │ • Feodo │ │ History │
│ • Rev DNS │ │ • ThreatFox │ │ (WAL) │
│ • RDAP │ │ • URLhaus │ └───────────┘
│ • GeoIP │ │ • DROP │
│ • OUI │ └─────────────┘
│ • mDNS │
└───────────┘
- Node.js 22+
- At least one supported NAT router: Yamaha RTX and/or Cisco IOS, with SSH access enabled
- (Optional) ASUS WiFi access point with web admin enabled (used as AP/mesh mode, not as a router)
Cisco IOS support is validated on a C841M-4X-JSEC/K9 running IOS 15.5(3)M9, including SSH, enable, NAT/ARP/NDP, verbose output, TOFU, and automatic reconnect. Multi-router behavior is automatically tested with 10 mixed fake routers and was supplementally tested by registering one physical Cisco and one physical Yamaha twice under distinct router IDs. This validates parallel collection and deduplication, not physical HA, state synchronization, or failover. Please report device-specific output differences through GitHub Issues.
EgressView exposes a Model Context Protocol (MCP) server so Claude Desktop, Claude Code, and other AI assistants can query your network data directly — just ask in natural language.
"Show me a threat summary for the last 24 hours"
"Any new devices on the network this week?"
"What is 192.168.1.50 connecting to?"
"Are there any threat connections right now?"
"Add a note to 192.168.1.97: Roomba, connects to GitHub for OTA updates"
Quick setup (Claude Desktop, macOS): add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"egressview": {
"command": "node",
"args": ["/path/to/egressview/mcp-server.js"],
"env": {
"EGRESSVIEW_URL": "http://your-server-ip:3000",
"EGRESSVIEW_TOKEN": "your-admin-token"
}
}
}
}11 tools available: get_threat_summary, get_traffic_summary, get_top_destinations, get_device_traffic, get_new_nodes, get_threat_connections, get_alerts, get_devices, query_connections, get_device_notes, set_device_note.
Use the API/admin token for EGRESSVIEW_TOKEN, not the browser login password.
See the MCP setup guide → for full instructions including remote EgressView access and HTTP mode behind Apache / nginx.
Want to explore the UI before setting up a router? Start in demo mode — it seeds 160 realistic sample connections and uses a fixed admin token:
git clone https://github.com/yo1t/egressview.git
cd egressview
npm install
DEMO_MODE=true DEMO_ADMIN_TOKEN=my-token npm startOpen http://localhost:3000 and enter my-token when prompted. All views — Graph Map, Statistics, Connection Log, Devices — are fully functional with the sample data. A DEMO badge appears in the header to distinguish it from a live installation.
Start with the smallest path that matches your network, then add sources later from Settings.
| Pattern | Use this when | What to configure first |
|---|---|---|
| Minimal: one Yamaha RTX or Cisco IOS | You want the fastest first run with no extra hardware | Router type, IP, SSH credentials, then Connect & Auto-detect |
| Multiple routers: up to 10 | You have redundant routers or multiple uplinks | Add each Yamaha/Cisco router as a separate named row |
| Optional: + ASUS AP | You also want WiFi client names, vendors, and MAC visibility | Router setup, then ASUS AP IP and admin login |
| Detailed: + dnsmasq / INSPECT / DHCPD | You want richer hostnames, short-lived TCP sessions, and live IP-to-MAC mapping | Recommended setup, then enable Data Sources |
| Notifications: + Slack | You want threat detections delivered by DM | Any setup above, then Slack notifications |
| Requirement | Setup guide | |
|---|---|---|
| ✅ | Node.js 22+ installed on your Mac/PC/Raspberry Pi | nodejs.org |
| ✅ | At least one Yamaha RTX or Cisco IOS router with SSH enabled | Yamaha guide → / Cisco guide → |
| ☐ | (Optional) ASUS WiFi AP with web admin enabled | Setup guide → |
| ☐ | (Optional) in-app AI Insights (Ollama / Anthropic / OpenAI / Amazon Bedrock) | Setup guide → |
| ☐ | (Optional) AI assistant access via MCP (AWS Kiro, Anthropic Claude, Anysphere Cursor…) | Setup guide → |
| ☐ | Choose local, private, public, or air-gapped deployment boundaries | Deployment profiles → |
| ☐ | Run with no internet access at all (EGRESSVIEW_OFFLINE_MODE=true) |
Offline mode → |
| ☐ | Install a signed portable release, then run it offline | Signed distribution → |
git clone https://github.com/yo1t/egressview.git
cd egressview
npm install
npm startOn first startup, an initial login password is shown once on an interactive terminal. Service/non-interactive startup writes it to .egressview.json.initial-login-password with mode 0600 instead of putting it in a persistent log:
══════════════════════════════════════════════════════════════
EgressView login password (initial):
KFpDqntYRfcr...
→ Log in with this password on first access
══════════════════════════════════════════════════════════════
Open http://localhost:3000 and enter the password. Each browser/device gets its own login session (30-day sliding expiry); you can review and revoke them — and change the password — in Settings → General.
Open Settings → L3/L4 and add each router as a separate row. Up to 10 enabled Yamaha RTX and Cisco IOS routers can be mixed freely.
| Field | Where to find it |
|---|---|
| Yamaha RTX IP | Your router's LAN IP (e.g. 192.168.1.1) |
| SSH username / password | The login you set up in Yamaha setup guide |
| Cisco IOS IP / username / password | The login you set up in the Cisco setup guide |
| ASUS AP IP / password | The AP's LAN IP and admin password (ASUS setup guide) |
For each Yamaha RTX, click Connect & Auto-detect after entering the IP, username, and password. EgressView checks SSH access, detects the NAT descriptor (usually 100), finds the LAN IP when available, verifies that NAT sessions can be read, and fills the recommended setting before you save.
For each Cisco IOS router, Connect & Auto-detect verifies SSH and NAT access. The LAN address is selected from the NAT inside interface. Each router is polled independently, with at most three router polls running at once, so one unavailable router does not stop the others.
Within a few seconds, devices, sessions, and statistics will start appearing in the UI.
Note: The password is stored only as a versioned scrypt record. Remove the one-time password file after the first successful login.
All API endpoints and the WebSocket connection are protected. Local login can never be disabled; Google OIDC is an optional additional login method.
| Credential | Purpose | Where |
|---|---|---|
| Login password | Browser login. Each device gets its own revocable session (30-day sliding expiry) | Printed on first startup; change it in Settings → General |
| API token | Scripts / automation (X-Admin-Token header) |
.egressview.json (adminToken); regenerate in Settings → General |
| Google OIDC | Allowed Google accounts; sessions are revocable locally | Configure in Settings → General → Authentication & Audit |
- Settings → General lists every logged-in device with last-activity time
- Revoke a single device, or log out all other devices at once
- Changing the password can optionally revoke all other sessions
# Interactive TTY only; revokes every browser session
npm run auth:reset
# Also rotate the automation credential
npm run auth:reset -- --regenerate-api-token- New passwords require at least 14 characters. Passwords use a versioned scrypt record; successful legacy logins upgrade the record.
- Failed logins are delayed 500 ms; comparisons use
crypto.timingSafeEqual - Browser sessions use Secure/HttpOnly/SameSite cookies and CSRF protection. Existing header tokens remain supported for automation.
- Login, logout, session revocation, token changes, and authenticated mutations are recorded in a pseudonymous append-only audit log.
- Google OIDC uses Authorization Code + PKCE, state, nonce, JWKS signature validation, verified email, and an email/domain allowlist.
Browser sessions use least-privilege roles derived on the server. The local
administrator is always admin; a Google account matched by an explicit email
entry is operator; and one matched only by a domain entry is read-only
viewer. Operators can add device notes but cannot run paid AI analysis,
change settings or credentials, restore backups, or manage authentication.
See the authentication and reverse-proxy guide before enabling internet access.
By default EgressView serves plain HTTP. To enable HTTPS, add to .egressview.json and restart:
"https": { "enabled": true }A self-signed certificate (.egressview-cert.pem / .egressview-key.pem, 10-year validity) is generated automatically via the openssl CLI — your browser will show a one-time warning to accept it. To use your own certificate instead:
"https": { "enabled": true, "certPath": "/path/to/cert.pem", "keyPath": "/path/to/key.pem" }HTTPS is recommended if you use the login password from multiple devices, and required for safe remote access over the internet. Use a strong unique login password and keep EgressView updated.
All settings are stored in .egressview.json (auto-generated, gitignored). You can also use environment variables:
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
HTTP server port |
POLL_INTERVAL_MS |
60000 |
ASUS polling interval (ms) |
ROUTER_IP |
192.168.1.1 |
Default ASUS router IP |
YAMAHA_IP |
— | Yamaha RTX IP address |
YAMAHA_USER |
— | Yamaha SSH username |
YAMAHA_PASS |
— | Yamaha SSH password |
YAMAHA_NAT |
100 |
NAT descriptor number |
SUBPATH |
— | Reverse proxy sub-path (e.g. /egressview) |
EGRESSVIEW_DB |
.egressview.db |
Path to the SQLite database file |
EGRESSVIEW_HISTORY_HOT_MAX |
100000 |
Maximum recent connections kept in memory; full retained history remains in SQLite |
LOG_LEVEL |
info |
Log verbosity: error / warn / info / debug |
Authenticated administrators can inspect the current RSS, heap usage, hot-cache size, limit, and persisted row count at GET /api/connections/memory. The response contains counts only, not traffic details.
- Parses
show nat descriptor address <N> detailoutput - Tracks TCP/UDP/ICMP/GRE sessions with source, destination, port, TTL
- Auto-reconnects on SSH timeout or connection loss
- TOFU (Trust On First Use) host key verification
The ASUS device is used as a WiFi access point (AP mode or AiMesh), not as a router. Yamaha RTX handles all L3 routing and NAT. The ASUS AP provides L2 client visibility:
- SHA256 challenge-response authentication
- Client list with connection type (wired/2.4G/5G/6G), RSSI, traffic rates
- AiMesh node discovery (multi-AP topology)
- Auto token refresh
- OUI database (Wireshark manuf, auto-downloaded weekly)
- mDNS/Bonjour service discovery (100+ service types)
- SSDP/UPnP device detection
- NetBIOS name resolution
- Apple model dictionary (200+ models: iPhone, iPad, Mac, Apple TV, HomePod, Apple Watch)
- Auto-investigation mode: scans unknown devices in the background
- Graph Map: Whole-network topology overview for spotting unusual device/destination clusters
- Statistics: Time-series charts and destination summaries for traffic trends
- Connection Log: Full session table with threat indicators, sortable columns, and per-column search filters (text match, regex, date range)
- Devices: Inventory view for drilling into device identity, notes, status, and history
- Connection panel: Per-device list of active internet connections with org/country info
- IPv4/IPv6 badges: Protocol detection per device via NDP cache polling
- Feodo Tracker: Emotet/Dridex/TrickBot C2 server IPs
- ThreatFox: Malware IOC (IP:port)
- URLhaus: Malware distribution URLs (with low-confidence handling for CDN domains like GitHub)
- Spamhaus DROP: Hijacked IP ranges (CIDR)
- Three confidence levels: 🚨 Detected (high) /
⚠️ Review (low — legitimate service) / ✅ Clear - Detailed threat popup with actionable guidance per confidence level
- Auto-refresh feeds every hour (configurable)
- Sends a Slack DM when a threat is detected
- Configurable per-destination cooldown (default 1 hour) to prevent notification spam
- Message language follows the UI language setting (English / Japanese)
- Test-send button in settings to verify configuration
- Requires a Slack Bot Token and your User ID (
U01XXXXXXX) — set up via Settings → General
- Admin token authentication (timing-safe comparison)
- SSRF protection (private IP ranges only)
- Socket.IO same-origin enforcement
- SSH host key fingerprint verification (TOFU)
- Config files stored with
0600permissions - No passwords sent to browser (only boolean flags)
EgressView supports up to 10 enabled L3/L4 routers in any Yamaha/Cisco combination. A connection observed by multiple routers is stored once with all observing router IDs.
- Physically validated: C841M-4X-JSEC/K9, IOS 15.5(3)M9
- Uses verbose NAT creation age and remaining TTL when available, with automatic plain-output fallback
Any model with SSH access and NAT descriptor support:
- RTX1200, RTX1210, RTX1220, RTX1300
- RTX810, RTX830
- NVR500, NVR510, NVR700W
- Automated gate: 10 mixed fake routers, 1,000 sessions each, concurrency capped at 3, failure isolation, and deterministic deduplication
- Physical supplementary smoke: one Cisco and one Yamaha each registered twice under different router IDs
- Not yet physically validated: multiple distinct units of the same vendor, HSRP/VRRP, NAT state synchronization, or real failover
Any model with the standard web admin interface, used in AP mode or AiMesh:
- RT-AX series (AX86U, AX88U, AX92U, etc.)
- RT-AC series
- ZenWiFi (AiMesh)
EgressView is dual-licensed:
- Open source license: GNU Affero General Public License v3.0
- Commercial license: available separately for proprietary or closed-source use
You may use, modify, and distribute EgressView under the AGPL-3.0. If you include EgressView or derivative works in a proprietary product, distribute it without source code, or provide a modified version as a network service, you must comply with the AGPL-3.0 source code obligations.
If you want to use EgressView in a proprietary or closed-source commercial product without releasing the corresponding source code under the AGPL-3.0, you must obtain a commercial license from the copyright holder.
EgressView — Real-time network connection visualizer
Copyright (C) 2025 Yoichi Takizawa
Source code: https://github.com/yo1t/egressview
AWS Kiro, Anthropic Claude, Anysphere Cursor, Cisco, Cisco IOS, Yamaha, ASUS, and other product names are trademarks or registered trademarks of their respective owners. EgressView is not affiliated with, endorsed by, or sponsored by those companies.
Issues and pull requests are welcome. Please open an issue first for major changes. See CONTRIBUTING.md for development setup and guidelines, ROADMAP.md for what's planned, and SECURITY.md for how to report vulnerabilities privately.





