Posted on
Artificial Intelligence

Artificial Intelligence SIEM Integration

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

Artificial Intelligence SIEM Integration: A Linux-first, Bash-powered Guide

Security teams aren’t short on alerts—they’re short on time. Your SIEM ingests millions of events, but turning that firehose into decisions is the hard part. AI can help by enriching, prioritizing, and explaining events as they land, letting analysts focus on what matters.

In this post, you’ll learn why AI + SIEM is a force multiplier and how to wire up a practical, Linux/Bash-first enrichment pipeline that:

  • Streams Linux logs as JSON

  • Classifies and tags events with a local AI model

  • Ships enriched events back to your SIEM for faster triage

No heavy frameworks required—just curl, jq, rsyslog, and a small script.


Why AI + SIEM is worth it

  • Cut alert fatigue: AI summarizes noisy logs into human-friendly context and tags suspicious patterns.

  • Faster triage: Auto-assign severity and MITRE ATT&CK-aligned tags so analysts know where to look first.

  • Cover the unknowns: LLMs help surface “weird” behavior that doesn’t match static rules.

  • Keep data on-prem: Run a local model to avoid sending sensitive logs to external services.


What we’ll build (in ~30 minutes)

A minimal enrichment loop: 1. Stream Linux events (journalctl) as JSON. 2. Call a local AI model to assign severity, tags, and reasons. 3. Merge the AI output into each event. 4. Send enriched events to your SIEM via syslog.

You can later expand this to more sources (auditd, nginx, containers) and more powerful models.


Prerequisites (install via your package manager)

We’ll use jq for JSON, curl for HTTP, rsyslog for forwarding, and auditd (optional) for deeper host telemetry.

  • Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y jq curl rsyslog auditd
sudo systemctl enable --now rsyslog
sudo systemctl enable --now auditd
  • RHEL/CentOS/Fedora (dnf):
sudo dnf install -y jq curl rsyslog audit
sudo systemctl enable --now rsyslog
sudo systemctl enable --now auditd
  • openSUSE/SLES (zypper):
sudo zypper refresh
sudo zypper install -y jq curl rsyslog audit
sudo systemctl enable --now rsyslog
sudo systemctl enable --now auditd

Tip: If your distro doesn’t use systemd/journald, replace journalctl with a tail on your log files (e.g., /var/log/auth.log or /var/log/secure).


Step 1: Install a local AI model (Ollama)

We’ll run a local LLM so sensitive logs never leave the box.

  • Install Ollama:
curl -fsSL https://ollama.com/install.sh | sh
  • Pull a small, capable model (adjust size to your hardware):
ollama pull llama3:8b
  • Quick test:
echo "Hello" | ollama run llama3:8b

Ollama exposes an HTTP API at http://127.0.0.1:11434 by default.

Security note: Keep the Ollama API bound to localhost unless you’ve locked it down.


Step 2: Stream Linux logs as JSON

For a focused demo, let’s follow SSH events. On systemd systems:

journalctl -f -u ssh.service -o json

If you don’t use systemd, tail the file directly:

  • Debian/Ubuntu:
tail -F /var/log/auth.log
  • RHEL/Fedora:
tail -F /var/log/secure

We’ll use the journald JSON output in the next step because it’s structured out of the box.


Step 3: Bash-based AI enrichment script

Create ai-enrich.sh and make it executable. It reads JSON lines from stdin, asks the local model to classify/annotate, merges the result, and prints enriched JSON.

#!/usr/bin/env bash
set -euo pipefail

MODEL="${MODEL:-llama3:8b}"
OLLAMA_URL="${OLLAMA_URL:-http://127.0.0.1:11434}"

