- Posted on
- • Artificial Intelligence
Artificial Intelligence for Linux Security Auditing
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence for Linux Security Auditing (with Bash-first workflows)
If you’re responsible for Linux systems, you already know: the logs are endless, the alerts are noisy, and attackers don’t wait. What if you could make your logs work for you—surfacing the unusual, the rare, and the truly suspicious—without buying a heavy commercial SIEM? That’s where a little practical AI can help.
This article shows how to add lightweight, auditable AI to your Linux security auditing using tools you already trust: Bash, systemd, auditd, and a small Python ML stack. You’ll:
Capture high-fidelity security signals (auditd, journald, process accounting)
Build and run a compact anomaly detector against SSH auth logs
Automate it with systemd timers so you get regular insights, not one-off experiments
All commands include apt, dnf, and zypper options where packages are installed.
Why AI for Linux auditing is worth your time
Pattern discovery beats static rules: Rule-based tools are great, but they can miss weird-but-real attacks. Unsupervised ML can find rare events you didn’t think to write a rule for.
Prioritization: AI helps you bubble up the top 10 suspicious events from millions of lines, so you can investigate faster.
Works with what you have: Journald, auditd, and your existing logs are already fantastic training data. You don’t need to ship your data to the cloud or install a giant stack.
1) Capture the right signals (auditd, journald, process accounting)
First, make sure you’re collecting rich, reliable telemetry. That means auditd for system calls and file watches, persistent journald, and optional process accounting.
Install auditd
- apt:
sudo apt update sudo apt install -y auditd audispd-plugins- dnf:
sudo dnf install -y audit audispd-plugins- zypper:
sudo zypper install -y audit- Enable:
sudo systemctl enable --now auditd sudo auditctl -sMake journald persistent
sudo mkdir -p /var/log/journal sudo sed -i 's/^#\?Storage=.*/Storage=persistent/' /etc/systemd/journald.conf sudo systemctl restart systemd-journald(Optional but useful) Enable process accounting for process-level forensics
- apt (Debian/Ubuntu: package “acct”, service “acct”):
sudo apt install -y acct sudo systemctl enable --now acct- dnf (RHEL/Fedora: package “psacct”, service “psacct”):
sudo dnf install -y psacct sudo systemctl enable --now psacct- zypper (openSUSE: package “acct”, service “acct”):
sudo zypper install -y acct sudo systemctl enable --now acctAdd a few high-value audit rules (file integrity and user/group DB changes)
sudo tee /etc/audit/rules.d/hardening.rules >/dev/null <<'RULES' -w /etc/passwd -p wa -k passwd_changes -w /etc/shadow -p wa -k shadow_changes -w /etc/group -p wa -k group_changes -w /usr/bin/sudo -p x -k sudo_exec -a always,exit -F arch=b64 -S execve -k exec_monitor -a always,exit -F arch=b32 -S execve -k exec_monitor RULES sudo augenrules --load || sudo service auditd restart
These rules ensure you’ll have the raw material AI needs: concrete events tied to identities, processes, and files.
2) Install a tiny, local ML toolchain
We’ll keep it simple: Python 3 plus scikit-learn, pandas, and numpy. No cloud. No data leaves your box.
Install Python and pip
- apt:
sudo apt update sudo apt install -y python3 python3-pip python3-venv- dnf:
sudo dnf install -y python3 python3-pip- zypper:
sudo zypper install -y python3 python3-pipInstall Python libraries (user scope)
python3 -m pip install --user --upgrade pip python3 -m pip install --user scikit-learn pandas numpy
Tip: If you prefer isolation, you can use a venv:
python3 -m venv ~/.venvs/ai-audit
~/.venvs/ai-audit/bin/pip install scikit-learn pandas numpy
3) Real-world example: SSH anomaly detection in under 50 lines
This script ingests your SSH authentication logs, extracts simple features (hour, success/failure, username length, IP octets, method), and uses an Isolation Forest to rank unusual events.
It works with both Debian/Ubuntu (/var/log/auth.log) and RHEL/Fedora/openSUSE (/var/log/secure).
Install the script
sudo mkdir -p /opt/ai-audit sudo tee /opt/ai-audit/detect_auth_anomalies.py >/dev/null <<'PY' #!/usr/bin/env python3 import os, re, json, socket from datetime import datetime import numpy as np from sklearn.ensemble import IsolationForest # Pick the auth log path CANDIDATES = ["/var/log/auth.log", "/var/log/secure"] LOG = next((p for p in CANDIDATES if os.path.exists(p)), None) if not LOG: print("No auth log found (checked /var/log/auth.log and /var/log/secure).") raise SystemExit(1) # Basic parser for sshd lines line_re = re.compile(r'^(?P<ts>[A-Z][a-z]{2}\s+\d+\s+\d{2}:\d{2}:\d{2})\s+(?P<host>\S+)\s+sshd\[\d+\]:\s+(?P<msg>.+)$') ip_re = re.compile(r'(\d{1,3}\.){3}\d{1,3}') user_re = re.compile(r'\bfor\s+([A-Za-z0-9._-]+)\b') def parse_dt(ts_str): # Add current year; journald-like syslog timestamps omit the year now = datetime.now() try: dt = datetime.strptime(f"{ts_str} {now.year}", "%b %d %H:%M:%S %Y") # handle year rollover (Jan logs in early Jan referring to Dec of previous year) if (now - dt).days < -300: dt = datetime.strptime(f"{ts_str} {now.year - 1}", "%b %d %H:%M:%S %Y") return dt except Exception: return None rows = [] raw = [] with open(LOG, "r", errors="ignore") as fh: for line in fh: m = line_re.match(line) if not m: continue ts = parse_dt(m.group("ts")) if not ts: continue msg = m.group("msg") # Focus on key sshd outcomes interesting = any(s in msg for s in ["Failed password", "Accepted password", "Invalid user", "Accepted publickey"]) if not interesting: continue ip = ip_re.search(msg) ip = ip.group(0) if ip else "0.0.0.0" user_m = user_re.search(msg) user = user_m.group(1) if user_m else "unknown" method = 0 if "publickey" in msg: method = 1 elif "password" in msg: method = 2 failed = 1 if ("Failed password" in msg or "Invalid user" in msg) else 0 invalid_user = 1 if "Invalid user" in msg else 0 # Featureize IP (IPv4 octets, crude but often useful) try: octs = [int(x) for x in ip.split(".")] if len(octs) != 4 or any(o < 0 or o > 255 for o in octs): octs = [-1, -1, -1, -1] except Exception: octs = [-1, -1, -1, -1] feat = [ ts.hour, failed, invalid_user, len(user), method, *octs ] rows.append(feat) raw.append({ "timestamp": ts.isoformat(), "user": user, "ip": ip, "message": msg.strip() }) if not rows: print("No relevant sshd events found.") raise SystemExit(0) X = np.array(rows, dtype=float) # Train Isolation Forest on the observed data (unsupervised) clf = IsolationForest( n_estimators=200, contamination="auto", random_state=42 ) clf.fit(X) # Higher score => more abnormal if we invert sign scores = -clf.score_samples(X) # Take top N anomalies N = min(30, len(scores)) idxs = np.argsort(scores)[-N:][::-1] anomalies = [] for i in idxs: r = raw[i] anomalies.append({ "timestamp": r["timestamp"], "user": r["user"], "ip": r["ip"], "anomaly_score": float(scores[i]), "message": r["message"] }) out_path = "/var/log/ai-ssh-anomalies.json" try: with open(out_path, "w") as f: json.dump(anomalies, f, indent=2) except PermissionError: # Fallback to user-writable location if not root home_out = os.path.expanduser("~/ai-ssh-anomalies.json") with open(home_out, "w") as f: json.dump(anomalies, f, indent=2) out_path = home_out print(f"[ai-audit] Wrote {len(anomalies)} anomalies to {out_path}") for a in anomalies[:10]: # also print the top few print(f"{a['timestamp']} user={a['user']} ip={a['ip']} score={a['anomaly_score']:.4f} :: {a['message']}") PY sudo chmod +x /opt/ai-audit/detect_auth_anomalies.pyRun it manually
python3 /opt/ai-audit/detect_auth_anomalies.pyAutomate with systemd (runs every 30 minutes and logs to journald)
sudo tee /etc/systemd/system/ai-ssh-audit.service >/dev/null <<'UNIT' [Unit] Description=AI SSH anomaly detector [Service] Type=oneshot ExecStart=/usr/bin/env bash -lc 'python3 /opt/ai-audit/detect_auth_anomalies.py | tee -a /var/log/ai-ssh-anomalies.log | logger -t ai-ssh-audit' Nice=10 ProtectSystem=full ProtectHome=true PrivateTmp=true CapabilityBoundingSet= NoNewPrivileges=true UNIT sudo tee /etc/systemd/system/ai-ssh-audit.timer >/dev/null <<'UNIT' [Unit] Description=Run AI SSH anomaly detector periodically [Timer] OnBootSec=5m OnUnitActiveSec=30m AccuracySec=1m Persistent=true [Install] WantedBy=timers.target UNIT sudo systemctl daemon-reload sudo systemctl enable --now ai-ssh-audit.timer
Check status and logs:
systemctl list-timers | grep ai-ssh-audit
journalctl -u ai-ssh-audit.service --no-pager -n 50
What you’ll get: a short, ranked list of “most unusual” SSH events with timestamps, users, and IPs, saved to JSON and echoed to your logs.
4) Turn insights into action (alerting and hardening)
Pivot quickly: For a flagged IP, check its recent activity:
sudo journalctl -S -2h -u ssh | grep '1\.2\.3\.4' sudo ausearch -k exec_monitor | grep '1\.2\.3\.4' || trueAdd targeted bans (pair with fail2ban or a short-term firewall rule):
sudo ipset create tempban hash:ip timeout 7200 sudo ipset add tempban 1.2.3.4 sudo iptables -I INPUT -m set --match-set tempban src -j DROPExpand coverage: Duplicate the approach for:
- Sudden new binaries in /usr/local/bin
- Abnormal sudo invocations (key: sudo_exec)
- Rare process names from acct/psacct history
Keep it local and private: Avoid shipping sensitive logs off-host unless policy requires it. The example pipeline runs entirely on your system.
A quick, real-world-flavored win
Admins often see waves of “Failed password” attempts—but which ones matter? In practice, the top anomalies tend to be:
New usernames never seen before (e.g., ops-admin vs. normal svc_ users)
Logins at rare hours for your environment
Source IP blocks that don’t match your usual geography
Method drift (e.g., sudden “Accepted publickey” from a host that has only ever used passwords)
The example detector floats these to the top so you can spend time investigating, not scrolling.
Conclusion and next steps (CTA)
You don’t need a massive budget to get value from AI in Linux security auditing. With auditd, persistent journald, a bit of Python, and systemd timers, you can:
Capture the right data
Surface the truly unusual
Act faster on what matters
Next steps:
Roll this to a staging box or non-critical host first and tune thresholds (features, score cutoffs, timer interval).
Add features unique to your environment (e.g., known-good subnets, service accounts).
Extend the same pattern to auditd rule hits and process accounting for deeper coverage.
Have an improvement or a field story? Share your tweaks and findings—let’s make Linux auditing smarter, together.