Wazuh-LLM Cisco Network Incident Response

Automated network incident response system for Cisco IOS-XE routers and switches. Takes Wazuh SIEM alerts, classifies them with a fine-tuned LLM, queries live device state via RESTCONF, generates CLI fix commands using domain-specific LoRA adapters, and applies the fixes automatically via RESTCONF PATCH.

Two backends are provided: a manual 3-script pipeline for operator-controlled workflows, and a fully autonomous daemon that watches Wazuh logs and resolves incidents end-to-end without human intervention.


Architecture

Backend 1 β€” Manual Pipeline (3 scripts)

Wazuh alerts file
        |
        v
[runners/prefilter.py]       filter level-12, drop auth noise
        |
        v
[runners/pipeline.py]
  Stage 1  Wazuh LLM (Ollama)       incident_type, severity, IOCs
  Stage 2  Show command lookup       deterministic table (incident -> show cmds)
  Stage 3  RESTCONF mapping          deterministic table (show cmd -> YANG path)
  Stage 4  Domain routing            selects correct LoRA adapter
        |
        v  creates show_outputs/alert_NNN_DEVICE_INCIDENT/
              restconf_commands.json   <- execute these GETs against routers
              alert_info.json

   (operator executes RESTCONF GETs and drops response JSONs into the folder)

        |
        v
[runners/run_fix.py]         polls folders, runs domain LoRA
        |
        |-- fix_commands.txt              CLI fix commands (human readable)
        +-- restconf_fix_commands.json    RESTCONF PATCH ops to apply the fix
        +-- pipeline_fix_output.jsonl     full record of all alerts processed

Backend 2 β€” Autonomous Daemon (always-on)

/var/ossec/logs/alerts/alerts.json   (Wazuh live output, tailed continuously)
        |
        v
[backend/daemon.py]
  Watch    tail alerts file, detect new entries (level 7-12)
  Detect   SSH brute-force: 5+ failures from same IP within 5-minute window
        |
        v  per alert, fully automatic:
  [1]  Extract device       IP -> device map
  [2]  Classify             Ollama wazuh-llama -> incident_type, IOCs, severity
  [3]  Show commands        deterministic table lookup
  [4]  RESTCONF GETs        execute live against device, collect YANG state
  [5]  Domain LoRA          generate CLI fix commands
  [6]  RESTCONF PATCHes     apply fixes directly to device
  [7]  Log result           managed_incidents.jsonl + managed_incidents.log
        |
        v  per-alert folder:
              restconf_get_results.json    what the device reported
              fix_commands.txt             CLI commands the LLM generated
              restconf_fix_commands.json   PATCH ops with YANG bodies
              patch_results.json           HTTP status of each PATCH

LoRA Adapters

18 domain-specific adapters fine-tuned on Hermes-3-Llama-3.1-8B (r=8, alpha=32):

Domain Adapter Incidents covered
OSPF incidents/ospf/ospf1 Neighbor down, full-to-down, adjacency loss
OSPF incidents/ospf/ospf2 ExStart/Exchange stuck, Init stuck, 2-Way
OSPF incidents/ospf/ospf3 Auth, hello/dead mismatch, area, network-type, MTU
OSPF incidents/ospf/ospf4 LSA flood, LSDB inconsistency, redistribution
BGP incidents/bgp/lora_llm_bgp1 Session flap, hold-timer expiry, neighbor reset
BGP incidents/bgp/lora_llm_bgp2 Prefix limit, route leak, path selection
BGP incidents/bgp/lora_llm_bgp3 Missing RIB routes, next-hop-self, AFI-SAFI mismatch
Sec incidents/security/lora_llm_sec1 ACL blocking legitimate traffic
Sec incidents/security/lora_llm_sec2 ACL misconfiguration (protocol, wildcard, direction)
Sec incidents/security/lora_llm_sec3 Excessive denies, brute force, port scan
Switch incidents/switch/lora_llm_switch1 MAC flapping, STP topology change, err-disable
Switch incidents/switch/lora_llm_switch2 Port security, duplex/speed mismatch
Switch incidents/switch/lora_llm_switch3 VLAN mismatch, trunk negotiation, storm control
Service incidents/service/lora_llm_service1 DHCP conflict, starvation, IP conflict
Service incidents/service/lora_llm_service2 DNS failure, NTP unsync, ARP spoofing
Sys incidents/sys/lora_llm_sys1 High CPU, memory exhaustion, process crash
Sys incidents/sys/lora_llm_sys2 Interface flap, duplex/speed mismatch
Sys incidents/sys/lora_llm_sys3 Reload, environmental, general system health

Requirements

pip install -r requirements.txt

The Wazuh LLM stage uses Ollama with a local wazuh-llama model:

# Install Ollama: https://ollama.com
ollama create wazuh-llama -f Modelfile

Quick Start β€” Manual Pipeline

# Step 1 β€” pre-filter raw Wazuh export
python runners/prefilter.py --input alerts.json --output s_alerts.jsonl

# Step 2 β€” classify + build RESTCONF show commands + create per-alert folders
python runners/pipeline.py --input s_alerts.jsonl --show-dir show_outputs

# Step 3 β€” execute the RESTCONF GETs listed in each folder's restconf_commands.json
#           and save JSON responses into the same folder

# Step 4 β€” run domain LoRA, generate fix commands + RESTCONF PATCH ops
python runners/run_fix.py --show-dir show_outputs

Per-alert output folder after all steps:

show_outputs/alert_001_R1_ospf_neighbor_down/
    alert_info.json              alert metadata
    restconf_commands.json       GET commands (written by pipeline.py)
    show_ip_ospf_neighbor.json   RESTCONF GET response (you drop this)
    fix_commands.txt             CLI fix commands (written by run_fix.py)
    restconf_fix_commands.json   RESTCONF PATCH ops (written by run_fix.py)

