Posted on
Artificial Intelligence

Artificial Intelligence Home Network Monitoring

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

Artificial Intelligence Home Network Monitoring (with Bash-first tooling)

Ever wonder which gadget in your house is phoning home at 3 AM, or why your bandwidth suddenly tanks when no one is streaming? A small Linux box, some classic CLI tools, and a sprinkle of AI can give you a private, always-on “radar” for your home network—so you see unusual traffic before it becomes a problem.

This guide shows you how to set up lightweight flow collection with Bash and tshark, build a baseline, and flag anomalies using a tiny Isolation Forest model. You’ll get practical commands, scripts, and install steps for apt, dnf, and zypper.

Why this matters

  • Home networks are noisy and dynamic. IoT devices update silently, default passwords linger, and cloud apps sync in the background.

  • Manual inspection doesn’t scale; you need automation that learns “normal” and highlights deviations.

  • Doing this locally on Linux keeps your packet metadata private and avoids SaaS lock-in or egress fees.

  • Start with simple stats; layer AI when ready. You can run the full setup on a Raspberry Pi or any spare Linux box.

What we’ll build

  • A Bash-first data pipeline that:
    • Discovers devices and collects light “flow-like” features (not full packet payloads).
    • Aggregates per-minute stats for src/dst pairs.
    • Trains a tiny anomaly detector (optional Python) to flag weird traffic.
    • Sends readable logs you can act on.

1) Install the tools

We’ll use tshark (CLI Wireshark) for capture, nmap for discovery, Suricata (optional IDS), jq for JSON, and Python for the small AI step.

  • Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y tshark nmap suricata jq python3 python3-pip python3-sklearn python3-pandas
  • Fedora/RHEL/CentOS Stream (dnf):
sudo dnf install -y wireshark-cli nmap suricata jq python3 python3-pip python3-scikit-learn python3-pandas
  • openSUSE (zypper):
sudo zypper install -y wireshark-cli nmap suricata jq python3 python3-pip python3-scikit-learn python3-pandas

Notes:

  • Capturing without root: On Debian/Ubuntu, consider:
sudo dpkg-reconfigure wireshark-common   # allow non-root capture (if you agree)
sudo usermod -a -G wireshark $USER
# log out and back in; dumpcap usually gets capabilities automatically
  • If you prefer Python packages via pip (user-local):
python3 -m pip install --user numpy pandas scikit-learn

2) Map and label your devices

Create a quick inventory so anomaly alerts show friendly names instead of just IPs.

  • Fast ping sweep (replace 192.168.1.0/24 with your LAN):
mkdir -p ~/ai-net
sudo nmap -sn 192.168.1.0/24 -oG - | awk '/Up$/{print $2}' > ~/ai-net/ips.txt
  • Make a simple label file you can hand-edit:
while read ip; do
  host=$(getent hosts "$ip" | awk '{print $2}')
  echo "$ip,${host:-unknown},${RANDOM}"    # third field is a placeholder tag you can edit
done < ~/ai-net/ips.txt > ~/ai-net/hosts.csv

Edit ~/ai-net/hosts.csv so each line is:

IP,Name,Tag

Examples:

192.168.1.10,smart-tv,livingroom
192.168.1.20,cam-frontdoor,security
192.168.1.50,work-laptop,owner-alex

3) Collect flow-like features with tshark

We’ll capture minimal metadata (timestamps, src/dst, sizes), aggregate per-minute stats in CSV, and store them under /var/log/ai-net.

Create /usr/local/bin/collect.sh:

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

OUTDIR="/var/log/ai-net"
mkdir -p "$OUTDIR"
TODAY=$(date +%Y%m%d)
CSV="$OUTDIR/flows-$TODAY.csv"

