- Capture the authoritative description of Ragnar as of December 2025.
- Align contributors on hardware expectations, software architecture, data flow, and operational behaviors.
- Cover every major subsystem including ping sweeps, orchestrator, Wi-Fi/AP control, network data separation, dashboards, vulnerabilities, installation, AI, and e-paper display.
- Hardware target: Raspberry Pi Zero 2 W, Pi 4, Pi 5 with Waveshare 2.13" E-Paper HAT (default
epd2in13_V4). Pi Zero 2 W is the lowest common denominator; all timing and memory assumptions follow its limits. - OS: Raspberry Pi OS (Debian Trixie, 64-bit), kernel 6.12. Earlier Debian versions must provide
systemd,hostapd,dnsmasq,nmap >= 7.94. - Users: System user and hostname default to
ragnarfor scripts and service files. Changing the account requires updating systemd units (/etc/systemd/system/ragnar.service,ragnar_wifi.service). - Resource constraints: 512 MB RAM on Pi Zero 2 W drives conservative threading (1 orchestrator worker, 6 nmap threads), aggressive garbage collection, and incremental scanning.
- Power: Optimized for mobile battery packs; actual draw varies by Pi model/peripherals, so concurrency throttles and display refresh cadence are used instead of assuming fixed wattage.
- Networking: Single onboard WLAN interface; AP and STA modes are mutually exclusive and coordinated by Wi-Fi manager.
- Shared Data Core (
shared.py): Initializes paths, loads configuration, handles per-network storage, bootstraps AI, intelligence engines, display helpers, and exposes convenience getters/setters to every module. - Database (
db_manager.py): SQLite per active network; single source for hosts, ports, vulnerabilities, Wi-Fi analytics, action state, and loot inventory. All CSVs are write-through caches fed from the DB. - Network Scanner (
actions/scanning.py): Performs ARP, ping sweep, and nmap discovery; seeds orchestrator targets and updates scan history. - Orchestrator (
orchestrator.py): Schedules/executes action modules (scanners, attacks, data theft) with retry logic, dependency handling, and resource gating. - Vulnerability Scanner (
actions/nmap_vuln_scanner.py): Incremental, NSE-driven scanning feeding Network Intelligence and the vulnerabilities view. - Wi-Fi Manager (
wifi_manager.py): Maintains station mode, auto AP fallback, captive portal lifecycle, connection analytics, and endless-loop watchdog. - Web/API (
webapp_modern.py,web/): Modern dashboard served on port 8000 with REST+WebSocket endpoints, config UI, AI insights, file browser, and Wi-Fi portal. - AI Service (
ai_service.py): GPT-5 Nano integration for insights, caching, and API exposure; sanitizes outbound data. - Display Pipeline (
display.py,epd_helper.py): Renders status, loot, telemetry, and gamification badges to the e-paper HAT with full/partial refresh control. - Logging/Monitoring: Central
logger.py, action-specific logs,/var/logfallbacks,data/logsfor audit trails,resource_monitor.pyfor CPU/MEM tracking.
initialize_paths()pins every directory/file path the moment the process starts so later modules can referenceshared_data.<path attribute>without re-walking the filesystem.NetworkStorageManageris instantiated before configs load, letting_apply_network_context()immediately bind per-network directories and SQLite path, even before Wi-Fi connects.get_default_config()seeds hundreds of keys;load_config()overlays user JSON, andapply_display_profile()normalizesepd_typewidth/height/orientation so downstream display math never revalidates._configure_database()callsget_db(...).configure_storage()which rebinds SQLite to the currently activedata/networks/<slug>/db/<slug>.db. This happens again on every SSID switch.initialize_network_intelligence()andinitialize_ai_service()are deferred until after config + storage exist, ensuring both subsystems inherit the correct per-network directories and credentials.- Background services include
_start_cleanup_task()(periodic host pruning),create_livestatusfile(), live font/image loaders, and gamification loader to keep UI artifacts synced.
- Per-Network Isolation (
network_storage.py)- Every SSID maps to
data/networks/<slug>/containingdb/<slug>.db,intelligence/,threat_intelligence/,loot/data_stolen/,loot/credentials/, andlogs/. NetworkStorageManagerpersists last SSID, migrates legacy global stores, exposes context toSharedData.set_active_network(), and keeps.last_ssidfor seamless reboots.- Context switches flush in-memory intelligence caches before moving file pointers to avoid cross-network leakage.
- Every SSID maps to
- SQLite schema (simplified)
Table Key Columns Purpose hostsmac (PK), ip, hostname, vendor, alive, open_ports, tags Truth for discovered devices. scan_historyid, mac, tool, ports_found, timestamp Audit trail of scanners per run. vulnerabilitiesid, mac, cve, severity, source, status Feeding Network Intelligence + UI. wifi_networksssid, bssid, signal, security Cached AP list for portal and analytics. wifi_connectionsid, ssid, start, end, status, failure_reason Connection analytics/time-series. actions_statemac, action_name, status, timestamp Retry and throttling decisions. loot_inventoryid, mac, path, type, size Catalog of stolen files/credentials. - Legacy CSV mirrors
data/netkb.csv: still updated for display compatibility (e-paper + scripts) but never consumed as source of truth.data/logs/*.csv: rotating exports for offline review.data/vulnerabilities/vulnerability_summary.csv: summary for interoperability with Bjorn tooling.
upsert_host(mac, ip, hostname, ...)is the canonical write path for scanners, orchestrator actions, and display metrics; every module calls this rather than writing SQL.update_ping_status(mac, success=True/False)incrementsfailed_ping_count, updateslast_ping_success, and flipsstatusbetweenalive/degraded.add_scan_history(mac, ip, scan_type, ports_found)appends immutable audit rows consumed by the dashboard timeline and AI context.get_all_hosts()returns SQLite rows as dictionaries; orchestrator, display, and API responses rely on this call.- Wi-Fi analytics tables (
wifi_scan_cache,wifi_connection_history,wifi_network_analytics) are written through helper methods inwifi_manager.py, letting/api/wifi/*endpoints query historical signal strength, durations, and failure reasons without touching raw SQL.
NetworkScanner.run_initial_ping_sweep()triggered after Wi-Fi association, manual API kick, and periodically via orchestratorscan_interval(default 180 s).- All results are written via
db_manager—CSV mirrors are display-only. Each scan updatesscan_historyto preserve lineage. - Discovery flow (simplified text diagram):
- Wi-Fi connects →
WiFiManagernotifies SharedData →NetworkScannerkickoff. - ARP scan populates MAC/IP base.
- Ping sweep fills gaps + high-priority hosts.
- Nmap port scan enriches open services.
- Orchestrator re-reads DB and schedules follow-on actions.
- Wi-Fi connects →
- Commands:
sudo arp-scan --interface=wlan0 --localnetplus fallback/24sweep for routers with custom masks. Interfaces configurable throughshared_config.arp_scan_interface. - Output parser extracts IP, MAC, vendor, ignoring comment lines and invalid tokens via regex and
ipaddressvalidation. - Successful entries call
db.upsert_host()(write host metadata) anddb.update_ping_status()(alive=1). Vendor info seeds UI badges. - Failures (missing binary, timeout) logged with guidance to install
arp-scanor widen sudo privileges.
- Targets missing from ARP results across configured CIDRs (default
192.168.1.0/24, user-addable via config or UI). - Priority list (default
192.168.1.192, user-configurable) pinged with 3 attempts, 3 s timeout before general sweep (single ping, 2 s wait). Purpose: ensure crown-jewel host stays monitored even if stealthy. - Missing MACs create temporary pseudo-MACs (
00:00:<ip octets>) until reconciled inupdate_netkb()with real data; DB marks themis_pseudo=1. - Threaded execution honors
network_max_failed_pings,mac_scan_blacklist, andip_scan_blacklist. Workers limited tohost_scan_workers(default 4). - Summary stats (hosts seen, time taken) logged for e-paper and AI ingestion.
- Runs
nmap -Pn -sSagainst merged port list (top 50 +shared_config.portlistoverrides + UI extra ports). UDP scans only appear in results when separate modules request them; the default network sweep is TCP-only. - Adds
--open --min-rate 1000 --max-retries 1 --host-timeout 10s -vfor speed on constrained hardware; runs at full pace regardless of CPU load (no automaticresource_monitorbackpressure inside the scanner module). - Stores hostname, ordered ports list, service names/version strings when available; writes to SQLite and
data/logs/nmap.logvianmap_loggerwith exact command, start/end timestamps, and outcome. - Results feed orchestrator target selection, vulnerability scanner incremental logic, AI context, and dashboard visualizations.
- Thread pools for host/port scans are capped (
host_scan_workers/port_scan_workersmax 6) and automatically scale down on Pi Zero hardware, preventing socket exhaustion. _ping_sweep_missing_hosts()first brute-forcespriority_targets, then iterates remaining IPs, fabricating deterministic pseudo-MACs (00:00:c0:a8:xx:yy) until ARP learns the real vendor. The pseudo flag is reconciled later insideupdate_netkb()so downstream modules know the host is provisional.run_arp_scan()always runs two commands (localnet + explicit/24), merges results, then persists to SQLite before returning. The method logs each binary invocation for offline troubleshooting.- Every scanner write funnels through
DatabaseManagerso concurrency is controlled by SQLite’s own locking +threading.RLockinside the manager. CSV writing only happens inupdate_netkb()strictly for display compatibility.
- Validates config flags (
retry_success_actions,scan_vuln_interval,enable_attacks,scan_vuln_no_ports) and sets semaphore to 1 for Pi Zero 2 W stability (hard limit). Pi 4/5 builds may raise via config but 1 is default safeguard. - Loads actions from
config/actions.json(ordered byb_priority). Modules withb_portunset become standalone actions. Each module must exposeb_class, optionalb_parent,b_modulepath. - Initializes
self.network_scanner(actions/scanning) andself.nmap_vuln_scanner. Missing modules fail gracefully with warning and continue boot.
process_alive_ips()filters hosts withAlive='1'; pre-filters by required port before acquiring semaphore to avoid blocking queue with ineligible targets.- Parent actions (no
b_parent_action) execute first, followed by their children on the same host, then remaining children globally. Example chain:FTPConnector→StealFilesFTPonce credentials succeed. - Each action runs through
_execute_with_timeout()to guard against hung operations; timeouts mapped toaction_timeout(default 300 s). Return codessuccess,failed,timeoutfeed_update_action_status(). - Standalone actions run once per cycle and can modify global state (e.g.,
log_standalone.pywriting daily summary). - Active action names propagate to
shared_data.ragnarorch_statusfor e-paper + dashboard status card.
- Status strings
success_YYYYMMDD_HHMMSSandfailed_*stored per host/action row plusretry_reason. Manual DB edits should respect this format. _should_retry()enforces delays (success_retry_delaydefault 300 s,failed_retry_delay180 s). Custom per-action overrides available viaconfig/actions.jsonfieldb_retry_delay.- Vulnerability scanners receive special-case 24 h override when remote APIs throttle or
scan_vuln_running=False. - Resource monitor integration (
resource_monitor.py) blocks execution if free memory below threshold (default 30 MB) or CPU > 95% for >5 s; actions skipped with reason logged. - Failed cycles increment
failed_scans_count; once it flips to 1 the loop runs standalone actions, idles for a scan interval, then resets the counter—there is no configurable retry cap.
- Standalone actions (portless) run per cycle irrespective of host ports; typical responsibilities include housekeeping (e.g., prune old loot, sync dashboards) or aggregator jobs.
NmapVulnScannertriggered perscan_vuln_interval; records timestamps inshared_data.last_vuln_scan_time. Skipped whenscan_vuln_running=Falseor insufficient new ports.- Actions flagged
b_parentrequire parent success before running; skip recorded asdependency_blockedin DB for transparency.
- Each action module is required to set
b_class,b_module,b_port,b_parent,b_priority.load_action()instantiates classes dynamically viaimportlib.import_module('actions.<module>'), so mismatched class names surface immediately in logs. _execute_with_timeout()wraps user code inside a daemon thread, captures exceptions, and returns'failed'if the worker dies before returning'success'. This guard prevents unhandled exceptions in actions from killing the orchestrator loop.resource_monitor.can_start_operation(f"action_{action_key}", min_memory_mb=30)is called before the semaphore is acquired, ensuring we never starve other threads due to memory pressure.- Status strings saved back into SQLite (e.g.,
ssh_connectorcolumn) form the input for_should_retry(). Manual DB edits must keepstatus_timestampformat or retries will trigger every loop.
- Incremental Port Tracking:
scanned_ports_history.jsonensures only new or stale ports (>1 hour, configurable) are rescanned. History stored per MAC with timestamps; manual tampering resets to full scan next cycle. - NSE Scripts: Uses
vulners.nseby default plus optional NSE list defined inshared_config.nmap_nse_scripts. Additional script args supported viashared_config.nmap_extra_args. - Threat Sources:
threat_intelligence.pyingests CISA KEV, NVD CVE, AlienVault OTX, MITRE ATT&CK. Configurable indata/threat_intelligence/sources_config.jsonwith API keys (if required). Data cached per network indata/threat_intelligence/<network>/. - Data Flow: Parsed CVEs → Network Intelligence classification (
active_findings.json,resolved_findings.json,enriched_findings.json,threat_cache.json). Each entry includes CVSS, exploit links, remediation text, detection timestamp, and host mapping. - Web Exposure: Dashboard vulnerabilities tab queries
/api/v1/intel/vulnerabilities(internal) pulling from Network Intelligence; updates stream through WebSocket for near-real-time cards. Dismissals markstatus=dismissedbut reappear when scanner rediscovers CVE. - Retention: Findings older than
shared_config.vuln_retention_days(default 30) auto-archive unless still active. Resolved findings kept for historical graph. - Logs & Auditing: All commands stored in
data/logs/nmap.log; vulnerability parser logs indata/logs/vuln_scanner.log; threat sync logs per source for debugging API failures.
- Maintains four dicts keyed by
network_id(active_vulnerabilities,resolved_vulnerabilities,active_credentials,resolved_credentials). Eachnetwork_idis a hash derived from SSID viacreate_network_id()so raw SSIDs never leave disk. - Files persisted per network context:
network_profiles.json,active_findings.json,resolved_findings.json.set_storage_root()hot-swaps directories wheneverSharedDataswitches SSIDs. - Findings lifecycle:
add_vulnerability()/add_credential()generates deterministic IDs (md5 hash) and marksstatus=active.schedule_resolution_check()flags findings withpending_resolution=Truewhen the SSID changes.confirm_finding()incrementsconfirmation_countand clears pending flags when scanners rediscover the issue.resolve_finding()migrates entries intoresolved_*dicts with reason/time stamps.
- Network profiles track
connection_count,active_vulnerabilities,active_credentials, and are updated withinupdate_network_profile()every time Wi-Fi connects or scans run.
WiFiManager.start()runs an endless loop with a 30 s post-boot delay to let OS networking settle. Ifwifi_monitor_enabled=False, service exits after first success.- Known networks pulled from
shared_config.json(wifi_known_networks). Entries contain SSID, PSK, priority, optional static IP data. UI edits propagate to config +wpa_supplicant.conf. - Connection attempts limited by
wifi_max_attemptsandwifi_connection_timeout(default 3 attempts, 60 s each). After each cycle results recorded inwifi_connectionstable. - Successful connection triggers
_trigger_initial_ping_sweep()withwifi_ping_sweep_cooldown(default 120 s) to refresh network map. Additional sweeps may be triggered manually or when AI requests fresh data. - DNS + NTP sanity checks performed post-connect; repeated failures increment
wifi_validation_failuresdriving endless-loop fallback.
- Periodic validations every
wifi_validation_interval(180 s) with up towifi_validation_retries(default 5). Each validation pings gateway, resolves DNS, optionally hits configured health URL. - Analytics stored per cycle (RSSI, bitrate, Wi-Fi chip temperature, packet loss) for dashboard historical charts.
- Failsafe counter reboots after
failsafe_cycle_limitcycles (default 20) with >5 minute disconnections and no AP clients; ensures unattended deployments recover automatically. - Restart markers in
/tmp/ragnar_wifi_manager.pidprevent multiple concurrent managers.
- Activates when Wi-Fi is unavailable and
wifi_auto_ap_fallbackis true or when forced via/api/wifi/ap-mode. Relies onhostapd+dnsmasq;wifi_manager.pywrites fresh/tmp/ragnar/hostapd.confand/tmp/ragnar/dnsmasq.conffiles on every AP start instead of loading templates fromresources/. - Configurable SSID/password (
wifi_ap_ssid,wifi_ap_password), defaultRagnar/ragnarconnect. Channel default 6, can be changed via config. - Serves captive portal at
http://192.168.4.1/portal(assets underweb/). Portal surfaces known networks, RSSI, manual SSID entry, countdown timers, and AP-client analytics. - AP logger writes to
/var/log/ap.logordata/logs/ap.logfallback; logs include AP start/stop, client associations, portal submissions, and forced exits. - Idle timeout (
ap_mode_timeout, default 180 s) cycles between AP and Wi-Fi reconnect attempts; user interactions extend timers and markap_clients_connected=Trueto prevent premature shutdown. - Web UI can force exit AP mode via API toggles;
force_exit_ap_modeflag triggers immediate hostapd teardown and STA retry. - Credentials captured via portal stored encrypted (simple XOR + base64) inside SQLite until applied to wpa_supplicant.
_initial_endless_loop_sequence()enforces a 30 s post-boot delay, checks for existing connection via/tmp/ragnar_wifi_state.json, then either schedules AP mode or triggers_trigger_initial_ping_sweep()for the connected SSID._endless_loop_monitoring()(not shown in excerpt) continually alternates betweenconnect_to_known_networks()attempts, AP activation viastart_ap_mode(), and validation cycles. Each loop records timestamps sofailsafe_cycle_limitlogic can trigger reboots if the unit stays offline >5 minutes per cycle.- Every successful connection inserts/updates rows in
wifi_connection_history(start/end timestamps, signal, durations) andwifi_network_analytics(success/failure counters). This telemetry feeds/api/wifi/status,/api/wifi/networks, and the dashboard charts without rescanning the OS every refresh. setup_ap_logger()writes AP lifecycle events to/var/log/ap.logwhen possible ordata/logs/ap.logotherwise, making AP troubleshooting possible even during captive-portal onboarding.
WiFiManagercallsSharedData.set_active_network(ssid)after association or when user selects network via dashboard.- Context switch reconfigures SQLite path, intelligence directories, loot paths, AI caches, threat cache, and log pointers. Modules listening to
SharedDataattributes automatically start writing into the new namespace. data/networks/<slug>/loot/credentials/*.csvreplaces legacy globaldata/output/crackedpwdper network. Legacy directory kept for compatibility but no longer updated once new network is active..last_ssidensures reboots load the last active context even before Wi-Fi connects, allowing offline review of data.- Storage manager handles slug collisions, ASCII folding (SSID to slug), and migrations of old directories. Tools referencing direct paths should use
SharedDatahelpers to stay future-proof.
_slugify()strips non-ASCII, forces lowercase, and collapses non-alphanumeric characters into_, matching the folder naming convention enforced in code._ensure_network_dirs()createsdb/,intelligence/,threat_intelligence/, andloot/*subdirectories atomically, so modules can assume directory existence when they callos.path.join(shared_data.datastolendir, ...)._bootstrap_legacy_layout()is invoked once to move pre-networks-era directories intonetworks/default/. If the directory already contains data, migration is skipped to avoid clobbering user files.
SharedDataconfiguresEPDHelperbased onconfig.epd_type, orientation, andscreen_reversed. Supported profiles defined inDISPLAY_PROFILESmap width/height/flip options.display.pycomposes layered canvas: background template → headline metrics (targets, creds, vulns) → Wi-Fi info (SSID, IP) → rotating comments/AI quips → loot ticker. Fonts loaded fromresources/fontswith fallback.- Supports full refresh every configurable interval (default 2 minutes) to clear ghosting; partial updates used for incremental status changes. Full refresh triggered when
screen_reversedchanges or hardware profile swapped. - Gamification data from
data/gamification.jsonsurfaces progress badges (e.g., "First Blood", "Credential Hoarder"). Each badge includes icon path underresources/images/badges. - Display subsystem listens to
shared_data.ragnarorch_status, network stats, AI summary, and Wi-Fi manager state for real-time updates.
schedule_update_shared_data()runs every 5 s, readinglivestatus.csv, counting credentials by iterating the network-scopedcrackedpwddir, and settingshared_data.targetnbr,portnbr,vulnnbr,crednbr, andnetworkkbnbr. It contains retry logic around temporary CSV locks to avoid race conditions while actions write credentials.schedule_update_vuln_count()wakes every 300 s, readsvuln_summary_file, and synchronizes both the display andlivestatus.csvwith the current vulnerability count derived from SQLite.update_main_image()rotates status art by callingshared_data.update_image_randomizer(); fonts and bitmaps come fromresources/fontsandresources/images. Whenshared_data.imagegenis empty, the loop logs errors and keeps the previous image.
- Server:
webapp_modern.py(Flask + Flask-SocketIO) serves REST endpoints under/api, WebSocket for live updates, and static files fromweb/. - Frontend:
web/index_modern.html+ Tailwind CSS + vanilla Socket.IO-driven helpers inweb/scripts/ragnar_modern.jsdeliver the responsive dashboard and WebSocket widgets (no AlpineJS at present). - Key features:
- Real-time host list, port map, and threat intelligence overlays with filtering, tagging, and per-host action history.
- Config tab editing
shared_config.jsonwith validation + diff preview; writes via/api/configendpoint. - File browser and gallery backed by per-network loot directories; preview images, download artifacts, delete entries (updates DB + filesystem).
- System monitor (CPU, RAM, storage, GPU temp) via
/api/system/metrics(resource_monitor) with streaming updates. - Pwnagotchi bridge controls calling
scripts/install_pwnagotchi.shand toggling systemd unitsragnar.service,pwnagotchi.service. - AI insights cards (network summary, vulnerabilities, weaknesses) with manual refresh + cache status.
- Notification center showing kill switch warnings, AP status, update availability.
- API surface (representative):
/api/hosts,/api/hosts/<mac>– host data + actions state./api/actions/trigger– manually kick orchestrator action./api/files/loot– list/download/delete loot entries./api/system/control– reboot/shutdown toggles./api/wifi/*– scan networks, connect, start/stop AP, monitor state./api/kill– kill switch endpoint (requires confirmation token).
- Captive Portal:
GET /portalservesweb/captive_portal.htmlwhen AP clients hit the Dashboard root./generate_204responses redirect to/portalfor Android/iOS captive detection. AP clients then call the same/api/wifi/*endpoints as the dashboard (there are no dedicated/api/portal/*routes in the current codebase).
- Wi-Fi:
/api/wifi/interfaces,/status,/scan(POST),/networks,/connect,/disconnect,/exit-ap,/forget,/ap/enable,/ap/start,/ap/stop,/reconnect,/ap/exit,/force-recovery,/log. All calls proxy intoWiFiManagerhelpers and SQLite analytics tables. - System Control:
/api/system/metrics(resource monitor stats),/api/system/control(shutdown/reboot),/api/system/update(git pull + pip),/api/system/logs(tail sanitized logs). - Threat/Intel:
/api/v1/intel/vulnerabilities,/api/v1/intel/threats,/api/v1/intel/summarymap directly toshared_data.network_intelligenceandThreatIntelligenceFusioncaches. - Kill Switch:
/api/killorchestrates repository wipe,data/purge, optional shutdown; implemented inkill_switch()and gated byconfirmation == "ERASE_ALL_DATA". - Pwnagotchi bridge:
/api/pwnagotchi/install,/status,/logs,/swap,/cancelmanage service switching via_write_pwn_status_file()and_schedule_pwn_mode_switch(). - AI:
/api/ai/status|insights|network-summary|vulnerabilities|weaknesses|clear-cache|tokenroute intoAIServicefor caching + token management.
- Registered events include
request_status,request_logs,request_network,request_credentials,request_loot,start_scan,stop_scan,request_activity. Every handler emits structured JSON snapshots so the frontend can update without polling. - Connection metrics (
clients_connected) increment/decrement inside the@socketio.on('connect'/'disconnect')handlers, enabling UI banners warning when too many viewers are online.
ai_service.pyinitializes GPT-5 Nano via OpenAI SDK whenai_enabledandopenai_api_tokenare set. Supports alternative models viaai_modelvalue.- Capabilities toggled via config:
ai_analysis_enabled,ai_vulnerability_summaries,ai_network_insights,ai_personality(tone),ai_max_tokens,ai_temperature. - Cached responses (5 min TTL) stored in memory; optional disk cache (disabled by default) toggled with
ai_cache_to_diskfor offline review. - API surface:
GET /api/ai/status– readiness, configured model, last run.GET /api/ai/insights,/network-summary,/vulnerabilities,/weaknesses– structured JSON with textual + bullet guidance.POST /api/ai/clear-cache– flush cached responses.POST /api/ai/run– manual prompt injection (admin only).
- Integrates with Network Intelligence to pull sanitized host/service context (no raw credentials sent); redacts IP octets when
ai_privacy_modeenabled. - Prompts include metadata (host counts, CVE severities, Wi-Fi health) and personalities mimic Pwnagotchi-style quips for user engagement.
- Errors (quota exceeded, timeout) bubbled to UI with actionable remediation tips.
EnvManagerloadsRAGNAR_OPENAI_API_KEYfrom environment or.envand persists tokens when/api/ai/tokenPOST/DELETE endpoints run._ask()wraps the OpenAI Responses API with a two-pass system: attempt with configuredtemperature, then automatically retry without it if the model reports an unsupported parameter.- Responses are cached per-input via
_cache_key()using md5 hashes of the prompt JSON; the default TTL is 3600 s (overriding legacy 300 s) to minimize token usage on Pi deployments with limited bandwidth. analyze_network_summary,analyze_vulnerabilities, andidentify_network_weaknessesare the three domain-specific prompt builders. Each checks flags (ai_network_insights,ai_vulnerability_summaries) before calling_ask()and logs token counts for auditing.
- Master config file:
config/shared_config.json(auto-created from defaults inSharedData.get_default_config()). JSON grouped by pseudo-headings (__title_*). - Categories include scan timing, logging, Wi-Fi, display, AI, attack delays, wordlists, loot filters, AP behavior, and vulnerability scanning.
- Web UI writes to config via
SharedData.save_config(), reloading relevant services dynamically. Hot-reload events propagate viashared_datawatchers. - Additional per-feature configs:
config/actions.json– defines every action module, ports, parents, priority, retry overrides.data/threat_intelligence/sources_config.json– threat feed endpoints, keys, polling intervals.data/logs/logging_config.json(optional) – overrides logger levels/handlers.resources/comments/comments.json– curated display comments loaded at runtime.
- Key configuration highlights:
Key Default Description scan_interval180 Seconds between orchestrator sweeps. scan_vuln_interval300 Seconds between vuln scans (subject to incremental logic). enable_attacksFalse Master switch for offensive modules. wifi_auto_ap_fallbackTrue Whether to start AP when STA fails. wifi_failsafe_cycle_limit20 Disconnection cycles before auto-reboot. epd_typeepd2in13_V4Display driver selection. ai_enabledFalse Enables AI insights; requires token. release_gate_enabledFalse Lock UI/API until passphrase provided (demo mode). steal_file_names[...] Keyword list used by loot modules. mac_scan_blacklist[] MACs excluded from scanning/attacks. - Runtime modules reference
shared_data.configlive; writes through the Web UI callSharedData.save_config()which flushes JSON, updates in-memory attributes, and triggers downstream watchers (e.g., Wi-Fi manager reloading known networks, display togglingscreen_reversed). - Config headings (
__title_*) are used purely for UI grouping; the parser strips these keys automatically when exporting to Python dicts.
| Path | Purpose |
|---|---|
actions/ |
Attack and scan modules (FTP, SMB, SQL, BLE, etc.). |
config/ |
actions.json, shared_config.json, threat source config. |
data/ |
Logs, intelligence, per-network stores, loot, templates. |
data/networks/<slug>/ |
Isolated DB, intelligence, loot for each SSID. |
resources/ |
Images, fonts, WaveShare EPD drivers, comments, AP templates. |
web/ |
Modern dashboard HTML/CSS/JS plus captive portal assets. |
scripts/ |
Maintenance/install scripts (install_pwnagotchi.sh, fix_permissions.sh, etc.). |
var/log/ |
Runtime logs (AP, orchestrator) when system paths writable. |
var/log/ragnar/ |
Optional custom log dir for packaged releases. |
requirements.txt |
Python dependencies for pip installation. |
INSTALL.md, KILL_SWITCH.md, AI_INTEGRATION.md |
Topical documentation referenced by spec. |
- Automated install (
install_ragnar.sh)- Download via wget/curl, make executable, run as root.
- Script installs apt dependencies (nmap, arp-scan, hostapd, dnsmasq, python3-pip, libopenjp2) and pip packages from
requirements.txt. - Copies systemd units (
ragnar.service,ragnar_wifi.service,ragnar_web.service), enables them, and seeds/etc/sudoers.d/ragnarentries for necessary commands. - Runs
init_data_files.shto create data directories, templates, and default configs. - Prompts for reboot after verifying EPD hardware and Wi-Fi chips.
- Manual install: Clone repo, run
pip install -r requirements.txt, executepython3 init_shared.py, configure systemd units manually. - Upgrades:
quick_update.shperformsgit pull, checks requirements hash, re-runs pip if needed, migrates DB schema (viadb_managermigrations), restarts services. - Helper scripts: same as before plus
install_wifi_management.sh(sets hostapd/dnsmasq configs) andinstall_pwnagotchi.shbridging script. - Kill switch:
/api/killwipes DBs, logs, repository, and can optionally schedule a shutdown. Requires a POST JSON body with{"confirmation": "ERASE_ALL_DATA", "shutdown": false}(shutdown flag optional) and logs through the standard logger—there is no dedicatedkill.log.
- Validate
confirmation == "ERASE_ALL_DATA"and optionalshutdownflag. - Delete
data/ragnar.db(or active network DB path), followed bydata/tree viashutil.rmtree. - Remove the entire repository directory (
ragnar_dir) fetched either from$HOME/Ragnaror the running directory. - Log each step with CRITICAL severity and collect per-step success flags for the API response.
- If
shutdown_afteris true, schedulesudo shutdown nowafter returning JSON so the HTTP response flushes before power-off.
- JWT-less local API expected; rely on LAN isolation. Exposing publicly requires reverse proxy authentication (NGINX + OAuth) and HTTPS termination.
- AP portal served over HTTP; credentials stored locally in SQLite and exported to
wpa_supplicant.conf. Consider VPN tunnel if onboarding remote networks. - Sensitive actions (kill switch, shutdown, AP enable) present explicit confirmation prompts in the UI; the kill switch in particular forces the user to type
ERASE_ALL_DATAbefore the POST is issued. - CORS is currently wide open (
flask_cors.CORS(app)with default settings and Socket.IOcors_allowed_origins="*"); harden via reverse proxy or code changes if exposure beyond trusted LAN/AP is required. - No CSRF tokens are issued today; the dashboard relies on being reachable only from the trusted LAN/AP. Harden via reverse proxy auth or custom token middleware before exposing publicly.
- File downloads sanitized via whitelist to prevent directory traversal; uploads disabled by default.
resource_monitor.ResourceMonitorruns lightweight psutil checks;get_system_status()powers/api/system/metricsand providesmemory.percent,cpu.percent, process/thread counts, and a health flag.ResourceMonitor.can_start_operation()is used by orchestrator actions and scanners to ensure at leastmin_memory_mbremains free. If available RAM dips below 80 MB, it logsCRITICALand instructs callers to skip work to avoid Pi Zero kernel OOM killings.force_garbage_collection()(available but rarely used) can be triggered before expensive operations to reclaim memory without rebooting.
- Running offensive modules (brute force, file stealing) must be authorized; defaults have
enable_attacks=False. Enabling them without consent can violate local laws. - Pi Zero resource exhaustion can still occur if custom actions disregard semaphore or spawn heavy subprocesses. Always profile new modules with
shared_datainstrumentation before enabling in production. - AP mode exposes open HTTP portal—protect physical device to prevent rogue reconfiguration. Change default AP password and disable AP auto mode if device is in hostile environment.
- AI integration sends sanitized data to OpenAI; disable in air-gapped or regulated environments or configure local proxy/LLM.
- Kill switch relies on local HTTP endpoint; if Ragnar exposed publicly without auth, attacker could wipe device. Always gate reverse proxy with auth.
- Database encryption at rest not enabled by default; use encrypted FS (LUKS) for highly sensitive deployments.
- Boot device; Wi-Fi manager connects or launches AP. Verify
systemctl status ragnar.servicegreen before proceeding. - Once networked, initial ping sweep populates SQLite. Confirm via
data/logs/network_scanner.logor dashboard host count. - Orchestrator loops:
- Filter alive hosts from DB.
- Execute parent actions (e.g., credential bruteforce) respecting ports.
- Trigger child actions after success.
- Schedule standalone maintenance tasks.
- Monitor
data/logs/orchestrator.logfor failures/timeouts.
- Nmap vulnerability scanner runs per interval and updates intelligence; check
/api/v1/intel/vulnerabilitiesJSON for new findings or UI Vulnerabilities tab. - Dashboard, AI, and e-paper display live state from shared DB/intelligence files. If UI stale, restart
ragnar_web.serviceor inspect WebSocket logs. - Logs rotate under
data/logs; archive regularly. Kill switch wipes artifacts when needed—document reason externally before triggering. - For Pwnagotchi swaps: use Config tab control, wait for service handoff, reboot, then confirm mode via dashboard badges.
- Remove legacy CSV artifacts once web fully migrates to SQLite/JSON.
- Expand AI personalities and add local LLM option for offline mode.
- Increase modularity of Wi-Fi AP portal to support captive portal templates per customer.
- Add automated remediation playbooks for recurring vulnerabilities.
Ground truth: webapp_modern.py as of December 2025. Methods shown exactly as implemented; unless noted, responses are JSON.
| Path(s) | Methods | Purpose |
|---|---|---|
/ |
GET | Serve the modern dashboard or redirect AP clients into captive portal flow. |
/<path:filename> |
GET | Static asset handler for everything under web/. |
/portal |
GET | Explicit captive portal landing page used during AP onboarding. |
/wifi, /wifi-config, /setup |
GET | Legacy Wi-Fi configuration screens kept for compatibility. |
/connecttest.txt, /generate_204, /gen_204, /ncsi.txt, /success.txt |
GET | Captive portal probe responses that redirect mobile devices back to /portal. |
| Path | Methods | Purpose |
|---|---|---|
/download_file |
GET | Older file-download helper (still used by legacy UI widgets). |
/get_logs |
GET | Legacy log fetcher (plain text). |
/list_files |
GET | Legacy directory listing endpoint. |
/list_credentials |
GET | Legacy credential CSV export. |
/network_data |
GET | Legacy combined network JSON blob. |
/netkb_data_json |
GET | Legacy NetKB snapshot for scripts that predate SQLite. |
| Path | Methods | Purpose |
|---|---|---|
/api/status |
GET | High-level Ragnar health summary (hosts, Wi-Fi, orchestrator state). |
/api/stats |
GET | Aggregated counters for UI scorecards. |
/api/dashboard/quick |
GET | Lightweight stats for splash/loading cards. |
/api/dashboard/stats |
GET | Full dashboard metrics bundle (graphs, loot counts, etc.). |
/api/display |
GET | Returns e-paper friendly status payload. |
/api/epaper-display |
GET | Serves the last rendered e-paper image for remote preview. |
/api/logs |
GET | Streams orchestrator/web logs to the UI log viewer. |
/api/logs/activity |
GET | Activity feed summarizing recent actions. |
/api/network |
GET | Current network snapshot (hosts, ports, tags). |
/api/network/stable |
GET | Debounced network stats for widgets that poll less frequently. |
| Path | Methods | Purpose |
|---|---|---|
/api/config |
GET/POST | Read or persist shared_config.json (with server-side validation). |
/api/config/apply-profile |
POST | Apply predefined display/EPD hardware profile. |
/api/config/detect-hardware |
GET | Detect Pi model/EPD to suggest defaults. |
/api/config/hardware-profiles |
GET | Enumerate supported hardware profiles. |
/api/actions |
GET | Dump parsed actions.json so the UI can show orchestrator graph. |
/api/data/reset-threat-intel |
POST | Purge cached threat intelligence for the active network. |
/api/data/reset-vulnerabilities |
POST | Clear vulnerability cache to force a fresh scan. |
| Path | Methods | Purpose |
|---|---|---|
/api/files/list |
GET | Enumerate files under per-network loot folders. |
/api/files/download |
GET | Stream a selected loot artifact (binary-safe). |
/api/files/upload |
POST | Upload files (disabled by default, used for configs). |
/api/files/delete |
POST | Remove selected files and update DB inventory. |
/api/files/clear |
POST | Bulk-delete generated files (cleanup). |
/api/loot |
GET | Structured loot inventory (files + credentials) for UI cards. |
/api/credentials |
GET | Combined credential cache (modern + legacy view). |
/api/netkb/data |
GET | Live NetKB export sourced from SQLite. |
/api/netkb/entry/<entry_id> |
GET | Fetch an individual NetKB record for detailed inspection. |
/api/netkb/export |
GET | CSV/JSON export of the full NetKB. |
| Path | Methods | Purpose |
|---|---|---|
/api/attack |
GET/POST | View or trigger attack log streaming (manual kick capability). |
/api/manual/status |
GET | Indicates whether manual mode is active. |
/api/manual/targets |
GET | List of hosts eligible for manual actions. |
/api/manual/execute-attack |
POST | Run a single attack module manually. |
/api/manual/orchestrator/start, /api/manual/orchestrator/stop |
POST | Override orchestrator lifecycle when in manual mode. |
/api/manual/pentest/lynis |
POST | Fire the on-demand Lynis SSH pentest module. |
/api/manual/scan/network, /api/manual/scan/vulnerability |
POST | Force immediate network or vulnerability scans. |
/api/automation/orchestrator/start, /api/automation/orchestrator/stop |
POST | Toggle scheduled automation workflows. |
/api/scan/arp-localnet, /api/scan/combined-network, /api/scan/nmap-ping, /api/scan/status |
GET | Read-only scan telemetry (recent runs, combined results, ping view). |
/api/scan/start-realtime, /api/scan/deep, /api/scan/host |
POST | Kick off realtime scanning, deep single-host scans, or host-specific jobs. |
| Path | Methods | Purpose |
|---|---|---|
/api/network-intelligence |
GET | Active/resolved findings for the current SSID. |
/api/network-intelligence/add-credential |
POST | Insert a credential finding (manual or scripted). |
/api/network-intelligence/add-vulnerability |
POST | Insert a vulnerability finding. |
/api/vulnerabilities, /api/vulnerabilities/grouped |
GET | Raw + grouped vulnerability lists for dashboard tabs. |
/api/vulnerability-intel |
GET | Summarized remediation intelligence (AI-ready payload). |
/api/vulnerability-report/<path:filename> |
GET | Download generated vulnerability/PDF reports. |
/api/vulnerability-scan/history |
GET | Retrieve historical vuln scan metadata. |
/api/vulnerability-scan/history/reset |
POST | Clear vuln scan history (DB + files). |
/api/threat-intelligence/dashboard |
GET | Aggregated threat intel KPI cards (feed health, counts). |
/api/threat-intelligence/enriched-findings |
GET | Per-source enriched findings (CISA/NVD/OTX). |
/api/threat-intelligence/status |
GET | Feed status + last refresh info. |
/api/threat-intelligence/trigger-vuln-scan |
POST | Force vulnerability scan when a new threat hits. |
/api/threat-intelligence/enrich-finding, /api/threat-intelligence/enrich-target |
POST | Enrich a specific CVE/host pair on demand. |
/api/threat-intelligence/download-report |
POST | Generate and download compiled threat reports. |
| Path | Methods | Purpose |
|---|---|---|
/api/ai/status |
GET | AI readiness + configured model summary. |
/api/ai/insights |
GET | Cached AI insights bundle (network summary cards). |
/api/ai/network-summary |
GET | Viking-style overall assessment text. |
/api/ai/vulnerabilities |
GET | Structured vulnerability analysis from GPT-5. |
/api/ai/weaknesses |
GET | Attack-path assessment generated by AI. |
/api/ai/clear-cache |
POST | Flush in-memory AI cache. |
/api/ai/token |
GET/POST/DELETE | Preview, save, or remove the OpenAI API key via EnvManager. |
| Path | Methods | Purpose |
|---|---|---|
/api/wifi/interfaces |
GET | Enumerate WLAN interfaces + capabilities. |
/api/wifi/status |
GET | Current Wi-Fi connection state, RSSI, validation counters. |
/api/wifi/networks |
GET | Last scan results + analytics per SSID. |
/api/wifi/log |
GET | Tail AP/Wi-Fi manager logs. |
/api/wifi/scan |
POST | Trigger a fresh Wi-Fi scan. |
/api/wifi/connect |
POST | Connect to a selected SSID (applies portal credentials). |
/api/wifi/disconnect |
POST | Drop current Wi-Fi connection. |
/api/wifi/reconnect |
POST | Retry last-known SSID. |
/api/wifi/forget |
POST | Remove SSID from known-network list. |
/api/wifi/exit-ap |
POST | Leave AP mode and resume STA attempts. |
/api/wifi/ap/enable, /api/wifi/ap/start, /api/wifi/ap/stop, /api/wifi/ap/exit |
POST | Manage AP lifecycle flags and hostapd/dnsmasq processes. |
/api/wifi/force-recovery |
POST | Invoke Wi-Fi failsafe routines (restart services, clean state). |
| Path | Methods | Purpose |
|---|---|---|
/api/bluetooth/devices |
GET | Enumerate seen Bluetooth devices. |
/api/bluetooth/status |
GET | Bluetooth adapter state, discoverability, logs. |
/api/bluetooth/diagnose |
GET | Run built-in diagnostics to check stack health. |
/api/bluetooth/enable, /api/bluetooth/disable |
POST | Toggle adapter power. |
/api/bluetooth/discoverable/on, /api/bluetooth/discoverable/off |
POST | Control discoverability. |
/api/bluetooth/scan/start, /api/bluetooth/scan/stop |
POST | Start/stop discovery scans. |
/api/bluetooth/enumerate |
POST | Enumerate profiles/services on a target device. |
/api/bluetooth/pair, /api/bluetooth/unpair |
POST | Manage device pairing. |
/api/bluetooth/pentest/blueborne-scan, /api/bluetooth/pentest/beacon-track, /api/bluetooth/pentest/exfiltrate, /api/bluetooth/pentest/track-movement |
POST | Specialized BLE pentest modules. |
/api/bluetooth/pentest/report |
GET | Retrieve the latest BLE pentest report. |
/api/bluetooth/pentest/beacon-track etc. |
POST | Additional pentest workflows (credential exfil, tracking). |
| Path | Methods | Purpose |
|---|---|---|
/api/system/status |
GET | CPU/RAM/disk/process overview (ResourceMonitor-backed). |
/api/system/network-stats |
GET | Low-level network interface stats. |
/api/system/processes |
GET | Running process list (filtered). |
/api/system/check-updates |
GET | Git + pip update availability. |
/api/system/update |
POST | Run git pull + pip sync (blocking). |
/api/system/stash-update |
POST | Stash dirty tree and update safely. |
/api/system/fix-git |
POST | Apply safe.directory fix when running off removable media. |
/api/system/reboot |
POST | Reboot the device. |
/api/system/restart-service |
POST | Restart a named systemd service. |
/api/debug/ai-service, /api/debug/orchestrator-status, /api/debug/connectivity-tracking, /api/debug/scanned-networks, /api/debug/test-robust-tracking, /api/debug/verbose-logs |
GET | Deep-dive diagnostics per subsystem. |
/api/debug/force-arp-scan |
POST | Immediate ARP scan for troubleshooting. |
| Path | Methods | Purpose |
|---|---|---|
/api/pwnagotchi/status |
GET | Current Pwnagotchi install/switch state. |
/api/pwnagotchi/install |
POST | Kick off the installer script. |
/api/pwnagotchi/logs |
GET | Stream installer/service logs. |
/api/pwnagotchi/swap |
POST | Schedule Ragnar ↔ Pwnagotchi mode swap. |
| Path | Methods | Purpose |
|---|---|---|
/api/kill |
POST | Authenticated educational kill switch that wipes DBs, data directory, and repo (requires confirmation=ERASE_ALL_DATA). |
README.md– feature overview and quick start.INSTALL.md– detailed installation walkthrough.AI_INTEGRATION.md– instructions for GPT-5 Nano setup.KILL_SWITCH.md– secure wipe procedure.- Source files referenced in this spec for deeper context.