Cybersecurity Developer Tools Jul 19, 2026 1 min de lecture

Stop Building Cyber Threat Maps from Scratch! Use Raven Instead

B
Bright Coding
Auteur
Stop Building Cyber Threat Maps from Scratch! Use Raven Instead
Advertisement

Stop Building Cyber Threat Maps from Scratch! Use Raven Instead

Your SOC dashboard looks like a PowerPoint from 2003. Your executives are asking for "that map thing" they saw in a movie. And you're about to spend three weekends wrestling with D3.js, scraping GeoJSON files, and praying that your IP geolocation API doesn't rate-limit you into oblivion.

Sound familiar?

Here's the dirty secret nobody tells you: most cyber threat maps are either bloated SaaS products that leak your data to third parties, or fragile homegrown disasters that break when someone sneezes near a coordinate. Security teams in air-gapped environments? They're stuck drawing arrows on whiteboards.

But what if I told you there's a battle-tested, fully offline cyber threat map that renders 247 countries and ~100,000 cities without a single external lookup? No API keys. No phoning home. No praying that MaxMind didn't change their database format again.

Meet Raven—the open-source threat visualization engine that Qeeqbox built, and that security engineers are quietly deploying everywhere from classified networks to startup SOCs.

Ready to stop reinventing the wheel? Let's dive deep.


What is Raven?

Raven is an advanced cyber threat map designed for environments where privacy, isolation, and performance aren't nice-to-haves—they're requirements. Created by the security research team at Qeeqbox, the same minds behind popular tools like Chameleon, Honeypots, and the MITRE Visualizer, Raven solves a problem that most developers don't even realize exists until they're neck-deep in it.

Unlike virtually every other threat map on the market, Raven operates completely offline. It bundles its own IP lookup database, port information, and geospatial data. No calls to ipapi.co. No Google Maps dependencies. No CDN-hosted D3.js that suddenly 404s during a critical incident response.

The project leverages D3.js with TopoJSON—not Anime.js or other animation libraries that prioritize flash over substance. This architectural choice matters: TopoJSON's topology encoding reduces file sizes dramatically compared to GeoJSON, while D3.js provides the precision control that security visualization demands. You're not watching a pretty screensaver; you're analyzing attack patterns with millisecond-level timing control.

Why it's trending now:

  • Air-gapped environments are exploding in critical infrastructure, finance, and government
  • Supply chain attacks have made teams paranoid about external dependencies
  • The "map in the lobby" problem—executives want visualizations, but security teams refuse cloud-based solutions
  • Docker↗ Bright Coding Blog-native deployment means SOC teams can spin it up in minutes, not weeks

Raven isn't just a map. It's a statement that your threat intelligence doesn't need to leave your network to look professional.


Key Features That Separate Raven from the Pack

Let's dissect what makes Raven genuinely special—not the marketing fluff, but the technical capabilities that solve real engineering problems.

Zero-Dependency Offline Operation

Raven ships with complete geospatial datasets: 247 countries (not the truncated 174 you see in amateur projects), approximately 100,000 cities, and a built-in IP-to-location database. The scripts directory contains everything needed for resolution. This isn't "offline-capable if you download some extra files." This is born offline.

Intelligent "Guessing" Engine

The add_marker_by_gussing() function accepts three input formats interchangeably:

  • IP addresses (public or private: 8.8.8.8, 0.0.0.0)
  • Location names (seattle,wa,us, delhi,in, 0,us)
  • Raw coordinates (-11.074920,-51.648929)

This polymorphic input handling eliminates data preprocessing pipelines. Feed it whatever your SIEM spits out—Raven figures it out.

Dual Rendering Modes: Live and Replay

Active threat maps support real-time streaming via WebSocket and historical replay for post-incident analysis. The global_timeout parameter controls animation pacing, while db_length manages memory-resident attack history.

Responsive, Interactive Cartography

Built-in zoom, pan, and drag operations with optimized world map rendering. The TopoJSON topology means shared borders are encoded once, not twice—critical when you're plotting 500 simultaneous attacks without frame drops.

Deep Customization Without Code Surgery

The raven_options object exposes 20+ configuration parameters:

  • Color theming (orginal_country_color, clicked_country_color, selected_country_color)
  • Country filtering (selected_countries, remove_countries—default removes Antarctica with 'aq')
  • Panel modularization (enable/disable multi-output, single-output, tooltip, random, insert, taskbar)
  • Theme picker module for instant reskinning

WebSocket-Ready Architecture

Method 2 enables bidirectional real-time streaming with configurable request_timeout and server endpoints. Perfect for integrating with your existing security stack without exposing the visualization layer to the internet.

Docker-Isolated Simulation

