[size=18]
ClaudeIDS — Claude AI Alert Triage Plugin for OPNsense[/size]
Integrates the Anthropic Claude AI API into OPNsense as a native MVC plugin for automated IDS/IPS alert triage. Turns raw Suricata eve.json events into structured, actionable security intelligence — severity rating, block/monitor/investigate verdict, MITRE ATT&CK tactic, extracted IOCs, confidence score, and a plain-English recommended action.
Tested on OPNsense 25.x. Built and shared by gh0st.
(https://i.imgur.com/placeholder.png)
(Screenshot: Claude IDS triage console showing a live result with MITRE tactic, IOCs, confidence score and auto-block button)
[size=14]
What it does[/size]
- Manual triage console — paste any Suricata eve.json line, Zenarmor alert, or raw log entry and get a full structured triage result in seconds
- Auto-triage daemon — a background Python watcher tails eve.json and automatically triages every alert/anomaly event as it fires
- Auto-block integration — when Claude returns a block verdict above your configured severity threshold, the source IP is added to a named pf alias table automatically
- MITRE ATT&CK mapping — every result includes the relevant tactic, IOC list, confidence score (0–100), and a specific recommended action
- Native OPNsense MVC plugin — full plugin structure with model, controller, view, ACL, and menu registration. Appears under Services in the sidebar just like any other plugin
- Configurable — choose your Claude model (Sonnet recommended, Haiku for high-volume, Opus for depth), max tokens, block severity threshold, alias name, and eve.json path
[size=14]
Example triage output[/size]
Input: a Suricata
ET SCAN Potential SSH Scan alert from an external IP targeting port 22.
{
"status": "ok",
"severity": "medium",
"verdict": "investigate",
"summary": "External IP 198.51.100.22 is conducting potential SSH scanning
activity against internal server 10.0.0.1 on port 22.",
"reasoning": "The alert indicates reconnaissance activity with unidirectional
traffic (4 packets sent, 0 received) suggesting connection attempts
without successful establishment. The source IP is probing SSH
which could indicate automated scanning or brute force preparation.",
"recommended_action": "Check firewall logs for additional connection attempts
from this IP, review SSH auth logs on 10.0.0.1, and
consider rate limiting or blocking if pattern continues.",
"src_ip": "198.51.100.22",
"dst_ip": "10.0.0.1",
"ioc": ["198.51.100.22"],
"mitre_tactic": "Discovery",
"confidence": 75,
"timestamp": "2026-03-15T03:55:13Z"
}
[size=14]
Requirements[/size]
- OPNsense 23.x or later (tested on 25.x / FreeBSD 14)
- Anthropic API key — sign up at console.anthropic.com (https://console.anthropic.com), requires credits (very cheap — Haiku is ~$0.001 per triage)
- Suricata IDS running with eve.json output enabled (for auto-triage)
- PHP 8.x and Python 3.x — both bundled with OPNsense, nothing extra to install
[size=14]
Installation[/size]
Step 1 — DownloadDownload
claudeids-plugin.tar.gz attached to this post.
Step 2 — Copy to your OPNsense boxscp claudeids-plugin.tar.gz root@192.168.1.1:/tmp/
Step 3 — SSH in and run the install scriptssh root@192.168.1.1
cd /tmp && tar -xzf claudeids-plugin.tar.gz && sh claudeids-plugin/install.sh
The script copies all files, registers the plugin, clears caches, and restarts the web GUI automatically.
Step 4 — Hard refresh your browserPress
Ctrl+Shift+R. Claude IDS will appear under
Services in the left sidebar.
Step 5 — Add your API keyGo to
Services → Claude IDS → Settings. Paste your Anthropic API key, click
Save Settings, then
Test API Connection. The status chip in the top-right will turn green.
Step 6 (optional) — Set up auto-block- Go to Firewall → Aliases → Add
- Name: ClaudeIDS_Blocklist, Type: Host(s), leave content empty
- Create a firewall block rule using this alias as the source
- Back in Claude IDS Settings, enable Auto-block on verdict: block
Step 7 (optional) — Enable auto-triageIn Settings, toggle on
Auto-triage daemon. This starts a background watcher that tails your Suricata eve.json and triages every alert automatically. Results appear in the History tab and are logged to
/var/log/claudeids/triage.json.
[size=14]
File layout (what gets installed)[/size]
/usr/local/etc/inc/plugins.inc.d/claudeids.inc plugin registration
/usr/local/opnsense/mvc/app/
controllers/OPNsense/ClaudeIDS/
IndexController.php UI page controller
Api/TriageController.php REST API + Claude calls
models/OPNsense/ClaudeIDS/
ClaudeIDS.xml / ClaudeIDS.php settings model
ACL/ACL.xml access control
Menu/Menu.xml sidebar registration
views/OPNsense/ClaudeIDS/
index.volt dashboard UI
/usr/local/sbin/claudeids-watcher.py auto-triage daemon
/usr/local/opnsense/service/conf/actions.d/claudeids.conf configd actions
/var/log/claudeids/triage.json triage history (runtime)
/var/log/claudeids/watcher.log daemon log (runtime)
[size=14]
REST API endpoints[/size]
All endpoints require an OPNsense authenticated session (same as any other API call).
POST /api/claudeids/triage/analyze triage a single alert (alert=<string>)
POST /api/claudeids/triage/batch triage an array (alerts=<json array>)
GET /api/claudeids/triage/history last 200 triage records
POST /api/claudeids/triage/block manually block an IP (ip=<addr>)
GET /api/claudeids/triage/getSettings read current settings
POST /api/claudeids/triage/saveSettings write settings to config.xml
[size=14]
Uninstalling[/size]
sh /tmp/claudeids-plugin/uninstall.sh
Stops the daemon and removes all installed files. Your API key and settings remain in
/conf/config.xml under
//OPNsense/ClaudeIDS — remove manually if desired.
[size=14]
Important notes[/size]
- Use sh install.sh — not ./install.sh. OPNsense uses tcsh as its default shell. The install script must be run explicitly with sh to get a POSIX shell.
- Not an official plugin. This is a community plugin installed manually. It will not survive a full factory reset. Re-run install.sh after major OPNsense firmware upgrades.
- API key security. The Anthropic API key is stored in OPNsense's config.xml. Enable config encryption if you haven't already (System → Settings → Administration → Secure Shell), and restrict config backup access.
- Zenarmor. Zenarmor does not write to eve.json. Use the manual triage console to paste Zenarmor alerts, or pipe /var/log/sunny.log to the API endpoint manually.
- Model choice. claude-sonnet-4 is recommended for balanced quality and cost. Use claude-haiku-4 for high-volume auto-triage on busy networks. claude-opus-4 for the most thorough analysis on critical alerts.
[size=14]
How it works internally[/size]
The plugin sends each alert to the Claude API with a security analyst system prompt that instructs it to return a strict JSON object. The system prompt is tuned for OPNsense/Suricata context — it knows about Zenarmor categories, Suricata severity levels, and common home lab / small business threat patterns. The PHP controller strips any markdown fences from the response, parses the JSON, and returns it to the UI or logs it to the history file.download her (https://drive.google.com/file/d/1H5655Ecwd3lSgoFOSmgCLjqVJ0GCcE82/view?usp=drive_link)
The auto-triage watcher is a plain Python 3 script that uses only stdlib (no pip installs needed). It reads the eve.json path from the OPNsense config via the REST API, seeks to EOF on startup, and processes new lines as they appear. It re-fetches settings every 60 seconds so changes in the UI are picked up without a restart.
[size=12]
Built by gh0st — MIT License — feedback and PRs welcome[/size]
also worth mentioning code might not be perfect. as built with help of claude code. use at own risk.