Posted on
Artificial Intelligence

AI Agents for Security Operations

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

AI Agents for Security Operations: Bash-first Playbooks That Actually Help

Security teams are drowning in alerts, tickets, and log lines. What if you could drop in small, Unix-y AI agents that summarize noisy logs, enrich indicators, and even scaffold detection rules—without ripping up your stack? In this post, we’ll build practical, Bash-friendly micro-agents that sit alongside your existing tools and make your SOC faster and calmer.

You’ll get:

  • Why AI agents are worth your time (and where they fail)

  • 4 actionable, real-world mini-projects you can run today

  • Copy/paste installation commands for apt, dnf, and zypper

  • Minimal Bash + curl + jq code that works with a local LLM (Ollama) or a hosted one (OpenAI)

Why this is worth doing

  • Your logs are full of natural language-ish noise. LLMs are strong at reading messy text and explaining “what changed.”

  • The worst SOC toil is pattern-matching and summarization. That’s an LLM superpower, especially for Tier‑1 triage and IOC enrichment.

  • You don’t need a new platform. A few scripts can wrap existing tools (journalctl, Zeek, YARA, Sigma) and add an “explain this” button.

  • Guardrails matter. Keep humans-in-the-loop, test rules, and never let an AI push to prod unattended.

Below are four micro-agents that are small enough to audit, easy to deploy, and actually useful.


Prerequisites (copy/paste)

Install core CLI tools: curl, jq, whois, dig, Python, pipx, Git, YARA, and Zeek.

  • Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y curl jq whois dnsutils python3 python3-pip pipx git yara zeek
pipx ensurepath
  • Fedora/RHEL/CentOS (dnf):
sudo dnf install -y curl jq whois bind-utils python3 python3-pip pipx git yara zeek
pipx ensurepath
  • openSUSE (zypper):
sudo zypper refresh
sudo zypper install -y curl jq whois bind-utils python3 python3-pip pipx git yara zeek
pipx ensurepath

LLM options:

  • Local (recommended for sensitive data): Ollama
curl -fsSL https://ollama.com/install.sh | sh
# Start the service and pull a small model
ollama serve & disown
ollama pull llama3:8b
  • Hosted (OpenAI): set your API key
export OPENAI_API_KEY="sk-..."
# Optional: choose a model
export OPENAI_MODEL="gpt-4o-mini"

Tip: These agents auto-detect Ollama on localhost; if not found, they’ll use OPENAI_API_KEY when present.


Reusable helper: LLM call from Bash

Create a small helper snippet once; we’ll reuse it in all the agents.

ask_llm() {
  # Usage: ask_llm "your prompt text"
  local prompt="$1"
  # Prefer local Ollama if available
  if curl -sS http://localhost:11434/api/tags >/dev/null 2>&1; then
    curl -s http://localhost:11434/api/generate \
      -d "$(jq -n --arg m "${OLLAMA_MODEL:-llama3:8b}" --arg p "$prompt" '{model:$m,prompt:$p,stream:false}')" \
      | jq -r '.response'
  elif [ -n "$OPENAI_API_KEY" ]; then
    curl -s https://api.openai.com/v1/chat/completions \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer '"$OPENAI_API_KEY"'" \
      -d "$(jq -n \
            --arg m "${OPENAI_MODEL:-gpt-4o-mini}" \
            --arg sys "You are a careful SOC analyst. Be concise, include reasoning, and call out uncertainty." \
            --arg usr "$prompt" \
            '{model:$m,messages:[{role:"system",content:$sys},{role:"user",content:$usr}],temperature:0.2}')" \
      | jq -r '.choices[0].message.content'
  else
    echo "No LLM configured. Start Ollama or set OPENAI_API_KEY." >&2
    return 1
  fi
}

Save it in a file (e.g., llm.sh) and source it in the scripts below:

. ./llm.sh

1) Triage Agent: Summarize SSH auth noise into action

Goal: In 30 seconds, get a human-readable summary of the last hour of SSH activity: brute-force attempts, suspicious usernames, and top sources.

Real-world use: This turns 500 log lines into a 5-bullet executive brief you can paste into a ticket.

Install needs: already covered (curl, jq). Uses journalctl or /var/log/auth.log.

Script: triage-ssh.sh

#!/usr/bin/env bash
set -euo pipefail
. ./llm.sh