The included Dockerfile builds a complete simulation environment with zero host dependencies—ideal for testing, training, and classified deployments.


Use Cases: Where Raven Actually Shines

1. Air-Gapped SOC Visualization

The problem: Your facility has no internet. Your CISO still wants a threat map for the operations center.

Raven's solution: Static HTML deployment with all data embedded. Run python↗ Bright Coding Blog -m http.server on a local machine. Done. No API keys to rotate, no TLS certificates to manage for external services, no data exfiltration risk.

2. Honeypot Attack Correlation

Qeeqbox's own Honeypots project pairs naturally with Raven. Stream attack sources from your honeynet directly to the map via WebSocket, watching global attacker distribution in real-time without exposing your analysis infrastructure.

3. Incident Response Replay

The problem: Post-breach, you need to show exactly how the attack propagated geographically.

Raven's solution: Feed historical logs through add_to_data_to_table() with controlled timeouts. Replay the breach at 10x speed for executive briefings, or frame-by-frame for forensic analysis. The multi-output and single-output panels provide both aggregate and granular views.

4. Security Awareness Theater (The Good Kind)

That lobby screen. The one that makes executives feel like they're in a movie. Raven's random simulation mode generates plausible-looking attack traffic for demonstrations, training, and conference booths—without touching production data.

5. Custom Threat Intelligence Platforms

Building a TIP? Raven's iframe embed pattern lets you drop a fully functional world map into your React↗ Bright Coding Blog/Vue/Angular application with two code blocks. Focus on your intelligence logic; let Raven handle the cartography.


Step-by-Step Installation & Setup Guide

Method 1: Static Deployment (Simplest)

# Clone the repository
git clone https://github.com/qeeqbox/raven.git
cd raven

# Serve locally (any static server works)
python3 -m http.server 8080
# OR
npx serve .
# OR simply open src/raven.html in Firefox/Chrome/Safari

Navigate to http://localhost:8080/src/raven.html. That's it. No npm install. No webpack. No dependency hell.

Method 2: Docker Simulation (Isolated Environment)

# Build and run the complete simulation environment
sudo docker build -t simulation . && sudo docker run -p 5678:5678 -p 8080:8080 -it simulation

Then access the simulation interface at http://localhost:8080/simulation.html.

Advertisement

What this gives you:

  • WebSocket server on port 5678 for real-time data injection
  • Static file server on port 8080 for the visualization
  • Complete network isolation from your host
  • Pre-configured random attack generation for testing

Embedding in Your Application

Create an HTML file with this structure:

<!DOCTYPE html>
<html>
<head>
  <title>My SOC Dashboard</title>
  <style>
    body, html { margin: 0; padding: 0; height: 100%; overflow: hidden; }
    #raven-container { width: 100vw; height: 100vh; }
  </style>
</head>
<body>
  <div id="raven-container">
    <iframe id="raven-iframe" src="path/to/raven/src/raven.html" 
            frameborder="0" width="100%" height="100%" scrolling="auto"></iframe>
  </div>

  <script type="text/javascript↗ Bright Coding Blog">
    document.getElementById('raven-iframe').addEventListener("load", function() {
      
      var raven_options = {
        'world_type': null,                    // Use default world topology
        'selected_countries': [],              // Highlight specific countries (empty = all)
        'remove_countries': ['aq'],            // Remove Antarctica from display
        'height': window.innerHeight,          // Full viewport height
        'width': window.innerWidth,            // Full viewport width
        'backup_background_color': '#212222',  // Dark theme base
        'orginal_country_color': '#737373',    // Default country fill
        'clicked_country_color': '#6c4242',    // Color on mouse click
        'selected_country_color': '#ff726f',   // Color for targeted countries
        'attack_output': true,                 // Enable attack logging panels
        'global_timeout': 2000,                // Animation duration in ms
        'global_stats_limit': 10,              // Top N countries in stats panel
        'db_length': 1000,                     // Max attack history in memory
        'location': 'scripts',                 // Path to data scripts
        'panels': ['multi-output', 'single-output', 'tooltip', 'random', 'insert', 'taskbar'],
        'disable': [],                         // No panels disabled
        'verbose': true                        // Enable console logging
      }

      // Initialize Raven in the iframe context
      window['raven'] = document.getElementById('raven-iframe').contentWindow.raven
      window['raven'].init_all(raven_options)  // Setup all modules
      window['raven'].init_world()             // Render the world map
    });
  </script>
</body>
</html>

Critical configuration notes:

  • The location: 'scripts' path is relative to raven.html
  • Adjust remove_countries for your use case (Antarctica 'aq' is default-removed)
  • db_length controls memory usage—reduce for embedded systems
  • Panel order in the array determines UI layout priority

REAL Code Examples from the Repository