# Pick your primary egress interface automatically
IFACE=$(ip route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev"){print $(i+1); exit}}')
: "${IFACE:?Could not determine interface}"

# Ensure CSV has a header
if [ ! -s "$CSV" ]; then
  echo "ts_minute,src_ip,dst_ip,pkts,bytes,avg_pkt_bytes" > "$CSV"
fi

# Capture 60s of traffic, filter out broadcast/multicast chatter
# Requires root or dumpcap capabilities
sudo tshark -i "$IFACE" -a duration:60 -f "ip and not (broadcast or multicast)" \
  -T fields -E separator=, -e frame.time_epoch -e ip.src -e ip.dst -e frame.len \
| awk -F, '
  NF==4 {
    t=int($1/60)*60; src=$2; dst=$3; len=$4+0;
    k=src"|"dst"|"t;
    pkts[k]+=1; bytes[k]+=len
  }
  END {
    for (k in pkts) {
      split(k,a,"|");
      src=a[1]; dst=a[2]; t=a[3];
      p=pkts[k]; b=bytes[k];
      avg=(p>0? b/p : 0);
      print t","src","dst","p","b","avg
    }
  }
' >> "$CSV"

Make it executable:

sudo install -m 0755 /usr/local/bin/collect.sh /usr/local/bin/collect.sh

Test it once:

/usr/local/bin/collect.sh && tail -n5 /var/log/ai-net/flows-$(date +%Y%m%d).csv

Automate every 15 minutes via cron:

( crontab -l 2>/dev/null; echo "*/15 * * * * /usr/local/bin/collect.sh >/var/log/ai-net/collect.log 2>&1" ) | crontab -

Tip: If your LAN is not flat or you want to monitor a different interface (e.g., your AP bridge), set IFACE manually in the script.


4) Baseline and detect anomalies (two options)

Option A: Simple stats in Bash/awk (no Python). Great starting point.

  • Compute a rolling mean/std for each src->dst pair and flag high z-scores.

Create /usr/local/bin/detect-simple.sh:

#!/usr/bin/env bash
set -euo pipefail
OUTDIR="/var/log/ai-net"
DAYS=${DAYS:-7}

# Merge last N days of CSVs (ts_minute,src_ip,dst_ip,pkts,bytes,avg_pkt_bytes)
files=$(for i in $(seq 0 $((DAYS-1))); do date -d "-$i day" +$OUTDIR/flows-%Y%m%d.csv; done | tr '\n' ' ')
awk -F, 'NR==1{next} { k=$2"->"$3; bytes[k,NR]=$5; t[NR]=$1; key[k]=1 }
END {
  # For each key, compute mean/std and flag z>3 for last 200 rows (recent)
  for (k in key) {
    n=0; sum=0; sumsq=0;
    # First pass: stats
    for (i=1;i<=NR;i++) if (bytes[k,i]!="") { x=bytes[k,i]+0; n++; sum+=x; sumsq+=x*x }
    if (n<30) continue;
    mean=sum/n; std=sqrt((sumsq - n*mean*mean)/(n-1));
    if (std==0) std=1;
    # Second pass: print recent outliers
    for (i=NR-200;i<=NR;i++) if (bytes[k,i]!="") {
      x=bytes[k,i]+0; z=(x-mean)/std;
      if (z>3) {
        print strftime("%F %T", t[i])","k",bytes="x",z="z
      }
    }
  }
}' $files 2>/dev/null | sort

Run it:

/usr/local/bin/detect-simple.sh | tee -a /var/log/ai-net/anoms.log

Option B: Small ML step with Isolation Forest (Python). Better at odd shapes and mixed features.

Create /usr/local/bin/detect-ml.py:

#!/usr/bin/env python3
import argparse, glob, os
import pandas as pd
from sklearn.ensemble import IsolationForest

ap = argparse.ArgumentParser()
ap.add_argument("--glob", default="/var/log/ai-net/flows-*.csv")
ap.add_argument("--lookback_days", type=int, default=7)
ap.add_argument("--report_top", type=int, default=20)
args = ap.parse_args()

files = sorted(glob.glob(args.glob))
if not files:
    raise SystemExit("no flow files found")

