- Posted on
- • Artificial Intelligence
Artificial Intelligence Security Automation
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence Security Automation on Linux: A Bash-First Guide
If your Linux servers are exposed to the internet, they’re already being probed. The problem isn’t the lack of logs—it’s the overload. AI-driven security automation helps you separate signal from noise, flag true anomalies, and auto-remediate the obvious threats before a human even looks.
This article shows you how to build a simple, Linux-native, Bash-first AI security pipeline:
Collect signals with shell tools
Train a lightweight anomaly detector
Score in near-real-time and auto-block offenders with nftables
Automate everything with cron or systemd timers
No heavyweight SIEM required—just a few packages, shell scripts, and a pinch of Python.
Why AI Security Automation is Worth Your Time
Volume and speed: Attack traffic and system events grow faster than manual triage can handle.
Context over rules: Static rules alone miss novel behavior; anomaly detection adapts to your environment.
Linux-native automation: Journald, ps, ss, nftables, and cron give you a robust backbone for data, scoring, and action with minimal overhead.
Prerequisites: Install the Tools
We’ll use:
journalctl, ss, ps (already available on systemd-based distros)
jq for JSON parsing
nftables for blocking
Python 3 + pip for a tiny ML model (scikit-learn)
Optional: auditd and inotify-tools for richer signals
Run the appropriate commands for your distro (use sudo where needed).
Debian/Ubuntu (apt):
apt update
apt install -y auditd inotify-tools python3 python3-pip jq nftables
pip3 install --user --upgrade pip
pip3 install --user scikit-learn pandas numpy joblib
Fedora/RHEL/CentOS Stream (dnf):
dnf install -y audit inotify-tools python3 python3-pip jq nftables
pip3 install --user --upgrade pip
pip3 install --user scikit-learn pandas numpy joblib
openSUSE Leap/Tumbleweed (zypper):
zypper refresh
zypper install -y audit inotify-tools python3-pip jq nftables
pip3 install --user --upgrade pip
pip3 install --user scikit-learn pandas numpy joblib
Make sure your user’s local bin is in PATH if you used --user:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Step 1: Collect Security Signals with Bash
We’ll gather a few robust metrics every 15 minutes:
SSH failures and unique source IPs
Count of listening TCP ports
Count of high-CPU processes
Count of SUID binaries (basic privilege-escalation risk indicator)
Create the working directory and the collector:
sudo mkdir -p /var/lib/ai-sec
sudo chown "$USER":"$USER" /var/lib/ai-sec
cat > /var/lib/ai-sec/collect_features.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
STATE_DIR="/var/lib/ai-sec"
CSV="$STATE_DIR/features.csv"
SINCE="15 min ago"
# Metrics
fail_ssh=$(journalctl -u ssh -u sshd --since "$SINCE" 2>/dev/null \
| grep -Eci 'Failed password|Invalid user|authentication failure' || true)
unique_ips=$(journalctl -u ssh -u sshd --since "$SINCE" 2>/dev/null \
| grep -Eo 'from ([0-9]{1,3}\.){3}[0-9]{1,3}' \
| awk '{print $2}' | sort -u | wc -l | awk '{print $1}')
listening_ports=$(ss -ltn 2>/dev/null | awk 'NR>1{print $4}' \
| sed 's/.*://g' | sort -u | wc -l | awk '{print $1}')
high_cpu_procs=$(ps -eo pcpu= 2>/dev/null \
| awk '$1>=80{c++} END{print (c+0)}')
suid_count=$(find /usr/bin /usr/sbin -perm -4000 -type f 2>/dev/null | wc -l | awk '{print $1}')
timestamp=$(date -Iseconds)
# Initialize CSV with header if missing
if [[ ! -f "$CSV" ]]; then
echo "timestamp,fail_ssh,unique_ips,listening_ports,high_cpu_procs,suid_count" > "$CSV"
fi
echo "$timestamp,$fail_ssh,$unique_ips,$listening_ports,$high_cpu_procs,$suid_count" >> "$CSV"
echo "[collect] $timestamp OK"
EOF
chmod +x /var/lib/ai-sec/collect_features.sh
Bonus: Add a simple file integrity watch channel (optional). This logs changes instantly; you can later wire it into your model or alerting:
inotifywait -m -e modify,attrib,move,create,delete /etc /var/www 2>/dev/null
Tip: auditd can capture syscalls and privileged operations comprehensively. Keep it installed and tuned if you want deeper signals (rules depend on your environment).
Step 2: Train a Lightweight Anomaly Detector
We’ll use IsolationForest from scikit-learn. First, collect a day or two of “normal” data with the collector running periodically. Then train:
Training script:
cat > /var/lib/ai-sec/train_iforest.py << 'EOF'
#!/usr/bin/env python3
import json, sys
import numpy as np
import pandas as pd
from sklearn.ensemble import IsolationForest
from sklearn.preprocessing import StandardScaler
from joblib import dump
state_dir = "/var/lib/ai-sec"
csv_path = f"{state_dir}/features.csv"
model_path = f"{state_dir}/model.joblib"
scaler_path = f"{state_dir}/scaler.joblib"
meta_path = f"{state_dir}/meta.json"
df = pd.read_csv(csv_path)
# Basic sanity: drop rows with NaN or non-numeric
cols = ["fail_ssh","unique_ips","listening_ports","high_cpu_procs","suid_count"]
X = df[cols].fillna(0).astype(float).values
scaler = StandardScaler()
Xn = scaler.fit_transform(X)
# Assume small contamination; tune for your environment
clf = IsolationForest(n_estimators=200, contamination=0.02, random_state=42)
clf.fit(Xn)
# Compute training score distribution to set a threshold
scores = clf.decision_function(Xn) # higher is more normal
threshold = float(np.percentile(scores, 2)) # bottom 2% as anomalies
dump(clf, model_path)
dump(scaler, scaler_path)
with open(meta_path, "w") as f:
json.dump({"cols": cols, "threshold": threshold}, f)
print(json.dumps({"trained": True, "samples": len(X), "threshold": threshold}))
EOF
chmod +x /var/lib/ai-sec/train_iforest.py
Run training after you have some data:
/var/lib/ai-sec/train_iforest.py
Step 3: Score, Alert, and Auto-Block Offenders
Create a scoring script that reads the latest row, compares it to the learned threshold, and emits JSON:
cat > /var/lib/ai-sec/detect.py << 'EOF'
#!/usr/bin/env python3
import json, sys, pandas as pd
from joblib import load
state_dir = "/var/lib/ai-sec"
csv_path = f"{state_dir}/features.csv"
model_path = f"{state_dir}/model.joblib"
scaler_path = f"{state_dir}/scaler.joblib"
meta_path = f"{state_dir}/meta.json"
df = pd.read_csv(csv_path)
last = df.tail(1)
with open(meta_path) as f:
meta = json.load(f)
cols = meta["cols"]
threshold = float(meta["threshold"])
X = last[cols].fillna(0).astype(float).values
scaler = load(scaler_path)
clf = load(model_path)
score = float(clf.decision_function(scaler.transform(X))[0])
is_anom = score < threshold
out = {
"timestamp": str(last["timestamp"].values[0]),
"score": score,
"threshold": threshold,
"is_anomaly": bool(is_anom),
"metrics": {c: float(last[c].values[0]) for c in cols}
}
print(json.dumps(out))
EOF
chmod +x /var/lib/ai-sec/detect.py
Prepare a minimal nftables policy and a blocklist set (run once; ignore errors if they exist already):
sudo nft add table inet filter 2>/dev/null || true
sudo nft add set inet filter blocklist '{ type ipv4_addr; flags interval; }' 2>/dev/null || true
sudo nft add chain inet filter input '{ type filter hook input priority 0; policy accept; }' 2>/dev/null || true
sudo nft add rule inet filter input ip saddr @blocklist drop 2>/dev/null || true
Now wire detection to auto-block abusive SSH sources if the model flags an anomaly and failed attempts are high:
cat > /var/lib/ai-sec/detect_and_respond.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
STATE_DIR="/var/lib/ai-sec"
# Run collector first to get fresh data
"$STATE_DIR/collect_features.sh" >/dev/null
# Score
result=$("$STATE_DIR/detect.py")
echo "$result"
is_anom=$(echo "$result" | jq -r '.is_anomaly')
fail_ssh=$(echo "$result" | jq -r '.metrics.fail_ssh' | awk '{print int($1)}')
# Auto-response policy: only block when anomaly is true and failures are high
if [[ "$is_anom" == "true" && "$fail_ssh" -ge 20 ]]; then
echo "[respond] anomaly with high SSH failures; populating blocklist"
# Find noisy IPs (>=5 failures in last 15 minutes)
mapfile -t bad_ips < <(journalctl -u ssh -u sshd --since "15 min ago" 2>/dev/null \
| grep -Eo 'from ([0-9]{1,3}\.){3}[0-9]{1,3}' \
| awk '{print $2}' | sort | uniq -c | awk '$1>=5{print $2}')
if [[ ${#bad_ips[@]} -gt 0 ]]; then
# Ensure nftables set exists
sudo nft add table inet filter 2>/dev/null || true
sudo nft add set inet filter blocklist '{ type ipv4_addr; flags interval; }' 2>/dev/null || true
sudo nft add chain inet filter input '{ type filter hook input priority 0; policy accept; }' 2>/dev/null || true
sudo nft add rule inet filter input ip saddr @blocklist drop 2>/dev/null || true
for ip in "${bad_ips[@]}"; do
sudo nft add element inet filter blocklist { "$ip" } 2>/dev/null || true
echo "[respond] blocked $ip"
done
else
echo "[respond] no offending IPs found"
fi
else
echo "[respond] no action (either not anomalous or low SSH failures)"
fi
EOF
chmod +x /var/lib/ai-sec/detect_and_respond.sh
Test:
/var/lib/ai-sec/detect_and_respond.sh
Example output:
{"timestamp":"2026-07-12T11:45:33+00:00","score":-0.21,"threshold":-0.15,"is_anomaly":true,"metrics":{"fail_ssh":64,"unique_ips":9,"listening_ports":17,"high_cpu_procs":0,"suid_count":24}}
[respond] anomaly with high SSH failures; populating blocklist
[respond] blocked 203.0.113.24
[respond] blocked 198.51.100.7
Step 4: Automate with cron or systemd
With cron (every 15 minutes):
crontab -e
Add:
*/15 * * * * /var/lib/ai-sec/detect_and_respond.sh >> /var/log/ai-sec.log 2>&1
Or with systemd timers:
sudo tee /etc/systemd/system/ai-sec.service >/dev/null << 'EOF'
[Unit]
Description=AI Security Detect and Respond
[Service]
Type=oneshot
ExecStart=/var/lib/ai-sec/detect_and_respond.sh
EOF
sudo tee /etc/systemd/system/ai-sec.timer >/dev/null << 'EOF'
[Unit]
Description=Run AI Security Detect and Respond every 15 minutes
[Timer]
OnCalendar=*:0/15
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now ai-sec.timer
Real-World Notes and Tuning Tips
Baseline first: Let the collector run during “known-good” periods before training.
Contamination: If you see too many false positives, reduce contamination (e.g., 0.01) and retrain.
Feature engineering: Add richer metrics (e.g., per-protocol connection spikes, process start rates, auditd counts of execve by unprivileged users).
Safe responses: Start in “alert-only” mode. Log anomalies to a channel (syslog, email, Slack webhook via curl) before auto-blocking in production.
Persistence: Rotate /var/lib/ai-sec/features.csv and /var/log/ai-sec.log to prevent growth.
Slack webhook example (optional):
curl -X POST -H 'Content-type: application/json' \
--data "$(jq -n --arg t "AI-Sec Alert" --arg b "$(/var/lib/ai-sec/detect.py)" '{text: ($t + "\n" + $b)}')" \
https://hooks.slack.com/services/XXX/YYY/ZZZ
Conclusion and Next Steps
You just stood up a practical AI-assisted security loop using Bash, system tools, and a small ML model:
Collect signals
Learn “normal”
Detect anomalies
Auto-remediate the obvious
Next steps:
Add more features (auditd counts, file integrity deltas, per-user process bursts)
Send alerts to your chat/ops stack
Extend nftables logic to expire blocks or maintain sets per interface
Store training data in a Git-controlled repo or an S3 bucket for reproducibility
Security is a journey. Start small, automate safely, learn from alerts, and iterate fast—Linux and Bash give you all the levers you need.