Let's walk through actual production patterns from Raven's documentation, with deep technical commentary.

Example 1: Basic Line Plot (City-to-City Attack Visualization)

// Plot a line from Seattle to Delhi with automatic color selection
raven.add_marker_by_gussing(
  {'from':'seattle,wa,us','to':'delhi,in'},  // Polymorphic location input
  {'line':{'from':null,'to':null}},           // null = random color assignment
  2000,                                        // 2-second animation duration
  ['line']                                     // Render as connecting line
)

What's happening under the hood: Raven's guessing engine parses seattle,wa,us through its embedded geonames database, resolves to approximate coordinates, performs the same for delhi,in, then calculates a great-circle path (the shortest surface distance between two points on a sphere). The null color values trigger HSL randomization with perceptible luminance—no invisible yellow-on-white accidents. The ['line'] option array activates the SVG path animator, which interpolates along the TopoJSON topology.

Example 2: IP-Based Plot with Custom Colors

// Trace from Brazilian coordinates to a specific IP:port with red warning color
raven.add_marker_by_gussing(
  {'from':'-11.074920,-51.648929','to':'0.0.0.0:3389'},  // Raw coords to IP:port
  {'line':{'from':'#FF0000','to':'#FF0000'}},             // Explicit red for both ends
  1000,                                                     // 1-second fast animation
  ['line']                                                  // Line visualization mode
)

Why this matters: The :3389 port suffix triggers Raven's embedded IANA port database lookup, displaying "Remote Desktop Protocol" in tooltips. The explicit hex colors override randomization—critical when you need red = critical, yellow = warning semantic encoding. Coordinates bypass name resolution entirely, eliminating any ambiguity in precise geolocation.

Example 3: Point-Only Marker (Single Source Highlight)

// Mark Portland as an attack source without drawing a destination line
raven.add_marker_by_gussing(
  {'from':'portland,or,us','to':null},  // null 'to' = point-only mode
  {'line':{'from':null,'to':null}},     // Colors ignored in point mode
  2000,
  ['point']                              // Explicit point visualization
)

Use case: DDoS source identification, botnet node highlighting, or compromised asset marking. The ['point'] option activates the radial pulse animation—a CSS/D3 hybrid that expands concentric rings from the location. Without a to destination, no SVG path is calculated, reducing render load for high-density single-source scenarios.

Example 4: Table-Integrated Logging (SIEM-Style Output)

// Plot AND log to output panels for analyst review
raven.add_to_data_to_table(
  {'from':'8.8.8.8','to':'delhi,in'},           // Google DNS to Indian target
  {'line':{'from':null,'to':null}},              // Auto-color
  2000,
  ['line','multi-output','single-output']        // Triple action: visualize + aggregate log + detail log
)

The add_to_data_to_table vs add_marker_by_gussing distinction: The former pushes structured data to Raven's internal database, enabling the stats panel (global_stats_limit), country aggregation, and exportable logs. The latter is "fire and forget"—purely visual. For SOC integrations, always use add_to_data_to_table unless you're running pure animation.

Example 5: WebSocket Real-Time Streaming

{
  "function": "marker",
  "method": "ip",
  "object": {
    "from": "0.0.0.0",
    "to": "us"
  },
  "color": {
    "line": {
      "from": "#977777",
      "to": "#17777"
    }
  },
  "timeout": 1000,
  "options": ["line", "single-output", "multi-output"]
}

Architecture insight: This JSON schema is what Raven's WebSocket consumer expects. The function field (marker vs table) determines database persistence. The method field (ip, name, coordinates) triggers different resolution paths in Raven's lookup engine. Send this to ws://localhost:5678 from your Python SIEM connector, Go log shipper, or whatever infrastructure you already run.


Advanced Usage & Best Practices

Performance Optimization for High-Frequency Feeds

When streaming >100 attacks/minute, batch your WebSocket messages and increase global_timeout to prevent animation queue saturation:

var raven_options = {
  'global_timeout': 5000,    // Slow animations, visible trail
  'db_length': 5000,         // Larger history for pattern analysis
  'disable': ['tooltip']     // Disable hover tooltips to reduce DOM load
}

Color Psychology for Security Context

Don't randomize in production. Establish semantic mapping:

// Critical: inbound malware
{'line':{'from':'#FF0000','to':'#FF0000'}}
// Warning: reconnaissance
{'line':{'from':'#FFA500','to':'#FFA500'}}
// Info: benign scanning
{'line':{'from':'#00BFFF','to':'#00BFFF'}}

Responsive Embed Patterns

Force aspect ratio preservation for kiosk displays:

#raven-iframe {
  width: 100%;
  height: 0;
  padding-bottom: 56.25%; /* 16:9 aspect ratio */
  position: relative;
}