enrich_line() {
  local line="$1"

  # Build a strict JSON-only prompt
  local prompt
  prompt=$(jq -rn --arg ev "$line" '
    "You are a SOC analyst. You will receive one Linux log event as JSON (journald format).
Produce STRICT JSON only (no prose), with keys:
  severity: one of [\"low\", \"medium\", \"high\", \"critical\"]
  reason: short string
  tags: array of lowercase strings (e.g., [\"ssh\", \"auth\", \"bruteforce\"])
  mitre: array of ATT&CK technique IDs if applicable (e.g., [\"T1110\"]) else []
  user: username if present else null
  src_ip: IPv4/IPv6 if present else null

Event: " + $ev
  ')

  # Ask the local model; Ollama returns {response: "..."} where response is a JSON string
  local payload resp analysis
  payload=$(jq -cn --arg model "$MODEL" --arg prompt "$prompt" '{model:$model, prompt:$prompt, stream:false}')
  resp=$(curl -sS "$OLLAMA_URL/api/generate" -H 'Content-Type: application/json' -d "$payload" | jq -r '.response')

  # The response should be a JSON object in text form; parse it safely
  if ! analysis=$(printf '%s' "$resp" | jq -c . 2>/dev/null); then
    # Fallback if the model ever returns non-JSON: wrap it as reason
    analysis=$(jq -cn --arg reason "$resp" '{severity:"low", reason:$reason, tags:[], mitre:[], user:null, src_ip:null}')
  fi

  # Merge AI analysis under .ai
  printf '%s\n' "$line" | jq -c --argjson ai "$analysis" '. + {ai: $ai}'
}

# Read JSON lines from stdin
while IFS= read -r line; do
  # Skip empty lines
  [ -z "$line" ] && continue
  enrich_line "$line"
done

Make it executable:

chmod +x ai-enrich.sh

Run it on your SSH journal stream:

journalctl -f -u ssh.service -o json | ./ai-enrich.sh

You’ll see each event augmented like:

{"_SYSTEMD_UNIT":"ssh.service",...,"MESSAGE":"Failed password for invalid user bob from 203.0.113.10 port 50432 ssh2","ai":{"severity":"high","reason":"Repeated failed SSH authentication from external IP","tags":["ssh","auth","bruteforce"],"mitre":["T1110"],"user":"bob","src_ip":"203.0.113.10"}}

Step 4: Ship enriched events to your SIEM

Option A (quick): Pipe to syslog with logger and forward a facility (local6) to your SIEM.

  • Send enriched JSON to local syslog:
journalctl -f -u ssh.service -o json \
  | ./ai-enrich.sh \
  | logger -p local6.info -t ai-enricher
  • Forward local6.* to your SIEM with rsyslog. Create /etc/rsyslog.d/60-local6-to-siem.conf:
# Send local6.* to SIEM over TCP 514 with a JSON-friendly template
template(name="JsonAi" type="string" string="<%pri%>1 %timegenerated% %hostname% ai-enricher - - - %msg%\n")
local6.* action(type="omfwd" target="SIEM_IP_OR_FQDN" port="514" protocol="tcp" Template="JsonAi")
  • Restart rsyslog:
sudo systemctl restart rsyslog

Now your SIEM receives clean, enriched JSON with ai.severity, ai.tags, ai.mitre, etc. Create saved searches or detection rules that key off ai.severity >= high to slash noise.

Option B (API ingestion): If your SIEM supports HTTP ingestion (e.g., Elastic/Opensearch custom endpoint, Graylog GELF HTTP), replace the logger line in the pipeline with a curl POST to your SIEM’s HTTP endpoint.


Step 5: Real-world examples you can try

  • SSH brute-force

    • Generate a few bad logins from a test box:
    ssh invalid@yourhost.example -p 22
    
    • The model should tag as bruteforce with T1110 and high severity.
  • Suspicious sudo

    • Trigger a sudo failure/success:
    sudo -k; sudo ls /root
    
    • Expect tags like ["sudo","privilege"] and a reason about privilege escalation attempts.
  • New geolocation or ASN (optional enhancement)

    • Extend the script to call a local GeoIP database first, then pass that context into the prompt for better tagging.

Hardening, performance, and cost tips

  • Keep it local: Prefer on-prem models for sensitive logs.

  • Constrain output: Always demand strict JSON to make parsing deterministic.

  • Batch where possible: For very high throughput, consider micro-batching or summarizing per-connection/source IP.

  • Throttle and cache: Rate-limit prompts on repetitive messages; cache AI outputs per message signature.

  • Model size vs. latency: Start with 7B–8B models; scale up only if your use case needs deeper reasoning.

  • Guardrails: Treat AI severity as advisory. Pair with traditional rules and thresholds.


Conclusion and next steps

AI won’t replace your SIEM—it’ll make it smarter. With a few lines of Bash, you added context, severity, and MITRE tags to raw logs and shipped them to your existing dashboards.

Your next moves:

  • Expand sources: feed auditd, web server, and container logs into the same enrichment loop.

  • Tune prompts and tags to match your playbooks.

  • Wire high-severity AI alerts to tickets or chat for faster MTTR.

  • Consider fine-tuning a local model on your environment’s logs for even better accuracy.

If you found this useful, try rolling it out to one high-signal source this week (SSH or sudo), measure triage time saved, and iterate.