LOG=$(journalctl -u ssh --since "-60 min" -o short-iso 2>/dev/null | tail -n 600 || true)
if [ -z "$LOG" ] && [ -r /var/log/auth.log ]; then
  LOG=$(grep -E 'sshd|auth' /var/log/auth.log | tail -n 600 || true)
fi

if [ -z "$LOG" ]; then
  echo "No SSH logs found in the last hour." >&2
  exit 0
fi

PROMPT=$(cat <<'EOF'
Task: Summarize SSH authentication events from the past hour.

- Identify brute-force patterns (rapid failures, password spraying).

- List top source IPs and countries (if mentioned).

- Call out suspicious usernames (e.g., root, admin, oracle).

- Provide 3 brief actions (block, alert, tune fail2ban, etc.).

- Output as:
Summary
Top sources
Suspect accounts
Recommended actions
Confidence

Logs:
EOF
)
ask_llm "$PROMPT

$LOG"

Run:

bash triage-ssh.sh

2) IOC Enrichment Micro-Agent: Turn an IP or domain into a quick dossier

Goal: Given an IP or domain, collect basic OSINT with standard tools, then ask the LLM for a concise assessment.

Real-world use: Fast context for triage—e.g., “203.0.113.10 is a cloud host seen in repeated SSH failures; likely password spray.”

Extra packages:

  • whois, dig (dnsutils/bind-utils) are already in the prerequisites.

Script: enrich-ioc.sh

#!/usr/bin/env bash
set -euo pipefail
. ./llm.sh

if [ $# -lt 1 ]; then
  echo "Usage: $0 <ip-or-domain>" >&2
  exit 1
fi

IOC="$1"

WHOIS=$(whois "$IOC" 2>/dev/null | sed -E 's/\r//g' | head -n 200 || true)
DNS_A=$(dig +short A "$IOC" 2>/dev/null | paste -sd, - || true)
DNS_PTR=$(dig +short -x "$IOC" 2>/dev/null | paste -sd, - || true)

CTX=$(jq -n \
  --arg i "$IOC" \
  --arg w "${WHOIS:-N/A}" \
  --arg a "${DNS_A:-N/A}" \
  --arg ptr "${DNS_PTR:-N/A}" \
  '{ioc:$i, whois:$w, dns_a:$a, dns_ptr:$ptr}')

PROMPT=$(cat <<'EOF'
You are a SOC analyst. Using the provided raw context, produce a short enrichment report.
Include:

- What is it (hosting/provider hints, age if visible)?

- Risk signals or typical abuse (if any).

- Fit to current enterprise threats (weak/medium/strong).

- 3 actions with clear rationale (block, watchlist, none).
Be concise. If unsure, say so.
EOF
)
ask_llm "$PROMPT

Context (JSON):
$CTX"

Run:

bash enrich-ioc.sh example.com
bash enrich-ioc.sh 203.0.113.10

Optional: Add your own threat feeds or APIs (e.g., ipinfo, AbuseIPDB) and merge them into the JSON before the LLM call.


3) Detection Engineer’s Helper: Draft Sigma and YARA skeletons with guardrails

Goal: Feed a natural-language description and get back:

  • A Sigma rule (YAML) you can convert to your SIEM backend

  • A YARA rule skeleton for file-based artifacts

Real-world use: Speed up prototyping while keeping a human review and syntax checks.

Install for Sigma (pySigma CLI) and confirm YARA:

  • apt:
sudo apt install -y pipx yara
pipx ensurepath
pipx install sigma-cli
  • dnf:
sudo dnf install -y pipx yara
pipx ensurepath
pipx install sigma-cli
  • zypper:
sudo zypper install -y pipx yara
pipx ensurepath
pipx install sigma-cli

Script: gen-rules.sh

#!/usr/bin/env bash
set -euo pipefail
. ./llm.sh

DESC="${1:-}"
if [ -z "$DESC" ]; then
  echo "Usage: $0 \"Short description of behavior to detect\"" >&2
  echo "Example: $0 \"Detect repeated failed SSH logins from many IPs against one account within 10m\"" >&2
  exit 1
fi

