Features: - Standalone agent server (intercept_agent.py) for remote sensor nodes - Controller API blueprint for agent management and data aggregation - Push mechanism for agents to send data to controller - Pull mechanism for controller to proxy requests to agents - Multi-agent SSE stream for combined data view - Agent management page at /controller/manage - Agent selector dropdown in main UI - GPS integration for location tagging - API key authentication for secure agent communication - Integration with Intercept's dependency checking system New files: - intercept_agent.py: Remote agent HTTP server - intercept_agent.cfg: Agent configuration template - routes/controller.py: Controller API endpoints - utils/agent_client.py: HTTP client for agents - utils/trilateration.py: Multi-agent position calculation - static/js/core/agents.js: Frontend agent management - templates/agents.html: Agent management page - docs/DISTRIBUTED_AGENTS.md: System documentation Modified: - app.py: Register controller blueprint - utils/database.py: Add agents and push_payloads tables - templates/index.html: Add agent selector section
12 KiB
Intercept Distributed Agent System
This document describes the distributed agent architecture that allows multiple remote sensor nodes to feed data into a central Intercept controller.
Overview
The agent system uses a hub-and-spoke architecture where:
- Controller: The main Intercept instance that aggregates data from multiple agents
- Agents: Lightweight sensor nodes running on remote devices with SDR hardware
┌─────────────────────────────────┐
│ INTERCEPT CONTROLLER │
│ (port 5050) │
│ │
│ - Web UI with agent selector │
│ - /controller/manage page │
│ - Multi-agent SSE stream │
│ - Push data storage │
└─────────────────────────────────┘
▲ ▲ ▲
│ │ │
Push/Pull │ │ │ Push/Pull
│ │ │
┌────┴───┐ ┌────┴───┐ ┌────┴───┐
│ Agent │ │ Agent │ │ Agent │
│ :8020 │ │ :8020 │ │ :8020 │
│ │ │ │ │ │
│[RTL-SDR] │[HackRF] │ │[LimeSDR]
└────────┘ └────────┘ └────────┘
Quick Start
1. Start the Controller
The controller is the main Intercept application:
cd intercept
python app.py
# Runs on http://localhost:5050
2. Configure an Agent
Create a config file on the remote machine:
# intercept_agent.cfg
[agent]
name = sensor-node-1
port = 8020
allowed_ips =
allow_cors = false
[controller]
url = http://192.168.1.100:5050
api_key = your-secret-key-here
push_enabled = true
push_interval = 5
[modes]
pager = true
sensor = true
adsb = true
wifi = true
bluetooth = true
3. Start the Agent
python intercept_agent.py --config intercept_agent.cfg
# Runs on http://localhost:8020
4. Register the Agent
Go to http://controller:5050/controller/manage and add the agent:
- Name: sensor-node-1 (must match config)
- Base URL: http://agent-ip:8020
- API Key: your-secret-key-here (must match config)
Architecture
Data Flow
The system supports two data flow patterns:
Push (Agent → Controller)
Agents automatically push captured data to the controller:
- Agent captures data (e.g., rtl_433 sensor readings)
- Data is queued in the
ControllerPushClient - Agent POSTs to
http://controller/controller/api/ingest - Controller validates API key and stores in
push_payloadstable - Data is available via SSE stream at
/controller/stream/all
Agent Controller
│ │
│ POST /controller/api/ingest │
│ Header: X-API-Key: secret │
│ Body: {agent_name, scan_type, │
│ payload, timestamp} │
│ ──────────────────────────────► │
│ │
│ 200 OK │
│ ◄────────────────────────────── │
Pull (Controller → Agent)
The controller can also pull data on-demand:
- User selects agent in UI dropdown
- User clicks "Start Listening"
- Controller proxies request to agent
- Agent starts the mode and returns status
- Controller polls agent for data
Browser Controller Agent
│ │ │
│ POST /controller/ │ │
│ agents/1/sensor/start│ │
│ ─────────────────────► │ │
│ │ POST /sensor/start │
│ │ ────────────────────────► │
│ │ │
│ │ {status: started} │
│ │ ◄──────────────────────── │
│ {status: success} │ │
│ ◄───────────────────── │ │
Authentication
API key authentication secures the push mechanism:
- Agent config specifies
api_keyin[controller]section - Agent sends
X-API-Keyheader with each push request - Controller looks up agent by name in database
- Controller compares provided key with stored key
- Mismatched keys return 401 Unauthorized
Database Schema
Two tables support the agent system:
-- Registered agents
CREATE TABLE agents (
id INTEGER PRIMARY KEY,
name TEXT UNIQUE NOT NULL,
base_url TEXT NOT NULL,
api_key TEXT,
capabilities TEXT, -- JSON: {pager: true, sensor: true, ...}
interfaces TEXT, -- JSON: {devices: [...]}
gps_coords TEXT, -- JSON: {lat, lon}
last_seen TIMESTAMP,
is_active BOOLEAN
);
-- Pushed data from agents
CREATE TABLE push_payloads (
id INTEGER PRIMARY KEY,
agent_id INTEGER,
scan_type TEXT, -- pager, sensor, adsb, wifi, etc.
payload TEXT, -- JSON data
received_at TIMESTAMP,
FOREIGN KEY (agent_id) REFERENCES agents(id)
);
Agent REST API
The agent exposes these endpoints:
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check (returns {status: "healthy"}) |
/capabilities |
GET | Available modes, devices, GPS status |
/status |
GET | Running modes, uptime, push status |
/{mode}/start |
POST | Start a mode (pager, sensor, adsb, etc.) |
/{mode}/stop |
POST | Stop a mode |
/{mode}/status |
GET | Mode-specific status |
/{mode}/data |
GET | Current data snapshot |
Example: Start Sensor Mode
curl -X POST http://agent:8020/sensor/start \
-H "Content-Type: application/json" \
-d '{"frequency": 433.92, "device_index": 0}'
Response:
{
"status": "started",
"mode": "sensor",
"command": "/usr/local/bin/rtl_433 -d 0 -f 433.92M -F json",
"gps_enabled": true
}
Example: Get Capabilities
curl http://agent:8020/capabilities
Response:
{
"modes": {
"pager": true,
"sensor": true,
"adsb": true,
"wifi": true,
"bluetooth": true
},
"devices": [
{
"index": 0,
"name": "RTLSDRBlog, Blog V4",
"sdr_type": "rtlsdr",
"capabilities": {
"freq_min_mhz": 24.0,
"freq_max_mhz": 1766.0
}
}
],
"gps": true,
"gps_position": {
"lat": 33.543,
"lon": -82.194,
"altitude": 70.0
},
"tool_details": {
"sensor": {
"name": "433MHz Sensors",
"ready": true,
"tools": {
"rtl_433": {"installed": true, "required": true}
}
}
}
}
Controller API
Agent Management
| Endpoint | Method | Description |
|---|---|---|
/controller/agents |
GET | List all agents |
/controller/agents |
POST | Register new agent |
/controller/agents/{id} |
GET | Get agent details |
/controller/agents/{id} |
DELETE | Remove agent |
/controller/agents/{id}?refresh=true |
GET | Refresh agent capabilities |
Proxy Operations
| Endpoint | Method | Description |
|---|---|---|
/controller/agents/{id}/{mode}/start |
POST | Start mode on agent |
/controller/agents/{id}/{mode}/stop |
POST | Stop mode on agent |
/controller/agents/{id}/{mode}/data |
GET | Get data from agent |
Push Ingestion
| Endpoint | Method | Description |
|---|---|---|
/controller/api/ingest |
POST | Receive pushed data from agents |
SSE Streams
| Endpoint | Description |
|---|---|
/controller/stream/all |
Combined stream from all agents |
Frontend Integration
Agent Selector
The main UI includes an agent dropdown in supported modes:
<select id="agentSelect">
<option value="local">Local (This Device)</option>
<option value="1">● sensor-node-1</option>
</select>
When an agent is selected:
- Device list updates to show agent's SDR devices
- Start/Stop commands route through controller proxy
- Data displays with agent name badge
Multi-Agent Mode
Enable "Show All Agents" checkbox to:
- Connect to
/controller/stream/allSSE - Display combined data from all agents
- Show agent name badge on each data item
GPS Integration
Agents can include GPS coordinates with captured data:
- Agent connects to local
gpsddaemon - GPS position included in
/capabilitiesand/status - Each data snapshot includes
agent_gpsfield - Controller can use GPS for trilateration (multiple agents)
Configuration Reference
Agent Config (intercept_agent.cfg)
[agent]
# Agent identity (must be unique across all agents)
name = sensor-node-1
# Port to listen on
port = 8020
# Restrict connections to specific IPs (comma-separated, empty = all)
allowed_ips =
# Enable CORS headers
allow_cors = false
[controller]
# Controller URL (required for push)
url = http://192.168.1.100:5050
# API key for authentication
api_key = your-secret-key
# Enable automatic data push
push_enabled = true
# Push interval in seconds
push_interval = 5
[modes]
# Enable/disable specific modes
pager = true
sensor = true
adsb = true
ais = true
wifi = true
bluetooth = true
Troubleshooting
Agent not appearing in controller
- Check agent is running:
curl http://agent:8020/health - Verify agent is registered in
/controller/manage - Check API key matches between agent config and controller registration
- Check network connectivity between agent and controller
Push data not arriving
- Check agent status:
curl http://agent:8020/status- Verify
push_enabled: trueandpush_connected: true
- Verify
- Check controller logs for authentication errors
- Verify API key matches
- Check if mode is running and producing data
Mode won't start on agent
- Check capabilities:
curl http://agent:8020/capabilities - Verify required tools are installed (check
tool_details) - Check if SDR device is available (not in use by another process)
No data from sensor mode
- Verify rtl_433 is running:
ps aux | grep rtl_433 - Check sensor status:
curl http://agent:8020/sensor/status - Note: Empty data is normal if no 433MHz devices are transmitting nearby
Security Considerations
- API Keys: Always use strong, unique API keys for each agent
- Network: Consider running agents on a private network or VPN
- HTTPS: For production, use HTTPS between agents and controller
- Firewall: Restrict agent ports to controller IP only
- allowed_ips: Use this config option to restrict agent connections
Files
| File | Description |
|---|---|
intercept_agent.py |
Standalone agent server |
intercept_agent.cfg |
Agent configuration template |
routes/controller.py |
Controller API blueprint |
utils/agent_client.py |
HTTP client for agents |
utils/database.py |
Agent CRUD operations |
static/js/core/agents.js |
Frontend agent management |
templates/agents.html |
Agent management page |