a51d968185
- Complete security menu restructure (3-mode: Analysis/Actions/Live) - Intelligent cPHulk enablement with CSF whitelist import - Live network security monitoring dashboard - Multi-source threat detection and classification - 50+ organized security tools across 4-level menu hierarchy - System health diagnostics with cPanel/WHM integration - Reference database for cross-module intelligence sharing
403 lines
14 KiB
Bash
Executable File
403 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
################################################################################
|
|
# Live Network Security Monitor
|
|
################################################################################
|
|
# Purpose: Real-time monitoring of active attacks and suspicious traffic
|
|
# Use Case: When server is currently under attack, monitor all activity live
|
|
# Author: Server Toolkit
|
|
#
|
|
# FEATURES:
|
|
# - Multi-source monitoring (SSH, Web, Email, Firewall)
|
|
# - Real-time threat detection and classification
|
|
# - Color-coded alerts (Critical/High/Medium/Low)
|
|
# - Live statistics dashboard
|
|
# - Connection tracking and blocking suggestions
|
|
# - Attack pattern recognition
|
|
################################################################################
|
|
|
|
# Get script directory
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
source "$SCRIPT_DIR/lib/common-functions.sh"
|
|
source "$SCRIPT_DIR/lib/system-detect.sh"
|
|
|
|
# Require root
|
|
if [ "$EUID" -ne 0 ]; then
|
|
print_error "This script must be run as root"
|
|
exit 1
|
|
fi
|
|
|
|
# Color definitions for threat levels
|
|
CRITICAL_COLOR='\033[1;41;97m' # White on Red background
|
|
HIGH_COLOR='\033[1;31m' # Bold Red
|
|
MEDIUM_COLOR='\033[1;33m' # Bold Yellow
|
|
LOW_COLOR='\033[0;36m' # Cyan
|
|
INFO_COLOR='\033[0;37m' # White
|
|
NC='\033[0m'
|
|
|
|
# Configuration
|
|
REFRESH_INTERVAL=2 # Seconds between dashboard refreshes
|
|
MAX_DISPLAY_LINES=30
|
|
THREAT_THRESHOLD_HIGH=10 # Requests per second from single IP
|
|
THREAT_THRESHOLD_MEDIUM=5
|
|
|
|
# Temporary files for tracking - use fixed directory for subshell access
|
|
TEMP_DIR="/tmp/live-monitor-current"
|
|
rm -rf "$TEMP_DIR" 2>/dev/null # Clean any previous session
|
|
mkdir -p "$TEMP_DIR"
|
|
touch "$TEMP_DIR/recent_events"
|
|
|
|
# Cleanup function to kill all child processes
|
|
cleanup() {
|
|
echo ""
|
|
echo "Stopping monitoring processes..."
|
|
|
|
# Kill all processes in this process group
|
|
kill $(jobs -p) 2>/dev/null
|
|
|
|
# Also kill any stray tail processes monitoring our logs
|
|
pkill -P $$ 2>/dev/null
|
|
|
|
# Clean up temp directory
|
|
rm -rf "$TEMP_DIR" 2>/dev/null
|
|
|
|
# Restore cursor
|
|
tput cnorm
|
|
|
|
echo "✓ Cleanup complete"
|
|
exit 0
|
|
}
|
|
|
|
trap cleanup EXIT INT TERM
|
|
|
|
# Statistics counters
|
|
declare -A IP_COUNTER
|
|
declare -A IP_THREAT_LEVEL
|
|
declare -A ATTACK_TYPE_COUNTER
|
|
declare -A BLOCKED_IPS
|
|
TOTAL_EVENTS=0
|
|
TOTAL_THREATS=0
|
|
START_TIME=$(date +%s)
|
|
|
|
# Hide cursor for cleaner display
|
|
tput civis
|
|
|
|
################################################################################
|
|
# Threat Classification Functions
|
|
################################################################################
|
|
|
|
classify_threat_level() {
|
|
local count="$1"
|
|
|
|
if [ "$count" -ge "$THREAT_THRESHOLD_HIGH" ]; then
|
|
echo "CRITICAL"
|
|
elif [ "$count" -ge "$THREAT_THRESHOLD_MEDIUM" ]; then
|
|
echo "HIGH"
|
|
else
|
|
echo "MEDIUM"
|
|
fi
|
|
}
|
|
|
|
get_threat_color() {
|
|
local level="$1"
|
|
|
|
case "$level" in
|
|
CRITICAL) echo "$CRITICAL_COLOR" ;;
|
|
HIGH) echo "$HIGH_COLOR" ;;
|
|
MEDIUM) echo "$MEDIUM_COLOR" ;;
|
|
LOW) echo "$LOW_COLOR" ;;
|
|
*) echo "$INFO_COLOR" ;;
|
|
esac
|
|
}
|
|
|
|
identify_attack_type() {
|
|
local log_line="$1"
|
|
|
|
# SSH brute force
|
|
if echo "$log_line" | grep -qi "Failed password\|authentication failure"; then
|
|
echo "SSH_BRUTEFORCE"
|
|
# SQL injection attempts
|
|
elif echo "$log_line" | grep -qiE "union.*select|concat.*\(|substring.*\(|' or '1'='1"; then
|
|
echo "SQL_INJECTION"
|
|
# XSS attempts
|
|
elif echo "$log_line" | grep -qiE "<script|javascript:|onerror=|onload="; then
|
|
echo "XSS_ATTACK"
|
|
# Path traversal
|
|
elif echo "$log_line" | grep -qE "\.\./|\.\.%2[fF]"; then
|
|
echo "PATH_TRAVERSAL"
|
|
# Port scanning
|
|
elif echo "$log_line" | grep -qi "port scan\|SYN_RECV"; then
|
|
echo "PORT_SCAN"
|
|
# Directory enumeration
|
|
elif echo "$log_line" | grep -qE "404.*\.(php|asp|jsp|cgi)"; then
|
|
echo "DIR_ENUM"
|
|
# Bot/crawler
|
|
elif echo "$log_line" | grep -qiE "bot|crawler|spider|scraper"; then
|
|
echo "BOT"
|
|
# DDoS patterns
|
|
elif echo "$log_line" | grep -qi "SYN flood\|UDP flood"; then
|
|
echo "DDOS"
|
|
# Exploit attempts
|
|
elif echo "$log_line" | grep -qiE "exploit|shell|backdoor|webshell"; then
|
|
echo "EXPLOIT"
|
|
# Excessive requests (likely DDoS or bot)
|
|
else
|
|
echo "SUSPICIOUS"
|
|
fi
|
|
}
|
|
|
|
get_attack_icon() {
|
|
local attack_type="$1"
|
|
|
|
case "$attack_type" in
|
|
SSH_BRUTEFORCE) echo "🔐" ;;
|
|
SQL_INJECTION) echo "💉" ;;
|
|
XSS_ATTACK) echo "⚠️ " ;;
|
|
PATH_TRAVERSAL) echo "📁" ;;
|
|
PORT_SCAN) echo "🔍" ;;
|
|
DIR_ENUM) echo "📂" ;;
|
|
BOT) echo "🤖" ;;
|
|
DDOS) echo "💥" ;;
|
|
EXPLOIT) echo "☠️ " ;;
|
|
*) echo "❓" ;;
|
|
esac
|
|
}
|
|
|
|
################################################################################
|
|
# Dashboard Display Functions
|
|
################################################################################
|
|
|
|
draw_header() {
|
|
clear
|
|
local uptime=$(($(date +%s) - START_TIME))
|
|
local uptime_str=$(printf "%02d:%02d:%02d" $((uptime/3600)) $((uptime%3600/60)) $((uptime%60)))
|
|
|
|
echo -e "${CRITICAL_COLOR}╔════════════════════════════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${CRITICAL_COLOR}║ 🚨 LIVE NETWORK SECURITY MONITOR 🚨 ║${NC}"
|
|
echo -e "${CRITICAL_COLOR}╚════════════════════════════════════════════════════════════════════════════╝${NC}"
|
|
echo -e "${INFO_COLOR}Runtime: ${uptime_str} | Events: ${TOTAL_EVENTS} | Threats Detected: ${TOTAL_THREATS} | Monitoring...${NC}"
|
|
echo ""
|
|
}
|
|
|
|
draw_statistics_panel() {
|
|
echo -e "${HIGH_COLOR}┌─ THREAT STATISTICS ────────────────────────────────────────────────────────┐${NC}"
|
|
|
|
# Top attacking IPs
|
|
echo -e "${MEDIUM_COLOR}Top Attacking IPs:${NC}"
|
|
local count=0
|
|
for ip in "${!IP_COUNTER[@]}"; do
|
|
local hits="${IP_COUNTER[$ip]}"
|
|
local level="${IP_THREAT_LEVEL[$ip]:-MEDIUM}"
|
|
local color=$(get_threat_color "$level")
|
|
|
|
printf "${color} %-15s %5d hits [%s]${NC}\n" "$ip" "$hits" "$level"
|
|
|
|
((count++))
|
|
[ $count -ge 5 ] && break
|
|
done | sort -t' ' -k2 -rn
|
|
|
|
echo ""
|
|
|
|
# Attack type breakdown
|
|
echo -e "${MEDIUM_COLOR}Attack Type Distribution:${NC}"
|
|
for attack_type in "${!ATTACK_TYPE_COUNTER[@]}"; do
|
|
local count="${ATTACK_TYPE_COUNTER[$attack_type]}"
|
|
local icon=$(get_attack_icon "$attack_type")
|
|
printf " ${icon} %-20s %5d\n" "$attack_type" "$count"
|
|
done | sort -t' ' -k3 -rn | head -5
|
|
|
|
echo -e "${HIGH_COLOR}└────────────────────────────────────────────────────────────────────────────┘${NC}"
|
|
echo ""
|
|
}
|
|
|
|
draw_live_feed() {
|
|
echo -e "${HIGH_COLOR}┌─ LIVE THREAT FEED ─────────────────────────────────────────────────────────┐${NC}"
|
|
|
|
if [ -f "$TEMP_DIR/recent_events" ]; then
|
|
tail -n "$MAX_DISPLAY_LINES" "$TEMP_DIR/recent_events"
|
|
else
|
|
echo -e "${LOW_COLOR} Waiting for events...${NC}"
|
|
fi
|
|
|
|
echo -e "${HIGH_COLOR}└────────────────────────────────────────────────────────────────────────────┘${NC}"
|
|
echo ""
|
|
}
|
|
|
|
draw_action_suggestions() {
|
|
echo -e "${MEDIUM_COLOR}┌─ SUGGESTED ACTIONS ────────────────────────────────────────────────────────┐${NC}"
|
|
|
|
# Suggest blocking top attackers
|
|
local suggested=0
|
|
for ip in "${!IP_COUNTER[@]}"; do
|
|
local hits="${IP_COUNTER[$ip]}"
|
|
local level="${IP_THREAT_LEVEL[$ip]}"
|
|
|
|
if [ "$level" = "CRITICAL" ] && [ -z "${BLOCKED_IPS[$ip]}" ]; then
|
|
echo -e " ${CRITICAL_COLOR}▶${NC} Block IP immediately: ${HIGH_COLOR}csf -d $ip${NC}"
|
|
((suggested++))
|
|
[ $suggested -ge 3 ] && break
|
|
fi
|
|
done
|
|
|
|
if [ $suggested -eq 0 ]; then
|
|
echo -e "${LOW_COLOR} No immediate actions required at this time${NC}"
|
|
fi
|
|
|
|
echo -e "${MEDIUM_COLOR}└────────────────────────────────────────────────────────────────────────────┘${NC}"
|
|
echo ""
|
|
echo -e "${INFO_COLOR}Press Ctrl+C to exit | Updates every ${REFRESH_INTERVAL}s${NC}"
|
|
}
|
|
|
|
################################################################################
|
|
# Log Monitoring Functions
|
|
################################################################################
|
|
|
|
monitor_ssh_attacks() {
|
|
# Monitor SSH brute force attempts
|
|
if [ -f "/var/log/secure" ]; then
|
|
tail -n 0 -F /var/log/secure 2>/dev/null | while read -r line; do
|
|
if echo "$line" | grep -qi "Failed password\|authentication failure"; then
|
|
local ip=$(echo "$line" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)
|
|
if [ -n "$ip" ]; then
|
|
process_threat_event "$ip" "SSH_BRUTEFORCE" "$line"
|
|
fi
|
|
fi
|
|
done &
|
|
fi
|
|
}
|
|
|
|
monitor_web_attacks() {
|
|
# Monitor Apache access logs for web attacks
|
|
local access_log="/var/log/apache2/domlogs/*"
|
|
|
|
if ls $access_log >/dev/null 2>&1; then
|
|
tail -n 0 -F $access_log 2>/dev/null | while read -r line; do
|
|
local ip=$(echo "$line" | awk '{print $1}')
|
|
local request=$(echo "$line" | awk '{print $7}')
|
|
|
|
# Check for suspicious patterns
|
|
if echo "$line" | grep -qiE "union.*select|<script|\.\.\/|\' or |exec\("; then
|
|
local attack_type=$(identify_attack_type "$line")
|
|
process_threat_event "$ip" "$attack_type" "$request"
|
|
# Track high-frequency requests (potential DDoS)
|
|
elif [ -n "$ip" ]; then
|
|
((IP_COUNTER[$ip]++))
|
|
if [ "${IP_COUNTER[$ip]}" -gt "$THREAT_THRESHOLD_MEDIUM" ]; then
|
|
process_threat_event "$ip" "HIGH_FREQUENCY" "$request"
|
|
fi
|
|
fi
|
|
done &
|
|
fi
|
|
}
|
|
|
|
monitor_firewall_blocks() {
|
|
# Monitor CSF/iptables blocks in real-time
|
|
if [ -f "/var/log/messages" ]; then
|
|
tail -n 0 -F /var/log/messages 2>/dev/null | while read -r line; do
|
|
if echo "$line" | grep -qi "Firewall\|iptables\|DENY"; then
|
|
local ip=$(echo "$line" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)
|
|
if [ -n "$ip" ]; then
|
|
BLOCKED_IPS[$ip]=1
|
|
log_event "$ip" "FIREWALL_BLOCK" "${LOW_COLOR}" "Blocked by firewall"
|
|
fi
|
|
fi
|
|
done &
|
|
fi
|
|
}
|
|
|
|
monitor_cphulk_blocks() {
|
|
# Monitor cPHulk blocks
|
|
if [ -x "/usr/local/cpanel/bin/cphulk_pam_ctl" ]; then
|
|
# Poll cPHulk status periodically
|
|
while true; do
|
|
whmapi1 cphulkd_list_blocks 2>/dev/null | grep -E "ip:" | while read -r line; do
|
|
local ip=$(echo "$line" | awk '{print $2}')
|
|
if [ -n "$ip" ] && [ -z "${BLOCKED_IPS[$ip]}" ]; then
|
|
BLOCKED_IPS[$ip]=1
|
|
log_event "$ip" "CPHULK_BLOCK" "${MEDIUM_COLOR}" "Blocked by cPHulk"
|
|
fi
|
|
done
|
|
sleep 5
|
|
done &
|
|
fi
|
|
}
|
|
|
|
################################################################################
|
|
# Event Processing
|
|
################################################################################
|
|
|
|
process_threat_event() {
|
|
local ip="$1"
|
|
local attack_type="$2"
|
|
local details="$3"
|
|
|
|
# Update counters
|
|
((IP_COUNTER[$ip]++))
|
|
((ATTACK_TYPE_COUNTER[$attack_type]++))
|
|
((TOTAL_EVENTS++))
|
|
((TOTAL_THREATS++))
|
|
|
|
# Classify threat level
|
|
local threat_level=$(classify_threat_level "${IP_COUNTER[$ip]}")
|
|
IP_THREAT_LEVEL[$ip]="$threat_level"
|
|
|
|
# Log to feed
|
|
log_event "$ip" "$attack_type" "$(get_threat_color "$threat_level")" "$details"
|
|
}
|
|
|
|
log_event() {
|
|
local ip="$1"
|
|
local attack_type="$2"
|
|
local color="$3"
|
|
local details="$4"
|
|
|
|
local timestamp=$(date '+%H:%M:%S')
|
|
local icon=$(get_attack_icon "$attack_type")
|
|
local hits="${IP_COUNTER[$ip]:-1}"
|
|
|
|
# Truncate details if too long
|
|
details=$(echo "$details" | cut -c1-60)
|
|
|
|
# Format: [TIME] ICON IP (hits) - TYPE - details
|
|
printf "${color}[%s] %s %-15s (%3d) %-20s %s${NC}\n" \
|
|
"$timestamp" "$icon" "$ip" "$hits" "$attack_type" "$details" \
|
|
>> "$TEMP_DIR/recent_events"
|
|
}
|
|
|
|
################################################################################
|
|
# Main Monitoring Loop
|
|
################################################################################
|
|
|
|
main() {
|
|
print_banner "Live Network Security Monitor"
|
|
|
|
echo ""
|
|
echo "Starting multi-source threat monitoring..."
|
|
echo " • SSH brute force detection"
|
|
echo " • Web attack detection (SQL, XSS, etc.)"
|
|
echo " • Firewall block monitoring"
|
|
echo " • cPHulk activity monitoring"
|
|
echo ""
|
|
echo "Press Ctrl+C to stop..."
|
|
sleep 3
|
|
|
|
# Start all monitoring processes
|
|
monitor_ssh_attacks
|
|
monitor_web_attacks
|
|
monitor_firewall_blocks
|
|
monitor_cphulk_blocks
|
|
|
|
# Main display loop
|
|
while true; do
|
|
draw_header
|
|
draw_statistics_panel
|
|
draw_live_feed
|
|
draw_action_suggestions
|
|
|
|
sleep "$REFRESH_INTERVAL"
|
|
done
|
|
}
|
|
|
|
# Run main
|
|
main
|