Quick Start β€” Autonomous Daemon

# Standard β€” watch live Wazuh alerts, auto-apply fixes (level 7-12)
python backend/daemon.py

# Dry run β€” classify + generate commands, but do NOT PATCH devices
python backend/daemon.py --dry-run

# Custom alert file and thresholds
python backend/daemon.py \
    --alerts /var/ossec/logs/alerts/alerts.json \
    --min-level 7 \
    --ssh-threshold 5 \
    --ssh-window 300 \
    --poll 3

The daemon tail-follows the Wazuh alerts file and processes each alert automatically end-to-end with no operator involvement.

Daemon output files

File Content
managed_incidents.jsonl Machine-readable: one JSON record per handled alert
managed_incidents.log Human-readable: one summary block per alert
daemon.log Full debug log of all daemon activity
show_outputs/alert_NNN_*/ Per-alert audit folder (GET results, fix, patch results)

SSH Brute-Force Detection

The daemon tracks failed SSH login alerts independently of the level filter. When 5 or more failures from the same source IP occur within 5 minutes, a synthetic ssh_brute_force incident is triggered and the full pipeline runs β€” even if each individual alert is below the level threshold.

Tune with --ssh-threshold N --ssh-window SECONDS.


Device Configuration

Edit the maps at the top of runners/pipeline.py and backend/daemon.py to match your network:

SOURCE_IP_DEVICE_MAP = {
    "10.10.10.10": "R1",
    "2.2.2.2":     "R2",
    # ...
}
DEVICE_MGMT_IP = {
    "R1": "10.10.10.10",   # management IP used for RESTCONF
    "R2": "2.2.2.2",
    # ...
}

Router credentials: ROUTER_USER / ROUTER_PASS constants (default: admin / cisco123!).


RESTCONF

All communication uses RESTCONF over HTTPS (port 443) with Cisco IOS-XE YANG models.

Read (GET) β€” _RESTCONF_RULES table maps each show command to its YANG path:

show ip ospf neighbor  ->  /restconf/data/Cisco-IOS-XE-ospf-oper:ospf-oper-data/ospf-state
show ip bgp summary    ->  /restconf/data/Cisco-IOS-XE-bgp-oper:bgp-state-data/bgp-route-vrfs
show interfaces        ->  /restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces
...

Write (PATCH) β€” CLI fix commands are parsed into context blocks and converted to RESTCONF PATCH operations with YANG-native JSON bodies:

interface GigabitEthernet0/0    ->  PATCH .../interface/GigabitEthernet=0%2F0
 ip ospf hello-interval 10           body: Cisco-IOS-XE-ospf:ospf hello-interval 10
router bgp 65001                ->  PATCH .../router/bgp=65001
 neighbor 10.0.0.2 timers 30 90      body: neighbor timers keepalive 30 holdtime 90
ip access-list extended INBOUND ->  PATCH .../ip/access-list/extended=INBOUND

Supported YANG modules include: Cisco-IOS-XE-ospf-oper, Cisco-IOS-XE-bgp-oper, Cisco-IOS-XE-interfaces-oper, Cisco-IOS-XE-acl-oper, Cisco-IOS-XE-spanning-tree-oper, Cisco-IOS-XE-vlan-oper, Cisco-IOS-XE-dhcp-oper, Cisco-IOS-XE-arp-oper, Cisco-IOS-XE-nat-oper, Cisco-IOS-XE-ntp-oper, Cisco-IOS-XE-process-cpu-oper, Cisco-IOS-XE-process-memory-oper, Cisco-IOS-XE-native


Training

Training scripts and datasets are in training/ and datasets/. Each adapter was trained on 900–1500 examples with LoRA (r=8, alpha=32, dropout=0.1) targeting q_proj and v_proj on Hermes-3-Llama-3.1-8B.

python training/train_ospf1.py
python training/train_bgp1.py
# etc.

Lab Topology

Tested on a 4-router + 4-switch Cisco IOS-XE lab:

  • R1 / R2 / R3 / R4 β€” IOS-XE routers running OSPF + BGP
  • SW1 / SW2 β€” distribution switches
  • ACCESS-SW1 / ACCESS-SW2 β€” access switches
  • R4 β€” DHCP server (192.168.40.0/24 pool)
  • Wazuh manager collecting syslog from all devices

Project Files

Path Description
runners/prefilter.py Pre-filter raw Wazuh export (level filter + brute-force detection)
runners/pipeline.py Manual backend Phase 1: classify, map RESTCONF GETs, create folders
runners/run_fix.py Manual backend Phase 2: run domain LoRA, generate and map fix commands
backend/daemon.py Autonomous daemon: watches live Wazuh alerts, resolves incidents end-to-end
Modelfile Ollama model definition for the Wazuh alert classifier
models/base/ Hermes-3-Llama-3.1-8B base model
models/incidents/ 18 domain-specific LoRA adapters
models/registry.json Adapter name -> path registry
datasets/ Training datasets (JSONL, one incident type per file)
training/ Training scripts (one per adapter)
cases/ Incident test cases used for evaluation

Citation

@misc{wazuh-llm-cisco-2025,
  title  = {Wazuh-LLM Cisco Network Incident Response},
  year   = {2025},
  url    = {https://huggingface.co/YOUR_USERNAME/wazuh-llm-cisco}
}
Downloads last month
-
GGUF
Model size
8B params
Architecture
llama
Hardware compatibility
Log In to add your hardware

4-bit

Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for JoeiBanana/ai-network-llms

Adapter
(278)
this model