# 1) Generate Sigma YAML
SIGMA_PROMPT=$(cat <<'EOF'
Create a Sigma rule in YAML only (no prose) matching the described behavior.
Constraints:

- Valid Sigma spec.

- Put reasonable metadata (title, id: UUID placeholder, status: experimental).

- Keep it generic for Linux auth logs if applicable.

- Add detection with selection + condition and a simple timeframe if needed.

- Keep false positives section minimal but realistic.
EOF
)
SIGMA_OUT=$(ask_llm "$SIGMA_PROMPT

Behavior description:
$DESC")

echo "$SIGMA_OUT" > rule.yml
echo "[*] Wrote Sigma rule.yml"
# Simple parse check: convert to a backend; exit non-zero on failure
if sigma convert -t es-qs rule.yml >/dev/null 2>&1; then
  echo "[✓] Sigma parse/convert OK"
else
  echo "[!] Sigma conversion failed. Please review rule.yml" >&2
fi

# 2) Generate YARA rule
YARA_PROMPT=$(cat <<'EOF'
Create a YARA rule that could help detect a file associated with the described behavior.
Constraints:

- Output a single valid YARA rule (no comments outside the rule).

- Use generic strings/regex; no hard-coded PII or secrets.

- Name the rule descriptively with CamelCase.
EOF
)
YARA_OUT=$(ask_llm "$YARA_PROMPT

Behavior description:
$DESC")

echo "$YARA_OUT" > rule.yar
echo "[*] Wrote YARA rule.yar"
if yarac rule.yar /tmp/compiled.yarc >/dev/null 2>&1; then
  echo "[✓] YARA compiles OK"
else
  echo "[!] YARA compile failed. Please review rule.yar" >&2
fi

Run:

bash gen-rules.sh "Detect repeated failed SSH logins from many IPs against one account within 10m"

Then manually review and tune. Never auto-deploy rules without human approval and testing in a lab.


4) Zeek + AI: Explain network activity from a PCAP

Goal: Run Zeek on a PCAP (or live interface), then ask the LLM to highlight notable flows, unusual ports, and suspicious user agents.

Real-world use: Quick readout during an incident to guide deeper investigation.

Ensure Zeek is installed (see prerequisites).

Script: zeek-summarize.sh

#!/usr/bin/env bash
set -euo pipefail
. ./llm.sh

if [ $# -lt 1 ]; then
  echo "Usage: $0 <pcap-file>" >&2
  exit 1
fi

PCAP="$1"
WORKDIR="$(mktemp -d)"
trap 'rm -rf "$WORKDIR"' EXIT

# Disable checksum validation (-C) to be lenient with captures
( cd "$WORKDIR" && zeek -Cr "$PCAP" )

if [ ! -s "$WORKDIR/conn.log" ]; then
  echo "No conn.log produced; check the pcap or Zeek output." >&2
  exit 1
fi

SUMMARY=$(tail -n 200 "$WORKDIR/conn.log")
PROMPT=$(cat <<'EOF'
You are a network analyst. Given Zeek conn.log lines, summarize:

- Unusual ports, protocols, or spikes

- Suspicious user agents or destinations (if visible)

- Possible data exfil or scanning behavior

- 3 next steps for investigation
Be concise and structured. If confidence is low, say why.
EOF
)
ask_llm "$PROMPT

Sample Zeek conn.log lines:
$SUMMARY"

Run:

bash zeek-summarize.sh sample.pcap

Ops tips and guardrails

  • Keep humans in the loop. Treat outputs as drafts—great for speed, not for blind trust.

  • Log redaction. Don’t send secrets, keys, or PII to hosted models. Prefer local models (Ollama) for sensitive data.

  • Be deterministic. Use stable prompt templates, temperature near 0, and save inputs/outputs for audit.

  • Measure impact. Track time saved on triage and the false-positive rate of drafted rules.


Conclusion and next steps

With a handful of Bash scripts, you’ve added AI “co-workers” to your SOC:

  • Triage SSH noise into crisp summaries

  • Enrich IOCs without leaving the terminal

  • Draft Sigma/YARA rules faster

  • Make sense of Zeek logs on demand

Next steps:

  • Put these scripts in a private repo and wire them into your ticket templates.

  • Add systemd timers for periodic triage summaries.

  • Expand data sources (Wazuh, osquery, EDR exports) and keep the human review gate.

  • If you need to stay offline, stick with Ollama and self-hosted models.

If you found this helpful, try adapting the triage agent to your highest-volume log source—and measure how much time it saves your team this week.