Posted on
Artificial Intelligence

Artificial Intelligence Security Projects

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

4 Practical AI Security Projects You Can Build on Linux (with Bash)

Artificial intelligence is now a core part of production systems—from fraud detection to code assistants to recommendation engines. But as AI goes mainstream, attackers follow. The challenge: how do you raise the security bar for AI systems using tools you already know—Linux, Bash, and a handful of open-source utilities?

This article gives you four hands-on, Linux-friendly AI security projects you can implement quickly. Each one is production-relevant, uses transparent Bash/POSIX tooling, and helps you reduce risk where it matters most: data, models, infrastructure, and secrets.

Note: These projects are meant for defensive, ethical use on systems you own or are authorized to manage.


Project 1: Rapid Log Anomaly Detection for SSH Using Python + Bash

Problem: How do you detect unusual authentication patterns (e.g., brute-force, odd hours, unfamiliar source IP ranges) before they become incidents?

Approach: Extract SSH auth logs with Bash, turn them into simple features, and run an Isolation Forest (unsupervised) to flag anomalies.

Install prerequisites

  • Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y python3 python3-venv python3-pip jq
  • Fedora/RHEL (dnf):
sudo dnf install -y python3 python3-pip jq
  • openSUSE (zypper):
sudo zypper install -y python3 python3-pip jq

Extract features from logs

This script normalizes across Debian-like (/var/log/auth.log) and RHEL-like (/var/log/secure) systems, then emits a CSV with a few numeric features.

#!/usr/bin/env bash
set -euo pipefail

LOGFILE=""
if [[ -f /var/log/auth.log ]]; then
  LOGFILE="/var/log/auth.log"
elif [[ -f /var/log/secure ]]; then
  LOGFILE="/var/log/secure"
else
  echo "No auth log found."
  exit 1
fi

# Last 24h lines containing SSH login attempts
grep -E "sshd.*(Failed password|Accepted password|Accepted publickey)" "$LOGFILE" | \
awk '
  function ip2oct(ip,   n, i, a) {
    n = split(ip,a,/\./);
    if (n!=4) return -1;
    return a[1]; # crude but useful to bucket by first octet
  }
  {
    # Example lines vary; capture timestamp, user, ip, status
    # Try to find an IP address:
    match($0, /([0-9]{1,3}\.){3}[0-9]{1,3}/, m);
    ip = (m[0] ? m[0] : "0.0.0.0");

    status = ($0 ~ /Failed password/ ? 1 : 0); # 1 = failed, 0 = success
    user = "unknown";
    for (i=1;i<=NF;i++) {
      if ($i=="for" && (i+1)<=NF) { user=$(i+1); }
    }

    # Hour extraction (assumes syslog ts "Mon DD HH:MM:SS")
    hour = 0;
    match($0, /[A-Z][a-z]{2} +[0-9]{1,2} +([0-9]{2}):[0-9]{2}:[0-9]{2}/, t);
    if (t[1]!="") { hour=t[1]; }

    oct = ip2oct(ip);

    # CSV: hour,user,ip_first_octet,status
    print hour","user","oct","status
  }
' > /tmp/ssh_features.csv

echo "Wrote features to /tmp/ssh_features.csv"
head -5 /tmp/ssh_features.csv

Train and score anomalies

Create a Python virtual environment and run a small script.

python3 -m venv ~/.venvs/ai-sec && source ~/.venvs/ai-sec/bin/activate
pip install --upgrade pip
pip install scikit-learn pandas
#!/usr/bin/env python3
# file: score_anomalies.py
import pandas as pd
from sklearn.ensemble import IsolationForest

df = pd.read_csv("/tmp/ssh_features.csv", header=None,
                 names=["hour","user","ip_first_octet","status"])

# Encode categorical "user"
df["user_code"] = df["user"].astype("category").cat.codes

X = df[["hour","ip_first_octet","status","user_code"]].fillna(0)

