Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - spen1995

#1
also worth mentioning code might not be perfect. as built with help of claude code. use at own risk.
#3
[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.


(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, 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 — Download
Download claudeids-plugin.tar.gz attached to this post.

Step 2 — Copy to your OPNsense box
scp claudeids-plugin.tar.gz root@192.168.1.1:/tmp/

Step 3 — SSH in and run the install script
ssh 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 browser

Press Ctrl+Shift+R. Claude IDS will appear under Services in the left sidebar.

Step 5 — Add your API key

Go 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-triage

In 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

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]