- Posted on
- • Artificial Intelligence
Automating Security Reports with Artificial Intelligence
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Automating Security Reports with Artificial Intelligence (A Bash-First Guide)
If your weekly “security review” is a scramble through scanner output, syslogs, and spreadsheets, you’re not alone. The raw data exists—but getting from noise to an actionable, executive-ready report costs hours you don’t have. What if a simple Bash workflow could gather key signals, summarize them with AI, and email a concise report by 7 AM every day?
In this post, you’ll build exactly that: a lightweight pipeline that collects host audit results, port scans, malware findings, and integrity checks, then hands them to an AI summarizer to produce a clean, prioritized report. We’ll do it with standard Linux tools, Bash, and a generic OpenAI-compatible API.
Why this matters:
Security teams drown in output, not in insight.
AI can convert unstructured scanner logs into risk-ranked narratives.
Bash automation is transparent, diffable, and easy to maintain.
You can run the AI step against a cloud API or a local OpenAI-compatible endpoint.
What you’ll build
A collector script that runs Lynis, Nmap, ClamAV, and AIDE, then normalizes results to JSON.
A summarizer script that uses an OpenAI-compatible API to create a concise Markdown report.
A scheduled job (cron or systemd timer) to deliver the report to your inbox daily.
1) Install prerequisites
Packages used:
- lynis (host audit), nmap (port scan), clamav (malware scan), aide (file integrity), jq (JSON), curl (HTTP), mailx/mailutils (email, optional)
Note:
Some commands may require sudo/root (e.g., AIDE initialization, deeper scans).
On RHEL/CentOS, you may need EPEL for lynis:
sudo dnf install epel-release(or the appropriate EPEL package for your version).
Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y lynis nmap clamav aide jq curl mailutils
Fedora/RHEL/CentOS (dnf):
sudo dnf install -y lynis nmap clamav aide jq curl mailx
openSUSE/SLE (zypper):
sudo zypper refresh
sudo zypper install -y lynis nmap clamav aide jq curl mailx
Optional setup:
- Initialize AIDE once before use:
sudo aide --init
sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
- Update ClamAV signatures (may run as a service on your distro):
sudo freshclam || true
2) Collect security signals with Bash
Create a collector that runs safely on a schedule, keeps logs tidy, and outputs a single JSON payload. Adjust paths and targets as needed.
#!/usr/bin/env bash
# collect_security_signals.sh
set -euo pipefail
OUT_DIR="/var/log/sec-reports"
TS="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
RUN_DIR="${OUT_DIR}/${TS}"
mkdir -p "$RUN_DIR"
# 1) Lynis host audit (no colors; capture stdout)
# Note: Lynis may exit non-zero for warnings; don't fail hard.
LYNIS_OUT="${RUN_DIR}/lynis.txt"
lynis audit system --quiet --no-colors >"$LYNIS_OUT" 2>&1 || true
# 2) Nmap quick TCP scan of localhost (no root needed with -sT)
# Adjust targets (e.g., your subnets or critical hosts)
NMAP_OUT="${RUN_DIR}/nmap.txt"
nmap -sT -Pn -T4 -p 1-1024 localhost >"$NMAP_OUT" 2>&1 || true
# 3) ClamAV malware scan on common directories
CLAMAV_OUT="${RUN_DIR}/clamscan.txt"
clamscan -r --infected --no-summary /home /var/www 2>&1 | tee "$CLAMAV_OUT" >/dev/null || true
# 4) AIDE integrity check
AIDE_OUT="${RUN_DIR}/aide.txt"
aide --check >"$AIDE_OUT" 2>&1 || true
# 5) Recent auth and kernel messages (last 24h)
JOURNAL_OUT="${RUN_DIR}/journal.txt"
if command -v journalctl >/dev/null 2>&1; then
journalctl --since "24 hours ago" -p warning -o short-iso >"$JOURNAL_OUT" || true
else
# Fallback for systems without systemd-journald
grep -E "($(date -d 'yesterday' '+%b %e')|$(date '+%b %e'))" /var/log/syslog /var/log/messages 2>/dev/null \
| grep -Ei 'fail|denied|segfault|error|auth' >"$JOURNAL_OUT" || true
fi
# Normalize to a single JSON document
JSON_OUT="${RUN_DIR}/signals.json"
jq -n \
--arg ts "$TS" \
--rawfile lynis "$LYNIS_OUT" \
--rawfile nmap "$NMAP_OUT" \
--rawfile clamav "$CLAMAV_OUT" \
--rawfile aide "$AIDE_OUT" \
--rawfile journal "$JOURNAL_OUT" \
'{
collected_at: $ts,
host: env.HOSTNAME // "unknown",
lynis: $lynis,
nmap: $nmap,
clamav: $clamav,
aide: $aide,
journal: $journal
}' >"$JSON_OUT"
echo "Collected signals: $JSON_OUT"
Make it executable:
sudo mkdir -p /var/log/sec-reports
sudo chown -R "$(whoami)":"$(whoami)" /var/log/sec-reports
chmod +x ./collect_security_signals.sh
3) Summarize with an AI that speaks “OpenAI-compatible API”
We’ll post the JSON to an AI endpoint with a clear prompt and produce a Markdown report. This pattern works with:
Cloud APIs that expose an OpenAI-compatible
/v1/chat/completionsLocal servers that emulate the same API (e.g., self-hosted OpenAI-compatible inference)
Environment variables:
AI_API_BASE (e.g., https://api.openai.com)
AI_API_KEY
AI_MODEL (e.g., gpt-4o-mini, gpt-4o, or a local model name your server exposes)
#!/usr/bin/env bash
# summarize_with_ai.sh
set -euo pipefail
OUT_DIR="/var/log/sec-reports"
LATEST_JSON="$(ls -1dt ${OUT_DIR}/* | head -n1)/signals.json"
[[ -f "$LATEST_JSON" ]] || { echo "No signals found"; exit 1; }
: "${AI_API_BASE:?Set AI_API_BASE}"
: "${AI_API_KEY:?Set AI_API_KEY}"
: "${AI_MODEL:=gpt-4o-mini}"
REPORT_MD="$(dirname "$LATEST_JSON")/report.md"
SYSTEM_PROMPT="You are a security analyst. Read raw outputs from host audits, port scans, malware scans, integrity checks, and logs.
- Produce a short, actionable Markdown report for technical readers and managers.
- Prioritize by risk and likelihood. Include clear remediation steps and an ETA estimate per item.
- Highlight: new open ports or services, malware hits, integrity changes, auth anomalies, kernel/hardware errors.
- Be concise; avoid hallucinations; cite exact lines or evidence from input where relevant.
- Output sections: Overview, High-Risk Findings, Medium/Low Findings, Notable Events, Remediation Plan, Appendix (citations)."
USER_PROMPT="$(jq -c . "$LATEST_JSON")"
PAYLOAD="$(jq -n \
--arg model "$AI_MODEL" \
--arg system "$SYSTEM_PROMPT" \
--arg user "$USER_PROMPT" \
'{
model: $model,
temperature: 0.2,
messages: [
{"role":"system","content":$system},
{"role":"user","content":$user}
]
}')"
curl -sS "${AI_API_BASE%/}/v1/chat/completions" \
-H "Authorization: Bearer ${AI_API_KEY}" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" | jq -r '.choices[0].message.content' >"$REPORT_MD"
echo "Wrote AI report: $REPORT_MD"
Example environment configuration (bash):
export AI_API_BASE="https://api.openai.com"
export AI_API_KEY="sk-REDACTED"
export AI_MODEL="gpt-4o-mini"
Local/air-gapped idea: point AI_API_BASE to your on-prem OpenAI-compatible gateway (e.g., a self-hosted inference server that exposes /v1/chat/completions). Keep sensitive payloads in-house if policy requires.
Optional: email the report
#!/usr/bin/env bash
# send_report.sh
set -euo pipefail
OUT_DIR="/var/log/sec-reports"
LATEST_DIR="$(ls -1dt ${OUT_DIR}/* | head -n1)"
REPORT="${LATEST_DIR}/report.md"
TO_ADDR="${1:-security-team@example.com}"
if command -v mail >/dev/null 2>&1; then
cat "$REPORT" | mail -s "Daily Security Report $(hostname) - $(date -u +'%Y-%m-%d')" "$TO_ADDR"
elif command -v mailx >/dev/null 2>&1; then
cat "$REPORT" | mailx -s "Daily Security Report $(hostname) - $(date -u +'%Y-%m-%d')" "$TO_ADDR"
else
echo "mail/mailx not installed; report at $REPORT"
fi
4) Automate it (cron or systemd)
Cron (run daily at 06:00 UTC):
crontab -e
Add:
0 6 * * * /path/to/collect_security_signals.sh && AI_API_BASE=https://api.openai.com AI_API_KEY=sk-REDACTED AI_MODEL=gpt-4o-mini /path/to/summarize_with_ai.sh && /path/to/send_report.sh security-team@example.com
Systemd timer (more robust logging):
Unit: /etc/systemd/system/sec-report.service
[Unit]
Description=Daily Security Report
[Service]
Type=oneshot
Environment=AI_API_BASE=https://api.openai.com
Environment=AI_API_KEY=sk-REDACTED
Environment=AI_MODEL=gpt-4o-mini
ExecStart=/path/to/collect_security_signals.sh
ExecStart=/path/to/summarize_with_ai.sh
ExecStart=/path/to/send_report.sh security-team@example.com
Timer: /etc/systemd/system/sec-report.timer
[Unit]
Description=Run Daily Security Report at 06:00 UTC
[Timer]
OnCalendar=*-*-* 06:00:00 UTC
Persistent=true
Unit=sec-report.service
[Install]
WantedBy=timers.target
Enable:
sudo systemctl daemon-reload
sudo systemctl enable --now sec-report.timer
5) Real-world patterns and tips
- Keep inputs minimal: exclude secrets and PII before sending to AI. For example, sanitize logs:
sed -E 's/(password|token|apikey)=\S+/\1=REDACTED/gi' input.log > sanitized.log
- Track deltas: version reports with git to spot regressions.
cd /var/log/sec-reports
git init -q || true
git add . && git commit -m "Report $(date -u +'%F %T')" || true
Tune Nmap scope and cadence: daily for critical hosts, weekly for broader ranges.
Balance cost and privacy: use a local OpenAI-compatible server for sensitive environments; use cloud APIs for convenience and larger models.
Handle large outputs: if your JSON is big, chunk by section and ask the AI to summarize each before a final synthesis.
Example: What your AI report might highlight
High-Risk: “Port 8080 opened since yesterday; unauthenticated management UI detected. Evidence: Nmap output line X.”
Medium: “Lynis flagged weak SSH algorithms; disable SHA1 MACs.”
Low: “AIDE reports changed web assets; matches recent deploy.”
Notable: “Repeated sudo auth failures from 203.0.113.10; consider blocking or MFA prompts.”
Security considerations
Permissions: ensure scans comply with your org’s policies; never scan networks you don’t own/operate.
Secrets hygiene: keep API keys in root-only readable files (e.g., systemd EnvironmentFile) or a secret manager.
Transport: prefer local AI or TLS-protected endpoints. Assume providers may log requests per their policies.
Fail-safe: if AI is unreachable, still archive raw signals; alert on failure paths.
Conclusion and next steps
With two small Bash scripts and your favorite package manager, you can convert noisy scanner outputs into crisp, prioritized security reports that hit inboxes automatically. Start small—one host, a handful of checks—then scale to your fleet.
Call to action:
Install the tools, drop in the scripts, and schedule a daily run this week.
Sit down with your team to tune the prompt and thresholds to your environment.
Consider moving to a local OpenAI-compatible server if data sensitivity is high.
When security reporting is automated and intelligible, you’ll spend less time parsing logs and more time fixing what matters.