model = IsolationForest(n_estimators=150, contamination=0.03, random_state=42)
model.fit(X)
df["score"] = model.decision_function(X)
df["is_anomaly"] = model.predict(X) == -1

anomalies = df[df["is_anomaly"]].sort_values("score")
print(anomalies.head(10).to_string(index=False))

Run it:

python3 score_anomalies.py

Actionable next step: cron this daily, alert on anomalies via logger/mail, and feed results into your SIEM.


Project 2: Dataset & Model Integrity Guard (auditd + inotify + minisign)

Problem: Model and dataset tampering is a real threat. You need visibility and integrity checks.

Approach:

  • Watch critical directories for writes with auditd.

  • Maintain signed SHA256 manifests of your datasets/models with minisign.

  • Trigger alerts on unexpected changes using inotify.

Install prerequisites

  • Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y auditd inotify-tools minisign coreutils
  • Fedora/RHEL (dnf):
sudo dnf install -y audit inotify-tools minisign coreutils
  • openSUSE (zypper):
sudo zypper install -y audit inotify-tools minisign coreutils

Set audit rules

Create rules to monitor your AI asset directories:

sudo mkdir -p /opt/ml/{data,models}
sudo bash -c 'cat >/etc/audit/rules.d/ai.rules' <<'EOF'
-w /opt/ml/data   -p wa -k ml-data
-w /opt/ml/models -p wa -k ml-models
EOF

sudo augenrules --load || sudo service auditd restart

Verify logs are flowing:

sudo ausearch -k ml-models --start recent

Baseline and sign your artifacts

cd /opt/ml/models
find . -type f -print0 | xargs -0 sha256sum | sort -k2 > manifest.sha256

# One-time key generation (store keys securely!)
minisign -G -p /root/model_manifest.pub -s /root/model_manifest.sec

# Sign the manifest
minisign -Sm -s /root/model_manifest.sec -m manifest.sha256

Continuous watch with inotify

This script re-hashes on changes and verifies signature. If verification fails, it logs a high-priority message.

#!/usr/bin/env bash
set -euo pipefail
DIR="/opt/ml/models"
PUB="/root/model_manifest.pub"

inotifywait -m -r -e modify,create,delete,move "$DIR" | while read -r _; do
  TMP="$(mktemp)"
  find "$DIR" -type f -print0 | xargs -0 sha256sum | sort -k2 > "$TMP"
  if minisign -Vm "$TMP" -p "$PUB" >/dev/null 2>&1; then
    logger -p auth.info "AI integrity: OK for $DIR"
  else
    logger -p auth.alert "AI integrity: MISMATCH in $DIR (possible tampering)"
  fi
  rm -f "$TMP"
done

Run as a systemd service to make it persistent, and route auth.alert to your SOC tooling.

Real-world note: This pattern has caught “accidental” overwrites in MLOps pipelines as well as suspicious timestamp anomalies.


Project 3: Rootless, TLS-Terminated Model Serving with Podman + Nginx

Problem: Model APIs often ship as containers that run as root, accept oversized payloads, and expose internals—great for attackers.

Approach: Run your model server rootless with Podman, terminate TLS with Nginx, and enforce sane limits.

Install prerequisites

  • Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y podman nginx openssl
  • Fedora/RHEL (dnf):
sudo dnf install -y podman nginx openssl
  • openSUSE (zypper): ``> sudo zypper install -y podman nginx openssl

### Minimal non-root API container Create a FastAPI server that echoes model metadata (placeholder for your real model). `Dockerfile`:

FROM python:3.11-slim

Create non-root user

RUN useradd -m -u 10001 appuser WORKDIR /app

COPY app/ /app/ RUN pip install --no-cache-dir fastapi uvicorn

USER 10001 EXPOSE 8000 CMD ["uvicorn","main:app","--host","0.0.0.0","--port","8000","--proxy-headers"]


`app/main.py`:

from fastapi import FastAPI, HTTPException, Request

app = FastAPI()

@app.get("/healthz") def healthz(): return {"status": "ok"}

