- 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.