- Posted on
- • Artificial Intelligence
AI-Based Bandwidth Analysis
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
AI-Based Bandwidth Analysis on Linux with Bash: From Packets to Anomalies
Ever looked at a graph that showed “100% bandwidth utilized” and still couldn’t answer why? Or noticed those mysterious 2 A.M. spikes that vanish before you can tcpdump them? This guide shows how to build a lightweight, AI-assisted bandwidth analyzer that runs from your Linux shell. You’ll collect packet metadata with tshark, turn it into time-windowed features, train an anomaly detector, and monitor in real time—all scriptable, reproducible, and friendly to encrypted traffic.
What you’ll get:
A capture-to-features Bash pipeline using tshark + awk
A tiny Python model (Isolation Forest) that flags outliers in bandwidth patterns
Ready-to-run commands and scripts, including install instructions for apt, dnf, and zypper
Why this works:
You don’t need payloads to understand bandwidth behavior—headers and simple counts (bytes, packets, protocol mix) are enough to spot unusual periods.
AI baselines your normal, then highlights unusual bursts, drops, or protocol shifts—even when your averages look “fine.”
It’s lightweight and respects least privilege (no long-running root processes).
Prerequisites and Install
We’ll use:
tshark (the Wireshark CLI) for packet metadata
vnstat for quick interface stats
iperf3 for controlled test traffic
Python 3 + pip + a few ML libs
setcap to capture without root
Install with your package manager:
- Debian/Ubuntu (apt)
sudo apt update
sudo apt install -y tshark iperf3 vnstat python3 python3-pip libcap2-bin
- Fedora/RHEL/CentOS (dnf)
sudo dnf install -y wireshark-cli iperf3 vnstat python3 python3-pip libcap
- openSUSE (zypper)
sudo zypper refresh
sudo zypper install -y wireshark-cli iperf3 vnstat python3 python3-pip libcap-progs
Grant non-root capture safely:
sudo groupadd -f pcap
sudo usermod -a -G pcap $USER
sudo chgrp pcap /usr/bin/dumpcap
sudo chmod 750 /usr/bin/dumpcap
sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/dumpcap
# Log out and back in so new group applies
Python packages:
python3 -m pip install --user --upgrade pip
python3 -m pip install --user pandas scikit-learn joblib
Overview of the Pipeline
1) Baseline your link quickly (vnstat, iperf3)
2) Capture and aggregate metadata in fixed windows (tshark + awk)
3) Train an Isolation Forest on “normal” data
4) Monitor live and alert on anomalies
5) Iterate (tune thresholds, filters, and windows)
1) Baseline: Know Your Normal
- Quick live view with vnstat (replace eth0 with your interface):
IFACE=eth0
vnstat -l -i "$IFACE"
- Optional controlled test with iperf3:
- On a test server:
iperf3 -s - From a client:
iperf3 -c <server-ip> -t 20 -RThis helps validate that your capture/analysis sees expected traffic levels.
- On a test server:
2) Collect Features from Packets (Bash-only)
We’ll capture IP headers only and aggregate into 5-second bins. Features per bin:
bytes, packets
tcp packets, udp packets (protocol mix)
Capture ~15 minutes of training data:
IFACE=eth0
BIN=5 # seconds
DUR=900 # training capture duration (seconds)
OUT=traffic_5s.csv
tshark -i "$IFACE" -a duration:$DUR -f "ip" -s 96 \
-T fields -E separator=\t \
-e frame.time_epoch -e frame.len -e ip.proto 2>/dev/null | \
awk -v BIN="$BIN" 'BEGIN{FS="\t"; OFS=","; print "ts,bytes,pkts,tcp,udp"}
{
t=int($1/BIN)*BIN
if (curr=="") curr=t
bytes[t]+=$2; pkts[t]++
if($3==6) tcp[t]++; else if($3==17) udp[t]++
if (t>curr) {
print curr, bytes[curr]+0, pkts[curr]+0, tcp[curr]+0, udp[curr]+0
delete bytes[curr]; delete pkts[curr]; delete tcp[curr]; delete udp[curr]
curr=t
}
}
END{
if (curr!="") print curr, bytes[curr]+0, pkts[curr]+0, tcp[curr]+0, udp[curr]+0
}' | tee "$OUT"
Notes:
We use a small snap length (-s 96) to reduce overhead (header-only).
If the link is busy, consider BPF filters to narrow scope (e.g., exclude known noisy ports).
3) Train an AI Model (Isolation Forest)
We’ll train on the 5-second bins you just captured.
Save as train_bandwidth_model.py:
#!/usr/bin/env python3
import sys, joblib, pandas as pd
from sklearn.ensemble import IsolationForest
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
CSV = sys.argv[1] if len(sys.argv) > 1 else "traffic_5s.csv"
BIN = 5.0
df = pd.read_csv(CSV)
# Build features
X = pd.DataFrame({
"bytes_per_s": df["bytes"]/BIN,
"pkts_per_s": df["pkts"]/BIN,
"tcp_frac": (df["tcp"]/df["pkts"]).fillna(0.0),
"udp_frac": (df["udp"]/df["pkts"]).fillna(0.0),
})
pipe = Pipeline([
("scaler", StandardScaler()),
("iso", IsolationForest(
n_estimators=200,
contamination=0.02, # ~2% of intervals flagged as anomalies
random_state=42
)),
])
pipe.fit(X)
joblib.dump(pipe, "bw_iso.joblib")
print("Model saved to bw_iso.joblib; trained on", len(X), "windows")
Train it:
python3 train_bandwidth_model.py traffic_5s.csv
Tuning tips:
contamination controls how “sensitive” the detector is; start 0.01–0.05.
BIN can be 1s for bursty traffic or 10–30s for slower links.
4) Monitor Live and Alert on Anomalies
We’ll reuse the same live aggregation concept and score each bin as it closes.
Save as score_bandwidth.py:
#!/usr/bin/env python3
import sys, joblib
from datetime import datetime
if len(sys.argv) < 2:
print("Usage: score_bandwidth.py <model.joblib>", file=sys.stderr)
sys.exit(1)
model_path = sys.argv[1]
pipe = joblib.load(model_path)
BIN = 5.0
def parse(line):
# ts,bytes,pkts,tcp,udp
parts = line.strip().split(",")
if parts[0] == "ts" or len(parts) < 5:
return None
ts = int(float(parts[0]))
bytes_, pkts, tcp, udp = map(float, parts[1:5])
x = [
bytes_/BIN,
pkts/BIN,
(tcp/pkts if pkts>0 else 0.0),
(udp/pkts if pkts>0 else 0.0),
]
return ts, x, (bytes_, pkts, tcp, udp)
for line in sys.stdin:
item = parse(line)
if not item:
continue
ts, x, raw = item
pred = pipe.predict([x])[0] # 1 normal, -1 anomaly
score = pipe.decision_function([x])[0] # higher is more normal
if pred == -1 or score < -0.1:
iso8601 = datetime.utcfromtimestamp(ts).strftime("%Y-%m-%d %H:%M:%S")
bytes_, pkts, tcp, udp = raw
msg = f"ALERT {iso8601}Z score={score:.3f} bytes={bytes_:.0f} pkts={pkts:.0f} tcp={tcp:.0f} udp={udp:.0f}"
print(msg, flush=True)
# Optional: send to syslog
# os.system(f'logger -t ai-bw "{msg}"')
Live watcher (ai-bw-watch.sh):
#!/usr/bin/env bash
set -euo pipefail
IFACE="${1:-eth0}"
BIN=5
MODEL="${2:-bw_iso.joblib}"
tshark -i "$IFACE" -f "ip" -s 96 \
-T fields -E separator=$'\t' \
-e frame.time_epoch -e frame.len -e ip.proto 2>/dev/null | \
awk -v BIN="$BIN" 'BEGIN{FS="\t"; OFS=","; print "ts,bytes,pkts,tcp,udp"}
{
t=int($1/BIN)*BIN
if (curr=="") curr=t
bytes[t]+=$2; pkts[t]++
if($3==6) tcp[t]++; else if($3==17) udp[t]++
if (t>curr) {
print curr, bytes[curr]+0, pkts[curr]+0, tcp[curr]+0, udp[curr]+0
delete bytes[curr]; delete pkts[curr]; delete tcp[curr]; delete udp[curr]
curr=t
}
}' | python3 score_bandwidth.py "$MODEL"
Run it:
chmod +x ai-bw-watch.sh
./ai-bw-watch.sh eth0 bw_iso.joblib
You’ll see lines like:
ALERT 2026-07-06 14:23:10Z score=-0.341 bytes=8448790 pkts=6840 tcp=5830 udp=982
Tip: Integrate with logging/monitoring
Syslog: uncomment the logger line in score_bandwidth.py
Systemd: run as a service or use tmux/screen
Grafana/Prometheus: write metrics to a textfile exporter if desired
5) Real-World Ways to Use It
Catch unplanned saturation
- Backups or large file sync jobs that start early can push normal limits. The model flags those windows even if your rolling averages look fine.
Spot protocol shifts
- A sudden jump in UDP relative to TCP can indicate streaming, tunneling, or misconfigurations.
Validate QoS or ISP changes
- Train a model before QoS rules or ISP switch; compare anomaly rates after. If anomaly frequency climbs, something changed.
Lab test it
- While ai-bw-watch.sh runs, generate bursts with iperf3:
iperf3 -c <server-ip> -u -b 200M -t 30You should see alerts during the burst windows.
Why This Approach Is Valid
Encryption-friendly: We only analyze metadata and counts; no payload inspection required.
Lightweight: Header-only capture and 5-second feature windows are cheap to compute.
Adaptive: Isolation Forest infers “normal” from your environment, not a static threshold.
Scriptable: The entire workflow is shell-first; easy to automate and version-control.
Tips, Tuning, and Safety
Reduce load:
- Keep snaplen small (-s 96), and consider filters like
-f "ip and not port 22 and not broadcast"
- Keep snaplen small (-s 96), and consider filters like
Tune sensitivity:
- Adjust contamination in the trainer (0.01–0.05). Too many false positives? Lower it.
- Change BIN to match your network’s “tempo.”
Permissions and policy:
- Only capture metadata you’re authorized to observe. Follow org policy and local law.
Conclusion and Next Steps
In a few commands, you built an AI-assisted bandwidth analyzer that runs from Bash: capture, aggregate, baseline, and alert. Next steps:
Let the trainer run over a representative day (weekday + weekend if applicable).
Deploy ai-bw-watch.sh under systemd and log to syslog/Grafana.
Iterate filters and thresholds until alerts match your intuition.
When your next 2 A.M. spike hits, you won’t just see it—you’ll know it’s unusual, and you’ll have the data to prove it.