Posted on
Artificial Intelligence

Artificial Intelligence DHCP Management

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

Artificial Intelligence DHCP Management with Bash: Predict, Detect, Auto‑Tune

Ever had your IP pool mysteriously run dry right before a big meeting, or spent late nights combing DHCP logs to figure out why clients aren’t getting addresses? What if a small, scriptable “AI layer” could sit on top of your existing DHCP and do the boring parts for you—track utilization, detect anomalies, forecast exhaustion, and even suggest smarter lease times?

In this post, we’ll build a practical, Bash‑first workflow that adds AI‑assisted decision making to DHCP. You’ll get runnable scripts to collect metrics, flag weird behavior with machine learning, forecast pool exhaustion, and catch rogue DHCP servers—without replacing your current stack.

Why AI for DHCP?

DHCP is an event- and time-based system—perfect for machine learning:

  • Utilization and lease churn follow daily/weekly patterns that AI can learn and forecast.

  • Anomaly detection can catch misconfigurations, loops, or rogue servers before users complain.

  • AI‑guided lease tuning reduces address pressure at peak times, improving reliability without guesswork.

Bottom line: you’ll reduce firefighting and move toward proactive capacity planning.

What you’ll build

  • A Bash collector that extracts DHCP telemetry (active leases, DORA events, NAKs).

  • A small Python model (Isolation Forest + linear regression) to:

    • Detect anomalies.
    • Estimate time to pool exhaustion.
    • Recommend lease time adjustments.
  • A cron‑friendly script that ties it all together and emits actionable recommendations.

  • An optional rogue DHCP watcher.

Note: The examples assume ISC dhcpd leases and syslog. If you use Kea, you can adapt the data collection to Kea’s stats API; the AI parts remain the same.


Prerequisites and installation

We’ll keep dependencies minimal: Bash/awk/grep, jq, curl, Python 3, and tcpdump.

Apt (Debian/Ubuntu):

sudo apt update
sudo apt install -y python3 python3-venv python3-pip jq curl tcpdump

Dnf (Fedora/RHEL/CentOS Stream):

sudo dnf install -y python3 python3-virtualenv python3-pip jq curl tcpdump

Zypper (openSUSE/SLES):

sudo zypper refresh
sudo zypper install -y python3 python3-virtualenv python3-pip jq curl tcpdump

Project setup:

sudo mkdir -p /var/lib/ai-dhcp
sudo chown "$USER":"$USER" /var/lib/ai-dhcp
cd /var/lib/ai-dhcp

python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install pandas scikit-learn numpy

Step 1 — Collect DHCP telemetry with Bash

This script pulls approximate “active leases” from dhcpd.leases and recent DORA/NAK counters from syslog. Adjust file paths and pool size for your network.

Save as dhcp_metrics.sh and make it executable:

chmod +x dhcp_metrics.sh
#!/usr/bin/env bash
set -euo pipefail

# Config
LEASES_FILE="${LEASES_FILE:-/var/lib/dhcp/dhcpd.leases}"
SYSLOG_FILE="${SYSLOG_FILE:-/var/log/syslog}"
POOL_SIZE="${POOL_SIZE:-254}"   # adjust to your subnet size
TAIL_LINES="${TAIL_LINES:-5000}"
OUT="${1:-metrics.csv}"

timestamp=$(date -Is)

