Files
Linux-Server-Management-Too…/modules/security/live-attack-monitor.sh
T
cschantz da01bd33c3 Fix integer expression error in variable validation
Properly handle grep output to prevent newlines and invalid values:
- Use explicit if/else instead of || fallback operator
- Strip all whitespace from grep results
- Validate variables match numeric pattern before use
- Set to 0 if validation fails

Prevents 'integer expression expected' errors when comparing values
2025-11-14 16:25:37 -05:00

1437 lines
55 KiB
Bash
Executable File

#!/bin/bash
################################################################################
# Live Network Security Monitor - ENHANCED with Intelligence
################################################################################
# Purpose: Real-time monitoring with bot intelligence and threat scoring
# Version: 2.0 - Intelligence Mode
# Features:
# - Bot classification using learned signatures
# - IP reputation DB integration
# - Real-time threat scoring (0-100)
# - Attack vector detection
# - Quick action blocking system
# - Ban tracking and history
################################################################################
# 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"
source "$SCRIPT_DIR/lib/ip-reputation.sh"
source "$SCRIPT_DIR/lib/bot-signatures.sh"
source "$SCRIPT_DIR/lib/attack-patterns.sh"
source "$SCRIPT_DIR/lib/threat-intelligence.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
SAFE_COLOR='\033[0;32m' # Green
INFO_COLOR='\033[0;37m' # White
BOLD='\033[1m' # Bold text
NC='\033[0m'
# Configuration
REFRESH_INTERVAL=2 # Seconds between dashboard refreshes
MAX_DISPLAY_LINES=20
THREAT_THRESHOLD_CRITICAL=80
THREAT_THRESHOLD_HIGH=60
THREAT_THRESHOLD_MEDIUM=40
# Temporary files for tracking
TEMP_DIR="/tmp/live-monitor-$$"
SNAPSHOT_DIR="/var/lib/server-toolkit/live-monitor"
mkdir -p "$TEMP_DIR" "$SNAPSHOT_DIR" 2>/dev/null
touch "$TEMP_DIR/recent_events"
touch "$TEMP_DIR/ip_data"
echo "0" > "$TEMP_DIR/event_counter"
# Save snapshot of IP data (for persistence across restarts)
save_snapshot() {
{
for ip in "${!IP_DATA[@]}"; do
echo "$ip=${IP_DATA[$ip]}"
done
} > "$SNAPSHOT_DIR/ip_data_snapshot" 2>/dev/null
}
# Cleanup function
cleanup() {
echo ""
echo "Stopping monitoring processes..."
# Save snapshot before exit
save_snapshot
# Kill all child processes
pkill -P $$ 2>/dev/null
# Wait a moment for background jobs
sleep 1
# Clean up temp directory
rm -rf "$TEMP_DIR" 2>/dev/null
# Restore cursor
command -v tput &>/dev/null && tput cnorm
echo "✓ Cleanup complete (snapshot saved)"
exit 0
}
trap cleanup EXIT INT TERM
# Statistics counters
declare -A IP_DATA # Stores: IP -> score|hits|bot_type|attacks|ban_count
declare -A ATTACK_TYPE_COUNTER
TOTAL_THREATS=0
START_TIME=$(date +%s)
MAX_TRACKED_IPS=500 # Prevent memory overflow
# Load persistent data from previous sessions if exists
if [ -f "$SNAPSHOT_DIR/ip_data_snapshot" ]; then
while IFS='=' read -r ip data; do
[ -n "$ip" ] && IP_DATA[$ip]="$data"
done < "$SNAPSHOT_DIR/ip_data_snapshot"
fi
# Hide cursor for cleaner display
command -v tput &>/dev/null && tput civis
################################################################################
# Intelligence Functions
################################################################################
# Get or create IP intelligence data
# Returns: score|hits|bot_type|attacks|ban_count|rep_score
get_ip_intelligence() {
local ip="$1"
# Check if we have cached data
if [ -n "${IP_DATA[$ip]}" ]; then
echo "${IP_DATA[$ip]}"
return 0
fi
# Query IP reputation database
local rep_data=$(lookup_ip "$ip" 2>/dev/null)
if [ -n "$rep_data" ]; then
# Parse: IP|HIT_COUNT|REP_SCORE|COUNTRY|ATTACK_FLAGS|...
IFS='|' read -r _ db_hits rep_score country attack_flags _ _ _ notes ban_count _ <<< "$rep_data"
# Initialize with learned data
local score=${rep_score:-0}
local hits=${db_hits:-0}
local bot_type="unknown"
local attacks=$(decode_attack_flags "$attack_flags" 2>/dev/null | tr ',' ' ' || echo "")
ban_count=${ban_count:-0}
# Cache it
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
echo "${IP_DATA[$ip]}"
else
# New IP - initialize
IP_DATA[$ip]="0|0|unknown||0|0"
echo "${IP_DATA[$ip]}"
fi
}
# Update IP intelligence
update_ip_intelligence() {
local ip="$1"
local url="$2"
local user_agent="$3"
local method="${4:-GET}"
# Get current data
local current=$(get_ip_intelligence "$ip")
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current"
# Increment hits
hits=$((hits + 1))
# Enrich with threat intelligence on first encounter (hits == 1)
if [ $hits -eq 1 ]; then
# Check if whitelisted first
if is_whitelisted_service "$ip" 2>/dev/null; then
score=0
bot_type="legit"
else
# Get threat intelligence (in background to avoid slowing down)
(
local threat_intel=$(get_threat_intelligence "$ip" 2>/dev/null)
IFS='|' read -r abuse_conf abuse_rpts country isp geo timing whitelisted <<< "$threat_intel"
# Store enrichment data for later use
local enrich_file="$TEMP_DIR/threat_enrich_${ip//\./_}"
echo "$threat_intel" > "$enrich_file"
# Boost score based on AbuseIPDB confidence
if [ "${abuse_conf:-0}" -ge 75 ]; then
# High confidence malicious - add 30 points
local current_data="${IP_DATA[$ip]}"
IFS='|' read -r old_score old_hits old_bot old_attacks old_ban old_rep <<< "$current_data"
local new_score=$((old_score + 30))
[ $new_score -gt 100 ] && new_score=100
IP_DATA[$ip]="$new_score|$old_hits|$old_bot|$old_attacks|$old_ban|$old_rep"
elif [ "${abuse_conf:-0}" -ge 50 ]; then
# Medium confidence - add 15 points
local current_data="${IP_DATA[$ip]}"
IFS='|' read -r old_score old_hits old_bot old_attacks old_ban old_rep <<< "$current_data"
local new_score=$((old_score + 15))
[ $new_score -gt 100 ] && new_score=100
IP_DATA[$ip]="$new_score|$old_hits|$old_bot|$old_attacks|$old_ban|$old_rep"
fi
# High-risk country adds 5 points
if is_high_risk_country "${geo:-XX}" 2>/dev/null; then
local current_data="${IP_DATA[$ip]}"
IFS='|' read -r old_score old_hits old_bot old_attacks old_ban old_rep <<< "$current_data"
local new_score=$((old_score + 5))
[ $new_score -gt 100 ] && new_score=100
IP_DATA[$ip]="$new_score|$old_hits|$old_bot|$old_attacks|$old_ban|$old_rep"
fi
) &
fi
fi
# Classify bot if unknown
if [ "$bot_type" = "unknown" ] && [ -n "$user_agent" ]; then
bot_type=$(classify_bot_type "$user_agent")
fi
# Record attack pattern for learning
if [ -n "$url" ]; then
record_attack_pattern "$ip" "${attacks:-unknown}" "$url" "${user_agent:-unknown}" 2>/dev/null &
fi
# Detect attacks in URL
local new_attacks=$(detect_all_attacks "$url" "$method")
if [ -n "$new_attacks" ]; then
# Add to attack list (unique)
if [ -z "$attacks" ]; then
attacks="$new_attacks"
else
attacks="$attacks,$new_attacks"
fi
# Remove duplicates
attacks=$(echo "$attacks" | tr ',' '\n' | sort -u | tr '\n' ',' | sed 's/,$//')
# Update attack type counter
IFS=',' read -ra ATTACK_ARRAY <<< "$new_attacks"
for attack in "${ATTACK_ARRAY[@]}"; do
((ATTACK_TYPE_COUNTER["$attack"]++))
done
# Calculate attack score
local attack_score=$(calculate_attack_score "$new_attacks")
score=$((score + attack_score))
((TOTAL_THREATS++))
fi
# Request volume scoring
if [ $hits -gt 100 ]; then
score=$((score + 5))
elif [ $hits -gt 50 ]; then
score=$((score + 3))
elif [ $hits -gt 20 ]; then
score=$((score + 1))
fi
# Adjust score based on bot type
case "$bot_type" in
legit|ai|monitor)
# Legitimate bots - reduce score
score=$((score - 5))
[ $score -lt 0 ] && score=0
;;
suspicious)
# Suspicious bots - increase score
score=$((score + 10))
;;
esac
# Cap at 100
[ $score -gt 100 ] && score=100
# Check if we're tracking too many IPs (memory protection)
if [ ${#IP_DATA[@]} -ge $MAX_TRACKED_IPS ]; then
# Remove lowest scoring IPs
local to_remove=()
for check_ip in "${!IP_DATA[@]}"; do
local check_score=$(echo "${IP_DATA[$check_ip]}" | cut -d'|' -f1)
[ "$check_score" -lt 10 ] && to_remove+=("$check_ip")
done
# Remove up to 100 low-score IPs
local removed=0
for remove_ip in "${to_remove[@]}"; do
unset IP_DATA[$remove_ip]
((removed++))
[ $removed -ge 100 ] && break
done
fi
# Update cached data
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
# Update IP reputation DB in background (if score > 0)
if [ $score -gt 0 ]; then
(update_ip_reputation "$ip" 1 "$score" 0 "Live monitor: $new_attacks" >/dev/null 2>&1) &
fi
}
# Get threat level from score
get_threat_level() {
local score="$1"
if [ "$score" -ge "$THREAT_THRESHOLD_CRITICAL" ]; then
echo "CRITICAL"
elif [ "$score" -ge "$THREAT_THRESHOLD_HIGH" ]; then
echo "HIGH"
elif [ "$score" -ge "$THREAT_THRESHOLD_MEDIUM" ]; then
echo "MEDIUM"
else
echo "LOW"
fi
}
# Get color for threat level
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" ;;
SAFE) echo "$SAFE_COLOR" ;;
*) echo "$INFO_COLOR" ;;
esac
}
# Get bot color
get_bot_color() {
local bot_type="$1"
case "$bot_type" in
legit) echo "$SAFE_COLOR" ;;
ai) echo '\033[0;34m' ;; # Blue
monitor) echo "$MEDIUM_COLOR" ;;
suspicious) echo "$HIGH_COLOR" ;;
*) echo "$INFO_COLOR" ;;
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)))
# Read event counter from file (updated by subshell)
local event_count=$(cat "$TEMP_DIR/event_counter" 2>/dev/null || echo "0")
echo -e "${CRITICAL_COLOR}╔════════════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CRITICAL_COLOR}║ 🚨 LIVE SECURITY MONITOR - INTELLIGENCE MODE 🧠 ║${NC}"
echo -e "${CRITICAL_COLOR}╚════════════════════════════════════════════════════════════════════════════╝${NC}"
echo -e "${INFO_COLOR}Runtime: ${uptime_str} | Events: ${event_count} | Threats: ${TOTAL_THREATS} | Monitoring...${NC}"
echo ""
}
draw_intelligence_panel() {
echo -e "${HIGH_COLOR}┌─ THREAT INTELLIGENCE ──────────────────────────────────────────────────────┐${NC}"
# Get top IPs by threat score
local count=0
for ip in "${!IP_DATA[@]}"; do
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "${IP_DATA[$ip]}"
echo "$score|$ip|$hits|$bot_type|$attacks|$ban_count|$rep_score"
done | sort -t'|' -k1 -rn | head -10 | while IFS='|' read -r score ip hits bot_type attacks ban_count rep_score; do
local level=$(get_threat_level "$score")
local color=$(get_threat_color "$level")
local bot_color=$(get_bot_color "$bot_type")
# Build status line
local status_line=$(printf "%-15s" "$ip")
status_line+=$(printf " Score:%-3s" "$score")
status_line+=$(printf " Hits:%-4s" "$hits")
# Bot type indicator
case "$bot_type" in
legit) status_line+=" ✅BOT" ;;
ai) status_line+=" 🤖AI" ;;
monitor) status_line+=" 📊MON" ;;
suspicious) status_line+=" ⚠️ SUS" ;;
*) status_line+="" ;;
esac
# Threat level
status_line+=$(printf " [%-8s]" "$level")
# Attacks
if [ -n "$attacks" ]; then
# Show first attack type
local first_attack=$(echo "$attacks" | cut -d',' -f1)
local icon=$(get_attack_icon "$first_attack")
status_line+=" $icon$(echo "$attacks" | cut -d',' -f1)"
fi
# Ban count
if [ "$ban_count" -gt 0 ]; then
status_line+=" 🚫x$ban_count"
fi
# Known threat indicator
if [ "$rep_score" -gt 0 ]; then
status_line+=" [KNOWN]"
fi
echo -e "${color}${status_line}${NC}"
done
echo -e "${HIGH_COLOR}└────────────────────────────────────────────────────────────────────────────┘${NC}"
echo ""
}
draw_attack_breakdown() {
echo -e "${MEDIUM_COLOR}┌─ ATTACK VECTORS ───────────────────────────────────────────────────────────┐${NC}"
if [ ${#ATTACK_TYPE_COUNTER[@]} -eq 0 ]; then
echo -e "${LOW_COLOR} No attacks detected yet...${NC}"
else
for attack_type in "${!ATTACK_TYPE_COUNTER[@]}"; do
local count="${ATTACK_TYPE_COUNTER[$attack_type]}"
local icon=$(get_attack_icon "$attack_type")
local color=$(get_attack_color "$attack_type")
printf "${color} ${icon} %-20s %5d${NC}\n" "$attack_type" "$count"
done | sort -t' ' -k3 -rn | head -5
fi
echo -e "${MEDIUM_COLOR}└────────────────────────────────────────────────────────────────────────────┘${NC}"
echo ""
}
draw_live_feed() {
echo -e "${HIGH_COLOR}┌─ LIVE THREAT FEED ─────────────────────────────────────────────────────────┐${NC}"
if [ -f "$TEMP_DIR/recent_events" ] && [ -s "$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_quick_actions() {
echo -e "${MEDIUM_COLOR}┌─ QUICK ACTIONS & RECOMMENDATIONS ─────────────────────────────────────────┐${NC}"
# Get blockable IPs (score >= 60, not already blocked)
local blockable_count=0
local blockable_ips=""
local has_ddos=0
local has_ssh_bruteforce=0
local high_conn_count=0
for ip in "${!IP_DATA[@]}"; do
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "${IP_DATA[$ip]}"
# Check attack patterns
[[ "$attacks" =~ DDOS ]] && has_ddos=1
[[ "$attacks" =~ BRUTEFORCE ]] && has_ssh_bruteforce=1
# Skip if score too low for blocking
[ "$score" -lt 60 ] && continue
# Quick check - only verify if CSF/iptables commands available
# Don't check on every refresh (too slow)
blockable_count=$((blockable_count + 1))
blockable_ips+="$ip "
done
# Check for high connection counts
if [ -f "$TEMP_DIR/recent_events" ]; then
high_conn_count=$(grep -c "HIGH_CONN_COUNT" "$TEMP_DIR/recent_events" 2>/dev/null)
else
high_conn_count=0
fi
# Ensure it's a valid number (strip whitespace and validate)
high_conn_count=$(echo "$high_conn_count" | tr -d '[:space:]')
[[ ! "$high_conn_count" =~ ^[0-9]+$ ]] && high_conn_count=0
# IP Blocking Recommendations
if [ "$blockable_count" -gt 0 ]; then
echo -e "${HIGH_COLOR} ⚠️ $blockable_count high-threat IPs ready to block${NC}"
echo -e "${MEDIUM_COLOR} → Press 'b' to open blocking menu${NC}"
else
echo -e "${SAFE_COLOR} ✓ No IPs requiring immediate blocks${NC}"
fi
# Intelligent Firewall Recommendations
local recommendations=0
if [ "$has_ddos" -eq 1 ] || [ "$high_conn_count" -gt 0 ]; then
echo -e "${HIGH_COLOR} ⚠️ DDoS/SYN Flood Detected - Firewall Protection Recommended${NC}"
echo -e "${MEDIUM_COLOR} → Enable SYNFLOOD protection: ${BOLD}csf -e SYNFLOOD${NC}"
echo -e "${MEDIUM_COLOR} → Optimize CT_LIMIT: ${BOLD}Press 'c' to run CT_LIMIT optimizer${NC}"
echo -e "${MEDIUM_COLOR} → Or manual: ${BOLD}modules/security/optimize-ct-limit.sh${NC}"
recommendations=1
fi
if [ "$has_ssh_bruteforce" -eq 1 ]; then
local ssh_attacks=0
if [ -f "$TEMP_DIR/recent_events" ]; then
ssh_attacks=$(grep -c "SSH_BRUTEFORCE" "$TEMP_DIR/recent_events" 2>/dev/null)
fi
ssh_attacks=$(echo "$ssh_attacks" | tr -d '[:space:]')
[[ ! "$ssh_attacks" =~ ^[0-9]+$ ]] && ssh_attacks=0
if [ "$ssh_attacks" -gt 5 ]; then
echo -e "${HIGH_COLOR} ⚠️ SSH Bruteforce ($ssh_attacks attempts) - Strengthen SSH Security${NC}"
echo -e "${MEDIUM_COLOR} → Lower LF_SSHD trigger: ${BOLD}Edit /etc/csf/csf.conf → LF_SSHD=\"3\"${NC}"
echo -e "${MEDIUM_COLOR} → Enable PortKnocking or change SSH port${NC}"
recommendations=1
fi
fi
if [ $recommendations -eq 0 ]; then
echo ""
fi
echo -e "${INFO_COLOR} Keys: 'b' Block | 'c' CT_LIMIT | 's' Stats | 'r' Refresh | 'h' Help | 'q' Quit${NC}"
echo -e "${MEDIUM_COLOR}└────────────────────────────────────────────────────────────────────────────┘${NC}"
}
################################################################################
# Quick Action Menu
################################################################################
show_blocking_menu() {
# Pause monitoring
local monitoring_paused=1
clear
print_banner "Quick IP Blocking"
echo ""
echo "Select IPs to block (1-hour temporary ban):"
echo ""
# Build array of blockable IPs
local -a blockable_list=()
for ip in "${!IP_DATA[@]}"; do
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "${IP_DATA[$ip]}"
# Skip if score too low or already blocked
[ "$score" -lt 60 ] && continue
is_ip_blocked "$ip" 2>/dev/null && continue
blockable_list+=("$ip|$score|$hits|$attacks")
done
if [ ${#blockable_list[@]} -eq 0 ]; then
echo "No IPs meet blocking criteria (score >= 60)"
echo ""
read -p "Press Enter to continue..."
return
fi
# Check if any IPs to block
if [ ${#blockable_list[@]} -eq 0 ]; then
echo ""
echo -e "${SAFE_COLOR}No IPs meet blocking criteria (score >= 60 and not already blocked)${NC}"
echo ""
read -p "Press Enter to continue..."
return
fi
# Sort by score
IFS=$'\n' blockable_list=($(sort -t'|' -k2 -rn <<<"${blockable_list[*]}"))
unset IFS
# Display IPs
local idx=1
for entry in "${blockable_list[@]}"; do
IFS='|' read -r ip score hits attacks <<< "$entry"
local level=$(get_threat_level "$score")
local color=$(get_threat_color "$level")
printf "${color} %2d) %-15s Score:%-3s Hits:%-5s Attacks: %s${NC}\n" \
"$idx" "$ip" "$score" "$hits" "${attacks:-none}"
((idx++))
done
echo ""
echo -e "${BOLD}Options:${NC}"
echo " 1-${#blockable_list[@]}) Block specific IP"
echo " a) Block ALL high-threat IPs (score >= 80)"
echo " 0) Cancel"
echo ""
read -p "Select option: " choice
if [ "$choice" = "0" ]; then
return
elif [ "$choice" = "a" ]; then
# Block all IPs with score >= 80
local blocked=0
for entry in "${blockable_list[@]}"; do
IFS='|' read -r ip score hits attacks <<< "$entry"
[ "$score" -lt 80 ] && continue
echo ""
block_ip_temporary "$ip" 1 "Auto-block: High threat (score $score)"
((blocked++))
done
echo ""
echo "Blocked $blocked IPs"
read -p "Press Enter to continue..."
elif [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#blockable_list[@]} ]; then
# Block specific IP
local entry="${blockable_list[$((choice-1))]}"
IFS='|' read -r ip score hits attacks <<< "$entry"
echo ""
block_ip_temporary "$ip" 1 "Manual block from live monitor (score $score)"
echo ""
read -p "Press Enter to continue..."
else
echo "Invalid option"
read -p "Press Enter to continue..."
fi
}
################################################################################
# Log Monitoring
################################################################################
monitor_apache_logs() {
# Try multiple log locations
local log_files=()
# Set default if not defined by system-detect.sh
local LOG_DIR="${SYS_LOG_DIR:-/var/log/apache2/domlogs}"
# Main access log
if [ -f "${LOG_DIR}/access_log" ]; then
log_files+=("${LOG_DIR}/access_log")
elif [ -f "/var/log/httpd/access_log" ]; then
log_files+=("/var/log/httpd/access_log")
elif [ -f "/var/log/apache2/access.log" ]; then
log_files+=("/var/log/apache2/access.log")
fi
# Domain logs (cPanel domlogs)
if [ -d "${LOG_DIR}" ]; then
# Find recent domain logs (modified in last hour)
while IFS= read -r domain_log; do
[ -f "$domain_log" ] && log_files+=("$domain_log")
done < <(find "${LOG_DIR}" -type f \( -name "*.com" -o -name "*.net" -o -name "*.org" \) 2>/dev/null | head -5)
fi
if [ ${#log_files[@]} -eq 0 ]; then
echo "ERROR: No accessible Apache log files found" >> "$TEMP_DIR/recent_events"
echo "Checked: ${LOG_DIR}, /var/log/httpd, /var/log/apache2" >> "$TEMP_DIR/recent_events"
return 1
fi
# Monitor all log files
local event_count=0
tail -f "${log_files[@]}" 2>/dev/null | while read -r line; do
# Increment event counter (update file every 10 events for performance)
((event_count++))
if [ $((event_count % 10)) -eq 0 ]; then
echo "$event_count" > "$TEMP_DIR/event_counter"
fi
# Parse Apache combined log format (supports IPv4 and IPv6)
# Note: bytes field can be - or number, so use [0-9-]+
if [[ "$line" =~ ^([0-9a-f.:]+)\ -\ -\ \[([^\]]+)\]\ \"([A-Z]+)\ ([^\"]+)\ [^\"]+\"\ ([0-9]+)\ ([0-9-]+)\ \"[^\"]*\"\ \"([^\"]+)\" ]]; then
local ip="${BASH_REMATCH[1]}"
local timestamp="${BASH_REMATCH[2]}"
local method="${BASH_REMATCH[3]}"
local url="${BASH_REMATCH[4]}"
local status="${BASH_REMATCH[5]}"
local bytes="${BASH_REMATCH[6]}"
local user_agent="${BASH_REMATCH[7]}"
# Skip local/private IPs and server's own IP
if [[ "$ip" =~ ^127\. ]] || \
[[ "$ip" =~ ^10\. ]] || \
[[ "$ip" =~ ^192\.168\. ]] || \
[[ "$ip" =~ ^172\.(1[6-9]|2[0-9]|3[01])\. ]] || \
[[ "$ip" =~ ^169\.254\. ]] || \
[[ "$ip" == "localhost" ]] || \
[[ "$ip" == "::1" ]]; then
continue
fi
# Update intelligence
update_ip_intelligence "$ip" "$url" "$user_agent" "$method"
# Get updated data
local intel=$(get_ip_intelligence "$ip")
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$intel"
# Determine if this is a threat
local level=$(get_threat_level "$score")
# Log all traffic with attacks, or score > 0, or suspicious bots
# This ensures we see everything interesting, not just high scores
if [ "$score" -gt 0 ] || [ -n "$attacks" ] || [ "$bot_type" = "suspicious" ]; then
local color=$(get_threat_color "$level")
local time_str=$(date +"%H:%M:%S")
# Build log line
local log_line="${color}[${time_str}] $ip"
log_line+=" | Score:$score [$level]"
# Show bot type if interesting
if [ "$bot_type" = "suspicious" ] || [ "$bot_type" = "ai" ]; then
log_line+=" | Bot:$bot_type"
fi
if [ -n "$attacks" ]; then
local first_attack=$(echo "$attacks" | cut -d',' -f1)
local icon=$(get_attack_icon "$first_attack")
log_line+=" | $icon$first_attack"
fi
log_line+=" | $url${NC}"
echo -e "$log_line" >> "$TEMP_DIR/recent_events"
fi
fi
done &
}
################################################################################
# Main Loop
################################################################################
################################################################################
# SSH Attack Monitoring
################################################################################
monitor_ssh_attacks() {
# Monitor SSH brute force attempts from /var/log/secure
local secure_log="/var/log/secure"
if [ ! -f "$secure_log" ]; then
# Try alternative location (Debian/Ubuntu)
secure_log="/var/log/auth.log"
fi
if [ -f "$secure_log" ]; then
tail -n 0 -F "$secure_log" 2>/dev/null | while read -r line; do
# Detect failed SSH login attempts
if echo "$line" | grep -qi "Failed password\|authentication failure\|Invalid user"; then
# Extract IP address
local ip=$(echo "$line" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
if [ -n "$ip" ]; then
# Skip local/private IPs
if [[ "$ip" =~ ^127\. ]] || \
[[ "$ip" =~ ^10\. ]] || \
[[ "$ip" =~ ^192\.168\. ]] || \
[[ "$ip" =~ ^172\.(1[6-9]|2[0-9]|3[01])\. ]]; then
continue
fi
# Process as BRUTEFORCE attack
local current_data="${IP_DATA[$ip]:-0|0|human||0|0}"
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current_data"
# Increment hits
hits=$((hits + 1))
# Add BRUTEFORCE to attacks if not already present
if [[ ! "$attacks" =~ BRUTEFORCE ]]; then
if [ -z "$attacks" ]; then
attacks="BRUTEFORCE"
else
attacks="${attacks},BRUTEFORCE"
fi
fi
# Calculate new score
score=$(calculate_attack_score "$attacks")
# Update IP_DATA
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
# Log to reputation DB
flag_ip_attack "$ip" "BRUTEFORCE" 0 "SSH failed login attempt" >/dev/null 2>&1 &
# Log event
local time_str=$(date +"%H:%M:%S")
local level=$(get_threat_level "$score")
local color=$(get_threat_color "$level")
local icon=$(get_attack_icon "BRUTEFORCE")
echo -e "${color}[${time_str}] $ip | Score:$score [$level] | ${icon}SSH_BRUTEFORCE | Hits:$hits${NC}" >> "$TEMP_DIR/recent_events"
fi
fi
done &
fi
}
################################################################################
# Firewall Block Monitoring
################################################################################
monitor_firewall_blocks() {
# Monitor CSF/iptables blocks in real-time from /var/log/messages
local messages_log="/var/log/messages"
if [ ! -f "$messages_log" ]; then
# Try alternative location
messages_log="/var/log/syslog"
fi
if [ -f "$messages_log" ]; then
tail -n 0 -F "$messages_log" 2>/dev/null | while read -r line; do
# Detect firewall blocks (CSF, iptables, kernel blocks)
if echo "$line" | grep -qiE "Firewall|iptables.*DENY|iptables.*DROP|CSF.*block"; then
# Extract IP address
local ip=$(echo "$line" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
if [ -n "$ip" ]; then
# Skip local/private IPs
if [[ "$ip" =~ ^127\. ]] || \
[[ "$ip" =~ ^10\. ]] || \
[[ "$ip" =~ ^192\.168\. ]] || \
[[ "$ip" =~ ^172\.(1[6-9]|2[0-9]|3[01])\. ]]; then
continue
fi
# Log firewall block
local time_str=$(date +"%H:%M:%S")
echo -e "${LOW_COLOR}[${time_str}] $ip | FIREWALL_BLOCK | Blocked by firewall${NC}" >> "$TEMP_DIR/recent_events"
fi
fi
done &
fi
}
################################################################################
# cPHulk Monitoring
################################################################################
monitor_cphulk_blocks() {
# Monitor cPHulk blocks (cPanel security system)
if [ -x "/usr/local/cpanel/bin/cphulk_pam_ctl" ] || command -v whmapi1 &>/dev/null; then
(
declare -A SEEN_BLOCKS
while true; do
# Query cPHulk for blocked IPs
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 "${SEEN_BLOCKS[$ip]}" ]; then
SEEN_BLOCKS[$ip]=1
# Skip local/private IPs
if [[ "$ip" =~ ^127\. ]] || \
[[ "$ip" =~ ^10\. ]] || \
[[ "$ip" =~ ^192\.168\. ]] || \
[[ "$ip" =~ ^172\.(1[6-9]|2[0-9]|3[01])\. ]]; then
continue
fi
# Process as BRUTEFORCE attack (cPHulk blocks login attempts)
local current_data="${IP_DATA[$ip]:-0|0|human||0|0}"
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current_data"
# Add BRUTEFORCE to attacks
if [[ ! "$attacks" =~ BRUTEFORCE ]]; then
if [ -z "$attacks" ]; then
attacks="BRUTEFORCE"
else
attacks="${attacks},BRUTEFORCE"
fi
fi
# Calculate score
score=$(calculate_attack_score "$attacks")
hits=$((hits + 1))
# Update IP_DATA
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
# Log event
local time_str=$(date +"%H:%M:%S")
local level=$(get_threat_level "$score")
local color=$(get_threat_color "$level")
echo -e "${color}[${time_str}] $ip | Score:$score [$level] | 🔐CPHULK_BLOCK | Blocked by cPHulk${NC}" >> "$TEMP_DIR/recent_events"
fi
done
sleep 10 # Poll every 10 seconds
done
) &
fi
}
################################################################################
# Network Attack Monitoring (SYN floods, port scans, DDoS)
################################################################################
monitor_network_attacks() {
# Monitor kernel logs and network statistics for SYN floods, port scans, etc.
local kern_log="/var/log/kern.log"
# Try different log locations
if [ ! -f "$kern_log" ]; then
kern_log="/var/log/messages"
fi
# Monitor kernel/firewall logs for network attacks
if [ -f "$kern_log" ]; then
tail -n 0 -F "$kern_log" 2>/dev/null | while read -r line; do
# Detect SYN flood patterns
if echo "$line" | grep -qiE "SYN flood|possible SYN flooding|TCP: Possible SYN flooding"; then
local ip=$(echo "$line" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
if [ -n "$ip" ]; then
# Skip local/private IPs
if [[ "$ip" =~ ^127\. ]] || \
[[ "$ip" =~ ^10\. ]] || \
[[ "$ip" =~ ^192\.168\. ]] || \
[[ "$ip" =~ ^172\.(1[6-9]|2[0-9]|3[01])\. ]]; then
continue
fi
# Process as DDOS attack
local current_data="${IP_DATA[$ip]:-0|0|human||0|0}"
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current_data"
# Add DDOS to attacks
if [[ ! "$attacks" =~ DDOS ]]; then
if [ -z "$attacks" ]; then
attacks="DDOS"
else
attacks="${attacks},DDOS"
fi
fi
# Calculate score (DDOS is high severity)
score=$(calculate_attack_score "$attacks")
hits=$((hits + 1))
# Update IP_DATA
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
# Log to reputation DB
flag_ip_attack "$ip" "DDOS" 0 "SYN flood detected" >/dev/null 2>&1 &
# Log event
local time_str=$(date +"%H:%M:%S")
local level=$(get_threat_level "$score")
local color=$(get_threat_color "$level")
echo -e "${color}[${time_str}] $ip | Score:$score [$level] | 💥SYN_FLOOD | Network attack${NC}" >> "$TEMP_DIR/recent_events"
fi
fi
# Detect port scan attempts
if echo "$line" | grep -qiE "port.*scan|stealth scan|SYN-FIN scan|NULL scan"; then
local ip=$(echo "$line" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
if [ -n "$ip" ]; then
# Skip local/private IPs
if [[ "$ip" =~ ^127\. ]] || \
[[ "$ip" =~ ^10\. ]] || \
[[ "$ip" =~ ^192\.168\. ]] || \
[[ "$ip" =~ ^172\.(1[6-9]|2[0-9]|3[01])\. ]]; then
continue
fi
# Process as SCANNER attack
local current_data="${IP_DATA[$ip]:-0|0|human||0|0}"
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current_data"
# Add PORT_SCAN to attacks (using ADMIN_PROBE for now - 5 points)
if [[ ! "$attacks" =~ ADMIN_PROBE ]]; then
if [ -z "$attacks" ]; then
attacks="ADMIN_PROBE"
else
attacks="${attacks},ADMIN_PROBE"
fi
fi
# Calculate score
score=$(calculate_attack_score "$attacks")
hits=$((hits + 1))
# Update IP_DATA
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
# Log event
local time_str=$(date +"%H:%M:%S")
local level=$(get_threat_level "$score")
local color=$(get_threat_color "$level")
echo -e "${color}[${time_str}] $ip | Score:$score [$level] | 🔎PORT_SCAN | Network reconnaissance${NC}" >> "$TEMP_DIR/recent_events"
fi
fi
done &
fi
# Monitor netstat for high connection counts (possible DDoS)
if command -v netstat &>/dev/null || command -v ss &>/dev/null; then
(
declare -A CONNECTION_COUNT
declare -A ALERT_SENT
while true; do
# Use ss if available (faster), otherwise netstat
if command -v ss &>/dev/null; then
# Count SYN_RECV connections per IP (sign of SYN flood)
while read -r ip count; do
if [ "$count" -gt 20 ]; then # More than 20 SYN_RECV connections
if [ -z "${ALERT_SENT[$ip]}" ]; then
ALERT_SENT[$ip]=1
# Skip local/private IPs
if [[ "$ip" =~ ^127\. ]] || \
[[ "$ip" =~ ^10\. ]] || \
[[ "$ip" =~ ^192\.168\. ]] || \
[[ "$ip" =~ ^172\.(1[6-9]|2[0-9]|3[01])\. ]]; then
continue
fi
# Log high connection count
local time_str=$(date +"%H:%M:%S")
echo -e "${HIGH_COLOR}[${time_str}] $ip | 💥HIGH_CONN_COUNT | $count SYN_RECV connections (possible DDoS)${NC}" >> "$TEMP_DIR/recent_events"
fi
else
# Reset alert if connections drop
unset ALERT_SENT[$ip]
fi
done < <(ss -tn state syn-recv 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | sort | uniq -c | awk '$1 > 5 {print $2, $1}')
fi
sleep 15 # Check every 15 seconds
done
) &
fi
}
################################################################################
# Email/SMTP Attack Monitoring
################################################################################
monitor_email_attacks() {
# Monitor mail logs for SMTP/IMAP/POP3 bruteforce
local mail_log="/var/log/maillog"
if [ ! -f "$mail_log" ]; then
mail_log="/var/log/mail.log"
fi
if [ -f "$mail_log" ]; then
tail -n 0 -F "$mail_log" 2>/dev/null | while read -r line; do
# Dovecot authentication failures
if echo "$line" | grep -qiE "auth.*failed|authentication failed|password mismatch"; then
local ip=$(echo "$line" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
if [ -n "$ip" ]; then
# Skip local/private IPs
[[ "$ip" =~ ^127\. ]] || [[ "$ip" =~ ^10\. ]] || [[ "$ip" =~ ^192\.168\. ]] || [[ "$ip" =~ ^172\.(1[6-9]|2[0-9]|3[01])\. ]] && continue
# Process as BRUTEFORCE attack
local current_data="${IP_DATA[$ip]:-0|0|human||0|0}"
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current_data"
hits=$((hits + 1))
# Add BRUTEFORCE to attacks
if [[ ! "$attacks" =~ BRUTEFORCE ]]; then
[ -z "$attacks" ] && attacks="BRUTEFORCE" || attacks="${attacks},BRUTEFORCE"
fi
score=$(calculate_attack_score "$attacks")
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
# Log to reputation DB
flag_ip_attack "$ip" "BRUTEFORCE" 0 "Email authentication failure" >/dev/null 2>&1 &
# Log event
local time_str=$(date +"%H:%M:%S")
local level=$(get_threat_level "$score")
local color=$(get_threat_color "$level")
echo -e "${color}[${time_str}] $ip | Score:$score [$level] | 📧EMAIL_BRUTEFORCE | Hits:$hits${NC}" >> "$TEMP_DIR/recent_events"
fi
fi
done &
fi
}
################################################################################
# FTP Attack Monitoring
################################################################################
monitor_ftp_attacks() {
# Monitor FTP logs for bruteforce attempts
local ftp_log="/var/log/vsftpd.log"
if [ ! -f "$ftp_log" ]; then
ftp_log="/var/log/xferlog"
fi
if [ -f "$ftp_log" ]; then
tail -n 0 -F "$ftp_log" 2>/dev/null | while read -r line; do
# FTP authentication failures
if echo "$line" | grep -qiE "FAIL LOGIN|authentication failed|530 Login incorrect"; then
local ip=$(echo "$line" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
if [ -n "$ip" ]; then
# Skip local/private IPs
[[ "$ip" =~ ^127\. ]] || [[ "$ip" =~ ^10\. ]] || [[ "$ip" =~ ^192\.168\. ]] || [[ "$ip" =~ ^172\.(1[6-9]|2[0-9]|3[01])\. ]] && continue
# Process as BRUTEFORCE attack
local current_data="${IP_DATA[$ip]:-0|0|human||0|0}"
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current_data"
hits=$((hits + 1))
# Add BRUTEFORCE to attacks
if [[ ! "$attacks" =~ BRUTEFORCE ]]; then
[ -z "$attacks" ] && attacks="BRUTEFORCE" || attacks="${attacks},BRUTEFORCE"
fi
score=$(calculate_attack_score "$attacks")
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
# Log to reputation DB
flag_ip_attack "$ip" "BRUTEFORCE" 0 "FTP login failure" >/dev/null 2>&1 &
# Log event
local time_str=$(date +"%H:%M:%S")
local level=$(get_threat_level "$score")
local color=$(get_threat_color "$level")
echo -e "${color}[${time_str}] $ip | Score:$score [$level] | 📁FTP_BRUTEFORCE | Hits:$hits${NC}" >> "$TEMP_DIR/recent_events"
fi
fi
done &
fi
}
################################################################################
# Database Attack Monitoring
################################################################################
monitor_database_attacks() {
# Monitor MySQL logs for authentication failures
local mysql_log="/var/log/mysqld.log"
if [ ! -f "$mysql_log" ]; then
mysql_log="/var/log/mysql/error.log"
fi
if [ -f "$mysql_log" ]; then
tail -n 0 -F "$mysql_log" 2>/dev/null | while read -r line; do
# MySQL authentication failures
if echo "$line" | grep -qiE "Access denied for user|Failed password for"; then
local ip=$(echo "$line" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
if [ -n "$ip" ]; then
# Skip local/private IPs
[[ "$ip" =~ ^127\. ]] || [[ "$ip" =~ ^10\. ]] || [[ "$ip" =~ ^192\.168\. ]] || [[ "$ip" =~ ^172\.(1[6-9]|2[0-9]|3[01])\. ]] && continue
# Process as SQL_INJECTION attack (database level)
local current_data="${IP_DATA[$ip]:-0|0|human||0|0}"
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current_data"
hits=$((hits + 1))
# Add SQL_INJECTION to attacks
if [[ ! "$attacks" =~ SQL_INJECTION ]]; then
[ -z "$attacks" ] && attacks="SQL_INJECTION" || attacks="${attacks},SQL_INJECTION"
fi
score=$(calculate_attack_score "$attacks")
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
# Log to reputation DB
flag_ip_attack "$ip" "SQL_INJECTION" 0 "MySQL authentication failure" >/dev/null 2>&1 &
# Log event
local time_str=$(date +"%H:%M:%S")
local level=$(get_threat_level "$score")
local color=$(get_threat_color "$level")
echo -e "${color}[${time_str}] $ip | Score:$score [$level] | 🗄️ DB_BRUTEFORCE | Hits:$hits${NC}" >> "$TEMP_DIR/recent_events"
fi
fi
done &
fi
}
################################################################################
# Distributed Attack Detection
################################################################################
detect_distributed_attacks() {
# Run in background, check every 30 seconds
(
while true; do
sleep 30
# Look for same attack pattern from multiple IPs in short time
if [ -f "$TEMP_DIR/recent_events" ]; then
# Get recent attacks (last 2 minutes)
local recent=$(tail -200 "$TEMP_DIR/recent_events" 2>/dev/null)
# Check for same attack type from 5+ different IPs
for attack_type in RCE SQL_INJECTION XSS PATH_TRAVERSAL BRUTEFORCE; do
local attack_count=$(echo "$recent" | grep -c "$attack_type")
if [ "$attack_count" -ge 5 ]; then
local unique_ips=$(echo "$recent" | grep "$attack_type" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | sort -u | wc -l)
if [ "$unique_ips" -ge 5 ]; then
# Distributed attack detected!
local time_str=$(date +"%H:%M:%S")
echo -e "${CRITICAL_COLOR}[${time_str}] DISTRIBUTED_ATTACK | ${attack_type} from ${unique_ips} IPs in last 2min | Possible botnet${NC}" >> "$TEMP_DIR/recent_events"
# Mark in a file for Quick Actions to see
echo "${attack_type}|${unique_ips}|$(date +%s)" >> "$TEMP_DIR/distributed_attacks"
fi
fi
done
fi
done
) &
}
################################################################################
# Automatic Mitigation Engine
################################################################################
auto_mitigation_engine() {
# Run in background, check every 10 seconds
(
while true; do
sleep 10
# Auto-block IPs that reach CRITICAL threshold
for ip in "${!IP_DATA[@]}"; do
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "${IP_DATA[$ip]}"
# Auto-block at score >= 80 (CRITICAL)
if [ "$score" -ge 80 ]; then
# Check if already blocked
if ! is_ip_blocked "$ip" 2>/dev/null; then
# Auto-block
local time_str=$(date +"%H:%M:%S")
echo -e "${CRITICAL_COLOR}[${time_str}] AUTO_BLOCK | $ip | Score:$score | ${attacks}${NC}" >> "$TEMP_DIR/recent_events"
# Block for 1 hour
block_ip_temporary "$ip" 1 "Auto-block: Critical threat score $score - ${attacks}" >/dev/null 2>&1 &
# Update ban count
ban_count=$((ban_count + 1))
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
fi
fi
done
done
) &
}
# Start all log monitoring sources
monitor_apache_logs
monitor_ssh_attacks
monitor_email_attacks
monitor_ftp_attacks
monitor_database_attacks
monitor_firewall_blocks
monitor_cphulk_blocks
monitor_network_attacks
# Start intelligence engines
detect_distributed_attacks
auto_mitigation_engine
# Periodic snapshot saving in background
(
while true; do
sleep 300 # Save every 5 minutes
save_snapshot
done
) &
# Main dashboard loop
LOOP_COUNT=0
while true; do
draw_header
draw_intelligence_panel
draw_attack_breakdown
draw_live_feed
draw_quick_actions
# Periodic cleanup (every 50 loops = ~100 seconds)
((LOOP_COUNT++))
if [ $((LOOP_COUNT % 50)) -eq 0 ]; then
# Trim event log to last 1000 lines
if [ -f "$TEMP_DIR/recent_events" ]; then
tail -1000 "$TEMP_DIR/recent_events" > "$TEMP_DIR/recent_events.tmp" 2>/dev/null
mv "$TEMP_DIR/recent_events.tmp" "$TEMP_DIR/recent_events" 2>/dev/null
fi
fi
# Non-blocking input with timeout
read -t $REFRESH_INTERVAL -n 1 key
case "$key" in
b|B)
show_blocking_menu
;;
c|C)
# Run CT_LIMIT optimizer
clear
"$SCRIPT_DIR/modules/security/optimize-ct-limit.sh"
read -p "Press Enter to return to monitor..."
;;
i|I)
# Show threat intelligence for specific IP
clear
print_banner "Threat Intelligence Lookup"
echo ""
read -p "Enter IP address: " lookup_ip
if [ -n "$lookup_ip" ]; then
echo ""
echo "Querying threat intelligence for $lookup_ip..."
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
local threat_intel=$(get_threat_intelligence "$lookup_ip")
IFS='|' read -r abuse_conf abuse_rpts country isp geo timing whitelisted <<< "$threat_intel"
echo ""
echo "${BOLD}Threat Intelligence:${NC}"
echo " AbuseIPDB Confidence: ${abuse_conf}%"
echo " Total Abuse Reports: $abuse_rpts"
echo " Country: ${geo:-$country}"
echo " ISP: $isp"
echo " Timing Pattern: $timing"
echo " Whitelisted: $whitelisted"
echo ""
if is_high_risk_country "${geo:-XX}"; then
echo -e "${HIGH_COLOR} ⚠️ HIGH RISK COUNTRY${NC}"
fi
if [ "${abuse_conf:-0}" -ge 75 ]; then
echo -e "${CRITICAL_COLOR} 🚨 HIGH CONFIDENCE MALICIOUS${NC}"
elif [ "${abuse_conf:-0}" -ge 50 ]; then
echo -e "${HIGH_COLOR} ⚠️ MEDIUM CONFIDENCE THREAT${NC}"
fi
echo ""
read -p "Generate full incident report? (y/n): " gen_report
if [[ "$gen_report" =~ ^[Yy]$ ]]; then
local report_file=$(generate_incident_report "$lookup_ip")
echo ""
echo "Report generated: $report_file"
echo ""
echo "View report? (y/n): "
read -n 1 view_report
if [[ "$view_report" =~ ^[Yy]$ ]]; then
less "$report_file"
fi
fi
fi
echo ""
read -p "Press Enter to return to monitor..."
;;
p|P)
# Show performance impact
clear
print_banner "Server Performance Monitor"
echo ""
local load_data=$(get_server_load)
IFS='|' read -r load1 load5 load15 cpu_count <<< "$load_data"
echo "${BOLD}Current Load:${NC}"
echo " 1 min: $load1"
echo " 5 min: $load5"
echo " 15 min: $load15"
echo " CPU cores: $cpu_count"
echo ""
if is_server_stressed; then
echo -e "${CRITICAL_COLOR} 🔥 SERVER UNDER STRESS${NC}"
echo ""
echo " Recommended Actions:"
echo " • Enable aggressive auto-blocking (higher threshold)"
echo " • Reduce CT_LIMIT temporarily"
echo " • Block high-volume attack IPs immediately"
else
echo -e "${SAFE_COLOR} ✓ Server load normal${NC}"
fi
echo ""
read -p "Press Enter to return to monitor..."
;;
q|Q)
cleanup
;;
r|R)
# Force refresh
continue
;;
s|S)
# Show stats
clear
show_ip_reputation_stats
read -p "Press Enter to continue..."
;;
h|H|\?)
# Show help
clear
print_banner "Keyboard Controls"
echo ""
echo "Available Commands:"
echo " ${BOLD}b${NC} - Open IP blocking menu (batch or individual)"
echo " ${BOLD}c${NC} - Run CT_LIMIT optimizer (analyze traffic & recommend limit)"
echo " ${BOLD}i${NC} - Threat intelligence lookup (AbuseIPDB, geo, incident reports)"
echo " ${BOLD}p${NC} - Show performance impact monitor (server load)"
echo " ${BOLD}s${NC} - Show IP reputation database statistics"
echo " ${BOLD}r${NC} - Force refresh display"
echo " ${BOLD}h${NC} - Show this help screen"
echo " ${BOLD}q${NC} - Quit and save snapshot"
echo ""
echo "Features:"
echo " • Real-time bot classification (legit/AI/monitor/suspicious)"
echo " • Attack vector detection (SQL, XSS, RCE, etc.)"
echo " • Threat scoring (0-100 scale)"
echo " • Threat intelligence integration (AbuseIPDB, geolocation)"
echo " • Attack pattern learning & behavioral analysis"
echo " • Automated incident report generation"
echo " • Smart whitelisting (CDNs, search engines)"
echo " • IP reputation DB integration"
echo " • CSF/iptables temporary bans (1 hour default)"
echo " • Auto-mitigation at critical threshold (score ≥80)"
echo " • Memory protection (max ${MAX_TRACKED_IPS} IPs tracked)"
echo " • Auto-save every 5 minutes + on exit"
echo ""
read -p "Press Enter to continue..."
;;
esac
done