2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00
2026-07-29 00:39:00 -04:00

Bluehound

Continuous BLE and Classic Bluetooth scanner with time-searchable logging, a REST API, and a web dashboard. Built for macOS and embedded/sensor-node deployments with WiFi streaming support.

Bluehound scans nearby Bluetooth devices in a loop, enriches each observation (manufacturer, service UUIDs, device class, estimated distance, Apple Continuity data), and persists everything to SQLite. A built-in HTTP server exposes the data for the bundled dashboard or any client.

Features

  • Dual-stack scanning — BLE via SimpleBLE, plus Classic Bluetooth inquiry and SDP service discovery on macOS via IOBluetooth.
  • Time-searchable history — every observation is stamped with date, time, hour, and minute and indexed for fast range queries.
  • Device enrichment — company/manufacturer lookup, standard service and characteristic UUID decoding, device-class decoding, and GATT characteristic enumeration on connect.
  • Distance estimation — RSSI + Tx power path-loss model, with per-device distance history.
  • Apple Continuity decoding — parses proximity/pairing advertisements.
  • Passive security assessment — flags risky services (OBEX, SPP, HID, audio) and known-vulnerable device signatures, assigning a HIGH/MEDIUM/LOW/NONE risk level.
  • Device nicknames — assign and manage human-readable labels per address.
  • ESP32 ingestion — remote sensor nodes can POST scan batches over WiFi to /esp32/scan.
  • REST API + web dashboard — a single-file HTML dashboard served over HTTP.

Requirements

  • macOS (Classic Bluetooth support uses IOBluetooth/CoreBluetooth frameworks)
  • CMake >= 3.15
  • SQLite3
  • Vendored dependencies (included in the repo):
    • SimpleBLE static library at simpleble/simpleble/build/lib/libsimpleble.a
    • cpp-httplib header at third_party/httplib.h

Build

./build.sh

This verifies the vendored dependencies, configures with CMake into build/, and compiles. The resulting binary is build/bluehound.

To build manually:

mkdir -p build && cd build
cmake ..
make -j

Install system-wide with sudo make install from the build/ directory.

Run

./build/bluehound

On start, Bluehound initializes ble_scans.db, launches the HTTP server on port 8080 (bound to 0.0.0.0), and begins scanning. Shut down cleanly with Ctrl-C (SIGINT/SIGTERM are handled gracefully).

Default configuration (compiled into Config in bluehound.cpp):

Setting Default
Scan duration 5000 ms per cycle
Scan interval 1000 ms between cycles
Database path ble_scans.db
HTTP port 8080
Max DB entries 1,000,000 (rotates)

Web dashboard

Serve the dashboard with the helper script (static server on port 8090):

python3 serve_dashboard.py

Then open http://127.0.0.1:8090. The dashboard queries the scanner's API on port 8080, so run the bluehound binary alongside it.

REST API

The scanner serves the following endpoints on port 8080:

Method Path Description
GET /health Health check
GET /scans/recent?limit=N Most recent observations
GET /scans/date/:date Observations for YYYY-MM-DD
GET /scans/hour/:hour Observations for hour HH
GET /stats Aggregate statistics
GET /device/:address/count Observation count for a device
GET /distance/:address Distance history for a device
GET /characteristics/:address Discovered GATT characteristics
GET /read/:address/:service/:characteristic Read a characteristic value
GET /nickname/:address Get a device nickname
POST /nickname/:address Set a device nickname
DELETE /nickname/:address Remove a device nickname
GET /nicknames List all nicknames
GET /security/:address Security assessment for a device
GET /security All security assessments
GET /tracking/:address Tracking data (device info, Apple Continuity)
POST /esp32/scan Ingest a scan batch from a remote ESP32 node

CORS is enabled for all origins.

Data model

Observations are stored in ble_scans.db (SQLite). Key tables:

  • ble_scans — every observation, with timestamps, RSSI, manufacturer/company, service UUIDs, estimated distance, protocol type, and Classic device-class/SDP fields.
  • device_distance_history — per-device RSSI/distance samples over time.
  • device_characteristics — discovered GATT services and characteristics.
  • device_nicknames — user-assigned labels.
  • security_assessments — risk level, vulnerabilities, and recommendations per device.
  • device_tracking_data — device model/firmware/serial, Apple Continuity, pairing status, and tracking identifiers.

Project layout

Path Purpose
bluehound.cpp Scanner core: scan loop, SQLite logging, HTTP API, BLE decoding, security assessment
classic_bluetooth.h / classic_bluetooth.mm Classic Bluetooth inquiry and SDP via IOBluetooth (Objective-C++)
web_dashboard.html Single-file web dashboard
serve_dashboard.py Static server for the dashboard
CMakeLists.txt / build.sh Build configuration
simpleble/ Vendored SimpleBLE
third_party/httplib.h Vendored cpp-httplib

Notes

  • Classic Bluetooth scanning and the IOBluetooth-backed features are macOS-only. BLE scanning via SimpleBLE is portable, but the build as configured links macOS frameworks.
  • The ESP32 endpoint uses lightweight string-based JSON parsing; use a proper JSON library for production ingestion.
  • Security assessments are heuristic and intended for authorized inventory and awareness, not as a substitute for a full audit.
S
Description
Continuous BLE and Classic Bluetooth scanner with time-searchable logging, REST API, and web dashboard
Readme
1.8 MiB
Languages
C++ 64.2%
HTML 26.6%
Objective-C++ 7.1%
CMake 0.6%
Shell 0.6%
Other 0.9%