# Count active leases (rough)
active_leases=$(awk '
  $1=="lease"{ip=$2}
  $1=="binding" && $2=="state" && $3=="active;"{print ip}
' "$LEASES_FILE" 2>/dev/null | sort -u | wc -l | awk "{print \$1}")

# Fallback to 0 if file missing
active_leases=${active_leases:-0}

# Event counters from recent log lines
if [[ -r "$SYSLOG_FILE" ]]; then
  window=$(tail -n "$TAIL_LINES" "$SYSLOG_FILE")
  discovered=$(printf "%s" "$window" | grep -c "DHCPDISCOVER" || true)
  offers=$(printf "%s" "$window" | grep -c "DHCPOFFER" || true)
  requests=$(printf "%s" "$window" | grep -c "DHCPREQUEST" || true)
  acks=$(printf "%s" "$window" | grep -c "DHCPACK" || true)
  naks=$(printf "%s" "$window" | grep -c "DHCPNAK" || true)
else
  discovered=0; offers=0; requests=0; acks=0; naks=0
fi

# Utilization
utilization=$(awk -v a="$active_leases" -v p="$POOL_SIZE" 'BEGIN{ if(p==0){print 0}else{printf "%.2f", (a/p)*100}}')

# Ensure CSV header
if [[ ! -s "$OUT" ]]; then
  echo "timestamp,active_leases,discovered,offers,requests,acks,naks,pool_size,utilization" > "$OUT"
fi

echo "$timestamp,$active_leases,$discovered,$offers,$requests,$acks,$naks,$POOL_SIZE,$utilization" >> "$OUT"
echo "Wrote metrics at $timestamp -> $OUT" >&2

Notes:

  • For Kea, consider querying kea-dhcp4 via Control Agent (REST) for lease stats; adapt the script to use curl + jq.

  • For systems using journald without /var/log/syslog, set SYSLOG_FILE to a text export or adapt to use journalctl.


Step 2 — Add a lightweight AI brain

We’ll use:

  • Isolation Forest to flag anomalies based on recent patterns.

  • Simple linear regression to estimate “hours to exhaustion.”

  • A heuristic to suggest a better default lease time.

Save as ai_dhcp.py:

chmod +x ai_dhcp.py
#!/usr/bin/env python3
import sys, json
import pandas as pd
from sklearn.ensemble import IsolationForest
from sklearn.linear_model import LinearRegression
import numpy as np

if len(sys.argv) < 2:
    print("usage: ai_dhcp.py metrics.csv", file=sys.stderr)
    sys.exit(1)

csv = sys.argv[1]
df = pd.read_csv(csv, parse_dates=["timestamp"])
if len(df) < 10:
    print(json.dumps({"error": "not_enough_data", "message":"Collect at least 10 samples"}))
    sys.exit(0)

# Use all but last row to fit
train = df.iloc[:-1].copy()
last = df.iloc[-1]

features = ["active_leases","discovered","offers","requests","acks","naks","pool_size","utilization"]
X = train[features].values

iso = IsolationForest(contamination=0.05, random_state=42)
iso.fit(X)

score = iso.score_samples([last[features].values])[0]
anomaly = bool(iso.predict([last[features].values])[0] == -1)

# Trend toward exhaustion
N = min(200, len(df)-1)
sub = df.iloc[-N-1:-1]  # exclude last row
t = (sub["timestamp"] - sub["timestamp"].min()).dt.total_seconds().values.reshape(-1,1) / 3600.0  # hours
y = sub["active_leases"].values

if np.all(y == y[0]):
    slope = 0.0
else:
    lr = LinearRegression().fit(t, y)
    slope = float(lr.coef_[0])  # leases per hour

pool = float(last["pool_size"])
active = float(last["active_leases"])
remaining = max(0.0, pool - active)

eps = 1e-6
hours_to_exhaustion = float("inf") if slope <= eps else remaining / slope

# Simple lease-time recommendation heuristic (in seconds)
util = float(last["utilization"])
if util > 90 or (util > 80 and slope > 1):
    recommend_lease = 3600  # 1h
elif util > 70 and slope > 0.3:
    recommend_lease = 7200  # 2h
elif util < 40 and slope < 0.0:
    recommend_lease = 86400  # 24h
else:
    recommend_lease = 14400  # 4h default

result = {
    "anomaly": anomaly,
    "isolation_forest_score": round(float(score), 4),
    "utilization": util,
    "active_leases": int(active),
    "pool_size": int(pool),
    "slope_leases_per_hour": round(float(slope), 3),
    "hours_to_exhaustion": None if hours_to_exhaustion == float("inf") else round(hours_to_exhaustion, 1),
    "recommend_lease_seconds": int(recommend_lease),
    "message": "Anomaly detected" if anomaly else "Normal",
}
print(json.dumps(result))

Step 3 — Automate and alert

Tie it all together with a runner script. It logs a recommendation when the model sees an anomaly or forecasts exhaustion in < 8 hours.

Save as run_ai.sh:

chmod +x run_ai.sh
#!/usr/bin/env bash
set -euo pipefail

DATA_DIR="${DATA_DIR:-/var/lib/ai-dhcp}"
VENV="${VENV:-$DATA_DIR/venv}"
METRICS="${METRICS:-$DATA_DIR/metrics.csv}"

mkdir -p "$DATA_DIR"

# Collect metrics
LEASES_FILE="${LEASES_FILE:-/var/lib/dhcp/dhcpd.leases}" \
SYSLOG_FILE="${SYSLOG_FILE:-/var/log/syslog}" \
POOL_SIZE="${POOL_SIZE:-254}" \
bash ./dhcp_metrics.sh "$METRICS"

# Activate venv and run model
source "$VENV/bin/activate"
out=$(python3 ./ai_dhcp.py "$METRICS")
echo "$out" | jq .

# Example: alert to syslog if anomaly or low hours_to_exhaustion
anomaly=$(echo "$out" | jq -r '.anomaly')
hours=$(echo "$out" | jq -r '.hours_to_exhaustion // "inf"')
rec_lease=$(echo "$out" | jq -r '.recommend_lease_seconds')

if [[ "$anomaly" == "true" || ( "$hours" != "inf" && $(printf "%.0f" "$hours") -lt 8 ) ]]; then
  logger -t ai-dhcp "Action recommended: set lease to ${rec_lease}s; hours_to_exhaustion=$hours"
  echo "Recommended default-lease-time ${rec_lease};" > "$DATA_DIR/recommendation.conf"
  echo "Inspect $DATA_DIR/recommendation.conf and apply manually."
fi

Optional cron job (every 10 minutes):

sudo bash -lc 'cat >/etc/cron.d/ai-dhcp <<EOF
*/10 * * * * root cd /var/lib/ai-dhcp && /usr/bin/env bash /var/lib/ai-dhcp/run_ai.sh >> /var/log/ai-dhcp.log 2>&1
EOF'

Caution: Apply configuration changes deliberately. Test changes during maintenance windows. For ISC dhcpd, you might integrate a controlled update like:

# Example (manual): update lease times and restart dhcpd
sudo cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.bak.$(date +%s)
echo "default-lease-time 7200;" | sudo tee /etc/dhcp/dhcpd.d/lease-tuning.conf
echo "max-lease-time 86400;"   | sudo tee -a /etc/dhcp/dhcpd.d/lease-tuning.conf
# Include the drop-in from main dhcpd.conf once, then:
sudo systemctl restart isc-dhcp-server

Step 4 — Catch rogue DHCP servers (bonus)

A quick watcher that listens for DHCP OFFERs and flags MACs not on your whitelist.

Save as rogue_dhcp_watch.sh:

chmod +x rogue_dhcp_watch.sh
#!/usr/bin/env bash
# Detect DHCP OFFERs from unknown MACs (run with sudo)
set -euo pipefail

IFACE="${1:-eth0}"
WHITELIST_FILE="${WHITELIST_FILE:-/etc/ai-dhcp/authorized_dhcp_macs.txt}"

mkdir -p "$(dirname "$WHITELIST_FILE")"
touch "$WHITELIST_FILE"

echo "Listening on $IFACE for 15s..."
offers=$(timeout 15s tcpdump -i "$IFACE" -nn -v port 67 or port 68 2>/dev/null | grep -i "DHCP Offer" || true)

echo "$offers" | awk -v wl="$WHITELIST_FILE" '
  BEGIN{
    while((getline < wl) > 0){auth[tolower($0)]=1}
  }
  /Client-Ethernet-Address/{
    mac=tolower($NF)
    seen[mac]=1
  }
  END{
    for(m in seen){
      if(!(m in auth)){
        print "POTENTIAL ROGUE DHCP SERVER OFFER from MAC:", m
      }
    }
  }'

Run (with sudo) and add your legitimate server MACs to /etc/ai-dhcp/authorized_dhcp_macs.txt.


Real-world example output

After a few hours of data collection, you might see:

{"anomaly": false, "isolation_forest_score": 0.1187, "utilization": 83.1, "active_leases": 211, "pool_size": 254, "slope_leases_per_hour": 3.5, "hours_to_exhaustion": 12.3, "recommend_lease_seconds": 7200, "message":"Normal"}

Interpretation:

  • No anomaly, but utilization is high and rising.

  • You have ~12 hours until exhaustion at the current trend.

  • The system suggests a 2‑hour default lease to reduce pressure during peak.


Tips and adaptations

  • Kea users: Replace the lease/log parsing with curl calls to Kea Control Agent and jq the results into the same CSV schema.

  • Multiple subnets: Collect metrics per subnet (separate CSVs) and run one model per pool.

  • Visualization: Feed metrics.csv into your graphing tool or gnuplot to spot patterns quickly.

  • Safety: Keep the AI in “advisory” mode at first. Automate only after you trust its behavior.


Conclusion and next steps

You don’t need a massive platform to get AI value from DHCP. With a few Bash scripts and a small Python model, you can:

  • See issues hours before users do.

  • Cut down time spent trawling logs.

  • Right-size lease times automatically.

Your next step: 1) Install the prerequisites (apt/dnf/zypper commands above). 2) Drop in the scripts and start collecting metrics. 3) Run the AI model on a schedule and review its recommendations. 4) Expand to multiple pools and integrate with your change workflow.

Got a twisty environment (VLANs, multiple pools, relay agents)? Ask, and I’ll help tailor the collectors and features for your setup.