@app.post("/infer") async def infer(request: Request): body = await request.body() if len(body) > 1_000_000: # 1MB server-side guardrail raise HTTPException(status_code=413, detail="Payload too large") # Replace with real model inference return {"ok": True, "received_bytes": len(body)}


Build and run rootless:

podman build -t ai-api . podman run --rm -p 127.0.0.1:8000:8000 ai-api


### Generate a dev TLS cert and configure Nginx Generate a self-signed cert for localhost (use real certs in prod):

sudo mkdir -p /etc/nginx/tls sudo openssl req -x509 -newkey rsa:4096 -nodes -days 365 \ -keyout /etc/nginx/tls/key.pem -out /etc/nginx/tls/cert.pem \ -subj "/CN=localhost"


Nginx site config (limits + reverse proxy):

sudo bash -c 'cat >/etc/nginx/conf.d/ai_api.conf' <<'EOF' limit_req_zone $binary_remote_addr zone=ml:10m rate=5r/s;

server { listen 443 ssl; server_name localhost;

ssl_certificate /etc/nginx/tls/cert.pem; ssl_certificate_key /etc/nginx/tls/key.pem;

client_max_body_size 1m; add_header X-Content-Type-Options nosniff always; add_header Referrer-Policy no-referrer always;

location / { limit_req zone=ml burst=10 nodelay; proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_http_version 1.1; } } EOF

sudo nginx -t && sudo systemctl reload nginx


Test:

curl -k https://localhost/healthz


Key guardrails you just added: - Rootless container reduces blast radius. - TLS by default, no plaintext traffic. - Strict request size and rate limits to throttle abuse. --- ## Project 4: Secretless Training and Serving with pass + age Problem: API tokens, database passwords, and keys often leak into training scripts, notebooks, or containers. Approach: Keep secrets out of repos and images. Store them encrypted with age, load them into env only at execution time. ### Install prerequisites - Debian/Ubuntu (apt):

sudo apt update sudo apt install -y pass age gnupg


- Fedora/RHEL (dnf):

sudo dnf install -y pass age gnupg2


- openSUSE (zypper):

sudo zypper install -y pass age gpg2


### Create an age key and encrypt secrets

mkdir -p ~/.config/age age-keygen -o ~/.config/age/key.txt echo "Public key:" grep -m1 "public key" ~/.config/age/key.txt | sed 's/# public key: //'


Encrypt a KEY=VALUE file (example uses a Hugging Face token):

mkdir -p ~/secrets cat > ~/secrets/ml.env <<'EOF' HF_API_TOKEN=hf_xxx DB_PASSWORD=supersecret EOF

Replace RECIPIENT with your printed public key (age1...)

age -r RECIPIENT -o ~/secrets/ml.env.age ~/secrets/ml.env shred -u ~/secrets/ml.env # remove plaintext


Load secrets only when you run:

set -a source <(age -d -i ~/.config/age/key.txt ~/secrets/ml.env.age) set +a

Now env vars are present only in this shell

python train.py ```

Tip: In CI or systemd services, decrypt to a protected tmpfs and avoid writing plaintext to disk.


Why These Projects Work

  • They reduce risk at natural choke points: auth logs (detection), file system changes (integrity), network edge (hardening), and secret handling (exposure).

  • They’re minimal-dependency, Bash-first, and observable—easy to audit and reason about.

  • They scale from laptops to clusters: the same primitives (auditd, inotify, TLS, rootless) apply everywhere.


Call to Action

Pick one project and ship it this week:

  • If you operate servers, start with Project 1 to get anomaly alerts tomorrow.

  • If you manage data/models, implement Project 2 to catch silent tampering.

  • If you expose model APIs, harden the edge with Project 3.

  • If your team handles tokens/keys, roll out Project 4 to stop secrets sprawl.

Iterate: add dashboards, alert routing, and documentation. Security is a practice—use these building blocks to make your AI stack safer, one Bash script at a time.