Now its time to improve the looks of the dashboard page...
So, I want to organise
the dashboard more professionally, instead of making it look so congested....All
the functionality is properly done so no changes in the functionality but I want to
make it look very clean immersive professional and attractive so that users will
have a good experience using it
import pandas as pd
import joblib
import time
import csv
import numpy as np
from flask import Flask, render_template, request, jsonify
import [Link] as px
from dash import dcc, html
import [Link] as plt
from fpdf import FPDF
import os
import dash
from [Link] import Input, Output
from [Link] import sniff, IP
from [Link] import ARIMA
from [Link] import IsolationForest
import smtplib
from [Link] import MIMEMultipart
from [Link] import MIMEText
from fpdf import FPDF
import threading
app = Flask(__name__)
file_name = "network_data.csv"
subscribed_emails = set()
def load_data():
try:
df = pd.read_csv(file_name, header=None, names=["Timestamp", "Source IP",
"Destination IP", "Protocol", "Packet Size", "Anomaly"],
on_bad_lines='skip', engine='python', dtype=str)
# Explicitly define the timestamp format based on your CSB data
df['Timestamp'] = pd.to_datetime(df['Timestamp'], format="%Y-%m-%d %H:%M:
%S", errors='coerce')
# Convert 'Packet Size' to numeric and remove non-numeric characters
df['Packet Size'] = pd.to_numeric(df['Packet Size'].[Link](r'\D', '',
regex=True), errors='coerce')
[Link](inplace=True)
# Convert 'Anomaly' column to boolean values
df['Anomaly'] = df['Anomaly'].map({'True': True, 'False': False})
[Link](inplace=True)
return df
except Exception as e:
print(f"❌ Error loading CSV: {e}")
return [Link]()
def train_arima():
df = load_data()
if [Link]:
return
df = df[['Timestamp', 'Packet
Size']].set_index('Timestamp').resample('T').mean().fillna(0)
df['Packet Size'] = df['Packet Size'].diff().fillna(0)
model = ARIMA(df['Packet Size'], order=(1,1,1))
arima_model = [Link]()
[Link](arima_model, "arima_model.pkl")
def train_isolation_forest():
df = load_data()
if [Link]:
return
if len(df) > 1000:
df = df[-1000:]
model = IsolationForest(contamination=0.01, random_state=42)
[Link](df[['Packet Size']])
[Link](model, "isolation_forest.pkl")
def load_arima():
return [Link]("arima_model.pkl")
def load_isolation_forest():
return [Link]("isolation_forest.pkl")
arima_model = None
isolation_forest_model = None
def load_models():
global arima_model, isolation_forest_model
try:
arima_model = [Link]("arima_model.pkl")
isolation_forest_model = [Link]("isolation_forest.pkl")
print("✅ Models loaded successfully!")
except Exception as e:
print(f"⚠️ Model loading failed: {e}")
def detect_anomalies(packet_size):
try:
arima_model = load_arima()
isolation_model = load_isolation_forest()
X_new = [Link]([[packet_size]], columns=['Packet Size'])
isolation_prediction = isolation_model.predict(X_new)[0] == -1
forecast = arima_model.forecast(steps=1)[0]
arima_anomaly = packet_size > forecast * 2
return arima_anomaly and isolation_prediction
except Exception as e:
print(f"⚠️ Error in anomaly detection: {e}")
return False
def send_email_alert(packet_size, src_ip, dst_ip):
try:
sender_email = "nuhayd.m.k@[Link]"
password = "unsq dtzd vlnd eylz"
subject = "🚨 Network Anomaly Detected"
message = f"Alert! Anomalous packet detected.\nPacket Size: {packet_size}\
nSource IP: {src_ip}\nDestination IP: {dst_ip}"
server = [Link]('[Link]', 587)
[Link]()
[Link](sender_email, password)
for email in subscribed_emails:
msg = MIMEMultipart()
msg['From'] = sender_email
msg['To'] = email
msg['Subject'] = subject
[Link](MIMEText(message, 'plain'))
server.send_message(msg)
[Link]()
print(f"📩 Email alert sent to {len(subscribed_emails)} users!")
except Exception as e:
print(f"⚠️ Failed to send email: {e}")
def packet_callback(packet):
try:
timestamp = [Link]('%Y-%m-%d %H:%M:%S', [Link]())
src_ip = packet[IP].src if [Link](IP) else "N/A"
dst_ip = packet[IP].dst if [Link](IP) else "N/A"
protocol = [Link]()
packet_size = len(packet)
anomaly = detect_anomalies(packet_size)
with open(file_name, mode='a', newline='') as file:
writer = [Link](file)
[Link]([timestamp, src_ip, dst_ip, protocol, packet_size,
anomaly])
except Exception as e:
print(f"⚠️ Error processing packet: {e}")
def start_sniffing():
sniff(prn=packet_callback, store=False)
dash_app = [Link](__name__, server=app, routes_pathname_prefix='/dashboard/')
dash_app.layout = [Link]([
html.H1("🚨 Real-Time Network Traffic Monitoring"),
[Link](id="live-graph"),
[Link](id="anomaly-alerts", style={'color': 'red', 'font-weight': 'bold',
'font-size': '18px'}),
[Link](id="interval-update", interval=60000, n_intervals=0)
])
@dash_app.callback(
[Output("live-graph", "figure"), Output("anomaly-alerts", "children")],
[Input("interval-update", "n_intervals")]
)
def update_graph(n):
df = load_data()
if [Link]:
return [Link](title="No Data Available"), "✅ No anomalies detected"
# Mark anomalies in red
df['Color'] = df['Anomaly'].apply(lambda x: 'red' if x else 'blue')
# **Possible Reason Mapping** (Customize as per your network knowledge)
df['Reason'] = df['Packet Size'].apply(lambda x:
"Unusual High Traffic" if x > 15000 else
"Suspicious Small Packets" if x < 500 else
"Potential Data Exfiltration"
)
# **Plotly Graph with Source IP & Reason in Hover**
fig = [Link](
df, x="Timestamp", y="Packet Size", color='Color',
title="Live Network Bandwidth (Anomalies in Red)",
labels={'Color': 'Anomaly Status'},
hover_data=["Source IP", "Reason"] # Adding Source IP & Reason
)
# **Anomaly Alert Message**
anomalies = df[df['Anomaly']]
if [Link]:
alert_message = "✅ No anomalies detected"
else:
alert_message = "🚨 Anomalies detected!\n"
for index, row in [Link]():
alert_message += f"🔴 {row['Timestamp']} | Source: {row['Source IP']} |
{row['Reason']}\n"
return fig, alert_message
@[Link]('/get_anomalies')
def get_anomalies():
df = load_data()
if [Link]:
return jsonify({"anomalies": [], "totalPackets": 0, "totalAnomalies": 0})
anomalies = df[df['Anomaly'] == True].tail(5).to_dict('records')
anomaly_messages = [f"{a['Timestamp']} | {a['Source IP']} ➝ {a['Destination
IP']} | {a['Packet Size']} bytes" for a in anomalies]
return jsonify({
"anomalies": anomaly_messages,
"totalPackets": len(df),
"totalAnomalies": len(df[df['Anomaly'] == True])
})
import os
# File to store subscribed emails
SUBSCRIPTION_FILE = "subscribed_emails.txt"
# Load previously subscribed emails from file
def load_subscribed_emails():
if [Link](SUBSCRIPTION_FILE):
with open(SUBSCRIPTION_FILE, "r") as file:
return set([Link]().splitlines())
return set()
# Save the updated subscribed emails to file
def save_subscribed_email(email):
with open(SUBSCRIPTION_FILE, "a") as file:
[Link](email + "\n")
# Load emails when the app starts
subscribed_emails = load_subscribed_emails()
@[Link]('/subscribe_email', methods=['POST'])
def subscribe_email():
email = [Link]("email")
if not email:
return jsonify({"message": "❌ Invalid email!"})
if email in subscribed_emails:
return jsonify({"message": "⚠️ You are already subscribed!"}) # Prevent
duplicate subscription
# Add email to the subscription list
subscribed_emails.add(email)
save_subscribed_email(email) # Save it to file
# Send confirmation email
try:
sender_email = "nuhayd.m.k@[Link]"
password = "unsq dtzd vlnd eylz"
subject = "✅ Subscription Confirmed: Network Alerts"
message = f"Hello,\n\nYou have successfully subscribed to network anomaly
alerts. You will receive an email if any unusual high traffic is detected.\n\
nRegards,\nNetwork Monitoring System"
server = [Link]('[Link]', 587)
[Link]()
[Link](sender_email, password)
msg = MIMEMultipart()
msg['From'] = sender_email
msg['To'] = email
msg['Subject'] = subject
[Link](MIMEText(message, 'plain'))
server.send_message(msg)
[Link]()
return jsonify({"message": "✅ Email subscribed successfully! Confirmation
email sent."})
except Exception as e:
print(f"⚠️ Failed to send confirmation email: {e}")
return jsonify({"message": "⚠️ Subscription successful, but failed to send
confirmation email."})
def wait_for_models():
while not [Link]("arima_model.pkl") or not
[Link]("isolation_forest.pkl"):
print("⏳ Waiting for models to be trained...")
[Link](5)
def generate_anomaly_report():
df = load_data()
if [Link]:
return None
# Generate Traffic Trend Graph
fig, ax = [Link](figsize=(8, 4))
[Link](x="Timestamp", y="Packet Size", ax=ax, title="Network Traffic Trend",
legend=False)
ax.set_xlabel("Time")
ax.set_ylabel("Packet Size")
[Link](rotation=45)
plt.tight_layout()
traffic_graph = "traffic_graph.png"
[Link](traffic_graph)
[Link]()
# Generate Pie Chart (Legit vs. Anomalous)
anomaly_counts = df["Anomaly"].value_counts()
labels = ["Legit Packets", "Anomalous Packets"]
sizes = [anomaly_counts.get(False, 0), anomaly_counts.get(True, 0)]
colors = ["green", "red"]
fig, ax = [Link](figsize=(5, 5))
[Link](sizes, labels=labels, colors=colors, autopct="%1.1f%%", startangle=90,
wedgeprops={"edgecolor": "black"})
ax.set_title("Packet Distribution")
pie_chart = "pie_chart.png"
[Link](pie_chart)
[Link]()
suspicious_packet = df[df["Anomaly"] == True].nlargest(1, "Packet Size")
if not suspicious_packet.empty:
most_suspicious = suspicious_packet.iloc[0]
source_ip = most_suspicious["Source IP"]
destination_ip = most_suspicious["Destination IP"]
packet_size = most_suspicious["Packet Size"]
reason = "Unusually high traffic detected."
else:
source_ip = "N/A"
destination_ip = "N/A"
packet_size = "N/A"
reason = "No major anomalies detected."
solution = "Investigate the source IP, check for large data exfiltration, and
monitor for unusual access patterns."
# **Step 5: Create PDF Report**
pdf = FPDF()
pdf.set_auto_page_break(auto=True, margin=15)
pdf.add_page()
pdf.set_font("Arial", "B", 16)
[Link](200, 10, "Network Anomaly Report", ln=True, align="C")
# **Add Suspicious Packet Details**
[Link](10)
pdf.set_font("Arial", "B", 12)
[Link](200, 10, "🔴 Most Suspicious Packet Detected:", ln=True)
pdf.set_font("Arial", "", 12)
pdf.multi_cell(0, 8, f"📌 Source IP: {source_ip}\n📌 Destination IP:
{destination_ip}\n📌 Packet Size: {packet_size} bytes\n📌 Reason: {reason}")
# **Add Solution**
[Link](5)
pdf.set_font("Arial", "B", 12)
[Link](200, 10, "🛠 Suggested Solution:", ln=True)
pdf.set_font("Arial", "", 12)
pdf.multi_cell(0, 8, f"{solution}")
# **Insert Traffic Graph**
[Link](10)
[Link](traffic_graph, x=10, w=180)
# **Insert Pie Chart**
[Link](10)
[Link](pie_chart, x=40, w=120)
# **Save PDF Report**
pdf_filename = "anomaly_report.pdf"
[Link](pdf_filename)
# Cleanup Images
[Link](traffic_graph)
[Link](pie_chart)
return pdf_filename
def send_email_alert(packet_size, src_ip, dst_ip):
try:
if packet_size <= 15000: # alerts for high traffic only
return
sender_email = "nuhayd.m.k@[Link]"
password = "unsq dtzd vlnd eylz"
subject = "🚨 High Traffic Alert: Network Anomaly Detected"
message = f"⚠️ Unusual High Traffic detected!\nPacket Size: {packet_size}
bytes\nSource IP: {src_ip}\nDestination IP: {dst_ip}\n\n📎 Attached: Detailed
Network Report (PDF)."
server = [Link]('[Link]', 587)
[Link]()
[Link](sender_email, password)
# Generate the PDF Report
pdf_filename = generate_anomaly_report()
for email in subscribed_emails:
msg = MIMEMultipart()
msg['From'] = sender_email
msg['To'] = email
msg['Subject'] = subject
[Link](MIMEText(message, 'plain'))
if pdf_filename:
with open(pdf_filename, "rb") as attachment:
pdf_attachment = MIMEText([Link](), "base64")
pdf_attachment.add_header("Content-Disposition", f"attachment;
filename={pdf_filename}")
[Link](pdf_attachment)
server.send_message(msg)
[Link]()
[Link](pdf_filename) # Cleanup
print(f"📩 High traffic alert with PDF report sent to
{len(subscribed_emails)} users!")
except Exception as e:
print(f"⚠️ Failed to send high traffic alert: {e}")
@[Link]('/')
def index():
return render_template("[Link]")
if __name__ == "__main__":
[Link](target=start_sniffing, daemon=True).start()
train_arima()
train_isolation_forest()
wait_for_models() # Ensure models exist before starting Flask
load_models()
[Link](debug=True, port=5000)
my [Link]
and [Link]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Network Monitoring Dashboard</title>
<link rel="stylesheet" href="{{ url_for('static', filename='[Link]')}}">
<link rel="stylesheet"
href="[Link]
>
<script
src="[Link]
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Network Monitoring System</a>
</div>
</nav>
<div class="container mt-4">
<div class="row">
<div class="col-md-6">
<div class="card p-3">
<h4>Live Network Traffic</h4>
<iframe src="/dashboard/" width="100%" height="400px"
style="border: none;"></iframe>
</div>
</div>
<div class="col-md-6">
<div class="card p-3">
<h4>Real-Time Anomaly Alerts</h4>
<ul id="anomalyList" class="list-group"></ul>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-6">
<div class="card p-3">
<h4>Email Alerts</h4>
<form id="emailForm">
<label for="email">Enter Email for Alerts:</label>
<input type="email" id="email" class="form-control mb-2"
required>
<button type="submit" class="btn
btn-primary">Subscribe</button>
</form>
<div id="responseMessage" class="mt-3"></div>
</div>
</div>
<div class="col-md-6">
<div class="card p-3">
<h4>Network Statistics</h4>
<p><strong>Total Packets Monitored:</strong> <span
id="totalPackets">0</span></p>
<p><strong>Total Anomalies Detected:</strong> <span
id="totalAnomalies">0</span></p>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
$('#emailForm').submit(function(event){
[Link]();
let email = $('#email').val();
$.post('/subscribe_email', {email: email},
function(response){
$('#responseMessage').text([Link]);
}, 'json');
});
function fetchAnomalies() {
$.getJSON('/get_anomalies', function(data) {
$('#anomalyList').empty();
$('#totalPackets').text([Link]);
$('#totalAnomalies').text([Link]);
[Link](function(anomaly) {
$('#anomalyList').append('<li class="list-group-
item list-group-item-danger">' + anomaly + '</li>');
});
});
}
$('#sendAlert').click(function(){
$.post('/send_email_alert', function(response){
alert([Link]);
}, 'json');
});
setInterval(fetchAnomalies, 5000);
});
</script>
</body>
</html>