4.0 KiB
4.0 KiB
Traffic Viewer - JSON Event Format
The traffic viewer is now fully integrated and supports TCP, HTTP, and UDP protocols. To enable structured event display, the NFProxy C++ binary (backend/binsrc/nfproxy.cpp) should emit JSON lines to stdout with the following format:
JSON Event Schema
{
"ts": 1701964234567,
"direction": "in",
"src_ip": "192.168.1.100",
"src_port": 54321,
"dst_ip": "10.0.0.5",
"dst_port": 443,
"proto": "tcp",
"size": 1420,
"verdict": "accept",
"filter": "filter_sanitize",
"sample_hex": "474554202f20485454502f312e310d0a486f73743a206578616d706c652e636f6d..."
}
Fields
ts(required): Unix timestamp in millisecondsdirection:"in"(client→server) or"out"(server→client)src_ip,dst_ip: Source and destination IP addressessrc_port,dst_port: Source and destination portsproto: Protocol name (e.g.,"tcp","udp")size: Packet/payload size in bytesverdict(required):"accept","drop","reject", or"edited"filter: Name of the Python filter that processed this packetsample_hex: Hex-encoded sample of payload (first 64-128 bytes recommended)
Implementation Notes
-
Backward Compatibility: The parser in
firegex.py::_stream_handleronly processes lines starting with{. Non-JSON output (logs, ACK messages) continues to work as before. -
Performance: Emit JSON only when needed. Consider an env flag:
bool emit_traffic_json = getenv("FIREGEX_TRAFFIC_JSON") != nullptr; if (emit_traffic_json) { std::cout << json_event << std::endl; } -
Sample Code (C++ with nlohmann/json or similar):
#include <nlohmann/json.hpp> using json = nlohmann::json; void emit_traffic_event(const PacketInfo& pkt, const char* verdict, const char* filter_name) { json event = { {"ts", current_timestamp_ms()}, {"direction", pkt.is_inbound ? "in" : "out"}, {"src_ip", pkt.src_addr}, {"src_port", pkt.src_port}, {"dst_ip", pkt.dst_addr}, {"dst_port", pkt.dst_port}, {"proto", pkt.protocol}, {"size", pkt.payload_len}, {"verdict", verdict}, {"filter", filter_name}, {"sample_hex", hex_encode(pkt.payload, std::min(64, pkt.payload_len))} }; std::cout << event.dump() << std::endl; }
Testing Without Binary Changes
The viewer works immediately—it will display "No traffic events yet" until the binary is updated. You can manually test the Socket.IO flow by emitting mock events from Python:
# In backend shell or script
import asyncio
import json
from utils import socketio
async def emit_test_event():
event = {
"ts": int(time.time() * 1000),
"direction": "in",
"src_ip": "192.168.1.50",
"src_port": 12345,
"dst_ip": "10.0.0.1",
"dst_port": 80,
"proto": "tcp",
"size": 512,
"verdict": "accept",
"filter": "test_filter"
}
await socketio.emit("nfproxy-traffic-YOUR_SERVICE_ID", event, room="nfproxy-traffic-YOUR_SERVICE_ID")
Current Features
✅ Backend:
- Ring buffer stores last 500 events per service
- REST endpoint:
GET /api/nfproxy/services/{id}/traffic?limit=500 - REST endpoint:
POST /api/nfproxy/services/{id}/traffic/clear - Socket.IO channels:
nfproxy-traffic-{service_id}for live events,nfproxy-traffic-historyon join
✅ Frontend:
- Live table view at
/nfproxy/{service_id}/traffic - Client-side text filter (searches IP, verdict, filter name, proto)
- Click row to view full event details + hex payload
- Auto-scroll, clear history button
- Accessible via new button (double-arrow icon) in ServiceDetails page
Next Steps
- Update
backend/binsrc/nfproxy.cppto emit JSON events as shown above - Rebuild the C++ binary
- Start a service and generate traffic—viewer will populate in real-time
- Optionally add more filters (by verdict, time range) or export to PCAP