# Load last N days
df = pd.concat([pd.read_csv(f) for f in files[-args.lookback_days:]], ignore_index=True)
# ts_minute,src_ip,dst_ip,pkts,bytes,avg_pkt_bytes
df = df.dropna()
df["ts_minute"] = df["ts_minute"].astype(int)

# Feature engineering
features = df[["pkts","bytes","avg_pkt_bytes"]].astype(float)

# Split: train on earlier 80%, score on last 20%
cut = int(len(df)*0.8)
train_X = features.iloc[:cut]
test_X  = features.iloc[cut:]

if len(train_X) < 200 or len(test_X) < 10:
    raise SystemExit("not enough data yet; let the collector run longer")

model = IsolationForest(n_estimators=200, contamination=0.01, random_state=0)
model.fit(train_X)
scores = -model.score_samples(test_X)     # higher = more anomalous

scored = df.iloc[cut:].copy()
scored["anomaly_score"] = scores

top = scored.sort_values("anomaly_score", ascending=False).head(args.report_top)
for _, r in top.iterrows():
    print(f"{pd.to_datetime(r['ts_minute'], unit='s')} src={r['src_ip']} dst={r['dst_ip']} "
          f"bytes={int(r['bytes'])} pkts={int(r['pkts'])} avg={int(r['avg_pkt_bytes'])} "
          f"score={r['anomaly_score']:.3f}")

Run it:

/usr/bin/env python3 /usr/local/bin/detect-ml.py | tee -a /var/log/ai-net/anoms.log

Cron it (offset to run after collection):

( crontab -l 2>/dev/null; echo "*/15 * * * * sleep 120; /usr/bin/env python3 /usr/local/bin/detect-ml.py >> /var/log/ai-net/anoms.log 2>&1" ) | crontab -

Interpretation tips:

  • A surge in bytes to an uncommon external IP from a camera device is suspicious.

  • Spikes at odd hours from a TV or printer are worth reviewing.

  • Short bursts to CDNs right after firmware updates may be benign—label them in hosts.csv.


5) Optional: Enrich with Suricata IDS

Signature-based alerts pair nicely with your anomaly feed.

  • Enable and start Suricata:
sudo systemctl enable --now suricata
  • Set your HOME_NET in /etc/suricata/suricata.yaml (e.g., [192.168.1.0/24]), then restart:
sudo systemctl restart suricata
  • Tail alerts:
sudo tail -F /var/log/suricata/eve.json | jq -r 'select(.alert) | [.timestamp,.src_ip,.dest_ip,.alert.signature] | @csv'

You can correlate timestamps/IPs from your anomaly log with Suricata alerts for faster triage.


Real-world examples

  • Smart TV phone-home: Late-night spikes to a new CDN after a firmware push. If it persists daily without updates, investigate or block.

  • Doorbell camera upload: Sudden increase in upstream bytes to an IP outside the vendor’s ASN—potential compromise or misconfiguration.

  • Work laptop: Unusual connections during off-hours—could be auto-updates, or a misbehaving app. Anomaly logs help you ask the right questions.


Privacy, safety, and maintenance

  • Capture filters: We collect metadata, not payloads. You can further restrict captures (e.g., exclude known streaming devices) in the tshark filter.

  • Legal: Monitor only networks you own/control.

  • Storage: Rotate logs (logrotate) and archive old CSVs monthly.

  • Tuning: Adjust contamination in Isolation Forest (e.g., 0.02) and z-score thresholds depending on how “bursty” your network is.


Conclusion and next steps

You now have a private, bash-driven system that learns what “normal” looks like on your LAN and flags the weird stuff—without shipping your data to the cloud. Next:

  • Let the collector run a few days to build a baseline.

  • Start with detect-simple.sh; when ready, move to detect-ml.py.

  • Add friendly names to hosts.csv to make alerts actionable.

  • (Optional) Feed anomalies into a dashboard (Grafana/Prometheus) or send to your email/Telegram.

If you want a follow-up post with dashboards, systemd timers, and blocking offenders with nftables based on anomaly triggers, say the word and I’ll publish a part two.