Memory-Constrained Deployments

For Raspberry Pi or embedded SOC displays:

'db_length': 100,           // Minimal history
'panels': ['single-output'], // One panel only
'remove_countries': ['aq','gl','sj']  // Remove low-traffic regions

Comparison with Alternatives

Feature Raven Norse (Defunct) Kaspersky Cybermap Custom D3.js SaaS Threat Maps
Offline capable ✅ Native ❌ Cloud-only ❌ Cloud-only ⚠️ Manual ❌ No
Zero external APIs ✅ Yes ❌ No ❌ No ⚠️ Your problem ❌ No
IP geolocation ✅ Built-in ❌ External ❌ External ❌ You build ⚠️ Vendor lock-in
Open source ✅ MIT ❌ Proprietary ❌ Proprietary ✅ Your code ❌ No
Docker deploy ✅ Included ❌ N/A ❌ N/A ⚠️ You build ❌ No
Custom data inputs ✅ 3 formats ❌ Fixed ❌ Fixed ✅ Unlimited ⚠️ Limited
Real-time WebSocket ✅ Native ❌ N/A ❌ Simulated ⚠️ You build ⚠️ Expensive
247 countries ✅ Yes ⚠️ ~180 ⚠️ ~180 ⚠️ Your data ⚠️ ~180
Cost Free Dead Free (data cost) Expensive (dev time) $$$/month

The verdict: Raven is the only solution that combines complete offline operation, professional-grade cartography, and zero cost. Custom D3.js projects typically consume 40-80 hours of development before reaching feature parity—and that's before you discover your IP geolocation API changed its response format.


FAQ

Q: Can Raven run on a completely air-gapped network with no internet ever? A: Absolutely. Raven was designed for this exact scenario. All geospatial data, IP lookups, and rendering libraries are self-contained. The only requirement is a modern browser (Firefox, Chrome, or Safari).

Q: How accurate is the IP geolocation? A: Raven uses embedded data from AFRINIC, APNIC, ARIN, LACNIC, and RIPE regional internet registries. Accuracy is comparable to basic GeoIP databases—country-level is reliable, city-level is approximate. For precise coordinates, feed Raven explicit lat/long values.

Q: Can I customize the world map appearance? A: Yes. The raven_options object exposes colors for every state: default fill, hover, click, and selected. The theme picker module enables runtime switching. For deeper customization, modify the CSS in src/raven.html directly.

Q: What's the maximum attack frequency Raven can handle? A: The live regression demo shows 500 simultaneous attacks without frame drops on modern hardware. For sustained high-frequency feeds, use WebSocket batching and increase global_timeout to prevent animation queue overflow.

Q: Is Raven suitable for commercial use? A: Yes. Qeeqbox projects are typically open-source with permissive licensing. Verify the specific license file in the repository, but commercial deployment is explicitly intended.

Q: How do I integrate Raven with my SIEM? A: Use Method 2 (WebSocket). Write a connector in Python/Go/Rust that parses your SIEM's output, formats it as the JSON schema shown above, and sends to ws://raven-host:5678. The simulation Docker image provides a working reference implementation.

Q: Can I remove specific countries or focus on a region? A: Yes. Use selected_countries to whitelist (empty array = all), or remove_countries to blacklist. Combine with move_to_country (unless disabled) to auto-center the viewport.


Conclusion

Here's the truth: cyber threat maps have been broken for years. They're either expensive SaaS products that monetize your security data, or they're weekend projects that collapse under real-world load. Raven is the rare exception—a tool built by security engineers, for security engineers, with the paranoid operational security that modern environments demand.

The Qeeqbox team didn't just build another D3.js demo. They solved the hard problems: offline IP resolution, performant TopoJSON rendering, polymorphic data ingestion, and deployment flexibility that spans from Docker containers to classified air-gapped networks. The 247-country dataset alone represents more geographic granularity than virtually any competitor.

Whether you're building a SOC dashboard, demonstrating attack patterns to executives, or running honeypot visualization in an isolated lab, Raven eliminates the "build vs buy" dilemma entirely. It's free, it's open, and it's ready to deploy in minutes—not weeks.

Stop drawing arrows on whiteboards. Stop paying for threat maps that leak your data. Stop reinventing geospatial visualization.

👉 Star Raven on GitHub and deploy your first offline threat map today. Your future self—staring at a beautiful, responsive, completely isolated attack visualization during your next incident response—will thank you.

Got a custom use case? The Qeeqbox team actively maintains this project and welcomes issues and contributions. Check out their other security tools while you're there—this ecosystem runs deep.

Advertisement
Advertisement

Commentaires 0

Aucun commentaire pour l'instant. Soyez le premier à réagir !

Laisser un commentaire

Advertisement