Initial commit: Server Management Toolkit v2.0
- 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
This commit is contained in:
Executable
+3240
File diff suppressed because it is too large
Load Diff
Executable
+368
@@ -0,0 +1,368 @@
|
||||
#!/bin/bash
|
||||
|
||||
################################################################################
|
||||
# cPHulk Enablement Script with CSF Whitelist Import
|
||||
################################################################################
|
||||
# Purpose: Enable cPHulk brute force protection and import CSF allowed IPs
|
||||
# Requirements: cPanel server with CSF installed
|
||||
# Author: Server Toolkit
|
||||
#
|
||||
# IMPORTANT NOTES:
|
||||
# - cPHulk operates SYSTEM-WIDE (not per-user or per-domain)
|
||||
# - Protects all authentication services: cPanel, WHM, SSH, FTP, Email
|
||||
# - This script intelligently discovers ALL CSF whitelist files including:
|
||||
# * Standard files (/etc/csf/csf.allow, cpanel.allow, etc.)
|
||||
# * Include directives (follows recursively)
|
||||
# * Hosting panel integrations (LiquidWeb, cPanel, InterWorx, etc.)
|
||||
# * Custom locations configured in csf.conf
|
||||
# - Supports multiple IP formats: simple IPs, s=IP, d=IP, CIDR notation
|
||||
################################################################################
|
||||
|
||||
# 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
|
||||
|
||||
print_banner "cPHulk Enablement with CSF Whitelist Import"
|
||||
|
||||
# Check if cPanel
|
||||
if [ "$SYS_CONTROL_PANEL" != "cpanel" ]; then
|
||||
print_error "This script is for cPanel servers only"
|
||||
print_info "Detected control panel: ${SYS_CONTROL_PANEL:-none}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if cPHulk exists
|
||||
if [ ! -x "/usr/local/cpanel/bin/cphulk_pam_ctl" ]; then
|
||||
print_error "cPHulk not found. This may not be a standard cPanel installation."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if CSF is installed
|
||||
if [ ! -x "/usr/sbin/csf" ]; then
|
||||
print_warning "CSF not found - will skip CSF whitelist import"
|
||||
CSF_AVAILABLE=false
|
||||
else
|
||||
CSF_AVAILABLE=true
|
||||
fi
|
||||
|
||||
print_section "Current cPHulk Status"
|
||||
|
||||
# Get current status
|
||||
CPHULK_STATUS=$(/usr/local/cpanel/bin/cphulk_pam_ctl --status 2>/dev/null)
|
||||
if echo "$CPHULK_STATUS" | grep -qi "enabled"; then
|
||||
print_success "cPHulk is currently ENABLED"
|
||||
ALREADY_ENABLED=true
|
||||
else
|
||||
print_info "cPHulk is currently DISABLED"
|
||||
ALREADY_ENABLED=false
|
||||
fi
|
||||
|
||||
# Show current whitelist count
|
||||
CURRENT_WHITELIST=$(/usr/local/cpanel/scripts/cphulkdwhitelist --list 2>/dev/null | grep -v "^$" | wc -l)
|
||||
print_info "Current cPHulk whitelist entries: $CURRENT_WHITELIST"
|
||||
|
||||
if [ "$CSF_AVAILABLE" = true ]; then
|
||||
print_section "CSF Whitelist Analysis"
|
||||
|
||||
# Get CSF allowed IPs
|
||||
echo "Scanning CSF allow files and following Include directives..."
|
||||
echo ""
|
||||
|
||||
# Start with main CSF allow file and follow all includes recursively
|
||||
declare -A PROCESSED_FILES # Track processed files to avoid duplicates
|
||||
CSF_FILES=()
|
||||
|
||||
# Function to recursively find included files
|
||||
find_csf_files() {
|
||||
local current_file="$1"
|
||||
|
||||
# Skip if already processed or doesn't exist
|
||||
[ -n "${PROCESSED_FILES[$current_file]}" ] && return
|
||||
[ ! -f "$current_file" ] && return
|
||||
|
||||
# Mark as processed
|
||||
PROCESSED_FILES["$current_file"]=1
|
||||
CSF_FILES+=("$current_file")
|
||||
|
||||
# Look for Include directives
|
||||
while IFS= read -r line; do
|
||||
if [[ "$line" =~ ^Include[[:space:]]+(.+)$ ]]; then
|
||||
local included_file="${BASH_REMATCH[1]}"
|
||||
# Trim whitespace
|
||||
included_file=$(echo "$included_file" | xargs)
|
||||
# Recursively process included file
|
||||
find_csf_files "$included_file"
|
||||
fi
|
||||
done < "$current_file"
|
||||
}
|
||||
|
||||
# Method 1: Start with main csf.allow and follow all includes
|
||||
if [ -f "/etc/csf/csf.allow" ]; then
|
||||
find_csf_files "/etc/csf/csf.allow"
|
||||
fi
|
||||
|
||||
# Method 2: Scan for all .allow files in /etc/csf/ (catches files not included)
|
||||
while IFS= read -r file; do
|
||||
find_csf_files "$file"
|
||||
done < <(find /etc/csf/ -maxdepth 1 -type f -name "*.allow" 2>/dev/null)
|
||||
|
||||
# Method 3: Check csf.conf for ALLOWIPS_INCLUDE directive
|
||||
# This directive can point to custom include directories
|
||||
if [ -f "/etc/csf/csf.conf" ]; then
|
||||
ALLOWIPS_INCLUDE=$(grep "^ALLOWIPS_INCLUDE" /etc/csf/csf.conf | cut -d'=' -f2 | tr -d '"' | tr -d ' ')
|
||||
if [ -n "$ALLOWIPS_INCLUDE" ] && [ -d "$ALLOWIPS_INCLUDE" ]; then
|
||||
echo "Found ALLOWIPS_INCLUDE directory: $ALLOWIPS_INCLUDE"
|
||||
while IFS= read -r file; do
|
||||
find_csf_files "$file"
|
||||
done < <(find "$ALLOWIPS_INCLUDE" -type f 2>/dev/null)
|
||||
fi
|
||||
fi
|
||||
|
||||
# Method 4: Common custom CSF include locations (hosting panel integrations)
|
||||
COMMON_CSF_LOCATIONS=(
|
||||
"/usr/local/lp/etc/csf" # LiquidWeb
|
||||
"/usr/local/cpanel/etc/csf" # cPanel custom
|
||||
"/usr/local/interworx/etc/csf" # InterWorx
|
||||
"/var/cpanel/csf" # cPanel var
|
||||
"/root/.csf" # Custom user location
|
||||
)
|
||||
|
||||
for location in "${COMMON_CSF_LOCATIONS[@]}"; do
|
||||
if [ -d "$location" ]; then
|
||||
# Look for all .allow files in these locations
|
||||
while IFS= read -r file; do
|
||||
find_csf_files "$file"
|
||||
done < <(find "$location" -type f -name "*allow*" 2>/dev/null)
|
||||
fi
|
||||
done
|
||||
|
||||
# Method 5: Parse all Include directives from csf.conf CUSTOM variables
|
||||
if [ -f "/etc/csf/csf.conf" ]; then
|
||||
# Some systems use CUSTOM1_LOG through CUSTOM9_LOG which may reference allow files
|
||||
while IFS= read -r include_path; do
|
||||
if [ -f "$include_path" ]; then
|
||||
find_csf_files "$include_path"
|
||||
fi
|
||||
done < <(grep -E "^(CUSTOM|GENERIC).*Include" /etc/csf/csf.conf 2>/dev/null | grep -oE '\/[^"]+' || true)
|
||||
fi
|
||||
|
||||
if [ ${#CSF_FILES[@]} -eq 0 ]; then
|
||||
print_warning "No CSF .allow files found"
|
||||
CSF_AVAILABLE=false
|
||||
else
|
||||
echo "Found ${#CSF_FILES[@]} CSF allow files (including includes):"
|
||||
for file in "${CSF_FILES[@]}"; do
|
||||
if [[ "$file" == /etc/csf/* ]]; then
|
||||
echo " • $(basename "$file")"
|
||||
else
|
||||
echo " • $file"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Extract IPs from all CSF files
|
||||
CSF_ALLOW_IPS=()
|
||||
declare -A IP_SOURCE_COUNT # Track which files contributed IPs
|
||||
|
||||
if [ ${#CSF_FILES[@]} -gt 0 ]; then
|
||||
for csf_file in "${CSF_FILES[@]}"; do
|
||||
file_ip_count=0
|
||||
file_display_name=""
|
||||
|
||||
if [[ "$csf_file" == /etc/csf/* ]]; then
|
||||
file_display_name="$(basename "$csf_file")"
|
||||
else
|
||||
file_display_name="$csf_file"
|
||||
fi
|
||||
|
||||
while IFS= read -r line; do
|
||||
# Skip comments and empty lines
|
||||
[[ "$line" =~ ^#.*$ ]] && continue
|
||||
[[ -z "$line" ]] && continue
|
||||
|
||||
# Skip Include directives (already processed)
|
||||
[[ "$line" =~ ^Include ]] && continue
|
||||
|
||||
# Try multiple IP extraction methods:
|
||||
ip=""
|
||||
|
||||
# Method 1: Simple IP format (IP at start of line)
|
||||
# Example: 192.168.100.1 # comment
|
||||
# Also handles CIDR: 10.20.4.0/22 # comment (strip /CIDR, just get IP)
|
||||
if [ -z "$ip" ]; then
|
||||
ip=$(echo "$line" | awk '{print $1}' | grep -oE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
|
||||
fi
|
||||
|
||||
# Method 2: CSF source format (s=IP)
|
||||
# Example: tcp|in|d=4|s=208.74.123.2 # cPanel Auth Server
|
||||
if [ -z "$ip" ]; then
|
||||
ip=$(echo "$line" | grep -oE 's=[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d'=' -f2)
|
||||
fi
|
||||
|
||||
# Method 3: CSF destination format (d=IP)
|
||||
# Example: tcp|out|d=443|d=45.11.128.61/32
|
||||
if [ -z "$ip" ]; then
|
||||
# Extract last d= parameter that contains an IP (not a port)
|
||||
ip=$(echo "$line" | grep -oE 'd=[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -1 | cut -d'=' -f2)
|
||||
fi
|
||||
|
||||
if [ -n "$ip" ]; then
|
||||
# Check if not already in array (deduplicate)
|
||||
if [[ ! " ${CSF_ALLOW_IPS[@]} " =~ " ${ip} " ]]; then
|
||||
CSF_ALLOW_IPS+=("$ip")
|
||||
file_ip_count=$((file_ip_count + 1))
|
||||
fi
|
||||
fi
|
||||
done < "$csf_file"
|
||||
|
||||
# Track count per file
|
||||
if [ $file_ip_count -gt 0 ]; then
|
||||
IP_SOURCE_COUNT["$file_display_name"]=$file_ip_count
|
||||
fi
|
||||
done
|
||||
|
||||
# Show breakdown by file
|
||||
echo "IP breakdown by source file:"
|
||||
for file in $(printf '%s\n' "${!IP_SOURCE_COUNT[@]}" | sort); do
|
||||
printf " • %-45s %3d IPs\n" "$file" "${IP_SOURCE_COUNT[$file]}"
|
||||
done
|
||||
echo ""
|
||||
|
||||
print_success "Found ${#CSF_ALLOW_IPS[@]} total unique IPs across all CSF files"
|
||||
fi
|
||||
|
||||
if [ ${#CSF_ALLOW_IPS[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo "Sample IPs to be imported:"
|
||||
for i in {0..4}; do
|
||||
if [ -n "${CSF_ALLOW_IPS[$i]}" ]; then
|
||||
echo " • ${CSF_ALLOW_IPS[$i]}"
|
||||
fi
|
||||
done
|
||||
if [ ${#CSF_ALLOW_IPS[@]} -gt 5 ]; then
|
||||
echo " ... and $((${#CSF_ALLOW_IPS[@]} - 5)) more"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
print_section "Actions to Perform"
|
||||
|
||||
if [ "$ALREADY_ENABLED" = false ]; then
|
||||
echo " 1. Enable cPHulk brute force protection"
|
||||
else
|
||||
echo " 1. cPHulk already enabled (skip)"
|
||||
fi
|
||||
|
||||
if [ "$CSF_AVAILABLE" = true ] && [ ${#CSF_ALLOW_IPS[@]} -gt 0 ]; then
|
||||
echo " 2. Import ${#CSF_ALLOW_IPS[@]} IPs from CSF to cPHulk whitelist"
|
||||
else
|
||||
echo " 2. No CSF IPs to import (skip)"
|
||||
fi
|
||||
|
||||
echo " 3. Display final configuration"
|
||||
|
||||
echo ""
|
||||
read -p "Proceed with these actions? (yes/no): " confirm
|
||||
|
||||
if [ "$confirm" != "yes" ]; then
|
||||
print_info "Operation cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
print_section "Execution"
|
||||
|
||||
# Step 1: Enable cPHulk
|
||||
if [ "$ALREADY_ENABLED" = false ]; then
|
||||
print_info "Enabling cPHulk..."
|
||||
if /usr/local/cpanel/bin/cphulk_pam_ctl --enable 2>&1; then
|
||||
print_success "cPHulk enabled successfully"
|
||||
else
|
||||
print_error "Failed to enable cPHulk"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_info "cPHulk already enabled, skipping"
|
||||
fi
|
||||
|
||||
# Step 2: Import CSF whitelist
|
||||
if [ "$CSF_AVAILABLE" = true ] && [ ${#CSF_ALLOW_IPS[@]} -gt 0 ]; then
|
||||
print_info "Importing CSF whitelist to cPHulk..."
|
||||
|
||||
IMPORTED=0
|
||||
SKIPPED=0
|
||||
FAILED=0
|
||||
|
||||
for ip in "${CSF_ALLOW_IPS[@]}"; do
|
||||
# Check if already in cPHulk whitelist
|
||||
if /usr/local/cpanel/scripts/cphulkdwhitelist --list 2>/dev/null | grep -q "$ip"; then
|
||||
SKIPPED=$((SKIPPED + 1))
|
||||
echo " [SKIP] $ip (already whitelisted)"
|
||||
else
|
||||
# Add to cPHulk whitelist
|
||||
if whmapi1 cphulkd_add_whitelist ip="$ip" 2>&1 | grep -q "success.*1"; then
|
||||
IMPORTED=$((IMPORTED + 1))
|
||||
echo " [OK] $ip"
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
echo " [FAIL] $ip"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
print_success "Import complete:"
|
||||
echo " • Imported: $IMPORTED"
|
||||
echo " • Skipped (already whitelisted): $SKIPPED"
|
||||
if [ $FAILED -gt 0 ]; then
|
||||
print_warning "Failed: $FAILED"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Step 3: Display final status
|
||||
echo ""
|
||||
print_section "Final Configuration"
|
||||
|
||||
# Check status
|
||||
FINAL_STATUS=$(/usr/local/cpanel/bin/cphulk_pam_ctl --status 2>/dev/null)
|
||||
if echo "$FINAL_STATUS" | grep -qi "enabled"; then
|
||||
print_success "cPHulk Status: ENABLED"
|
||||
else
|
||||
print_error "cPHulk Status: DISABLED (unexpected)"
|
||||
fi
|
||||
|
||||
# Count whitelist
|
||||
FINAL_WHITELIST=$(/usr/local/cpanel/scripts/cphulkdwhitelist --list 2>/dev/null | grep -v "^$" | wc -l)
|
||||
print_info "cPHulk whitelist entries: $FINAL_WHITELIST"
|
||||
|
||||
echo ""
|
||||
print_section "Next Steps"
|
||||
|
||||
echo "1. Configure cPHulk settings in WHM:"
|
||||
echo " WHM → Security Center → cPHulk Brute Force Protection"
|
||||
echo ""
|
||||
echo "2. Recommended settings:"
|
||||
echo " • Brute Force Protection Period: 5 minutes"
|
||||
echo " • Maximum Failures per Account: 5"
|
||||
echo " • Maximum Failures per IP: 10"
|
||||
echo ""
|
||||
echo "3. Add your own IPs to whitelist:"
|
||||
echo " whmapi1 cphulkd_add_whitelist ip=YOUR.IP.ADDRESS"
|
||||
echo ""
|
||||
echo "4. View currently blocked IPs:"
|
||||
echo " whmapi1 cphulkd_list_blocks"
|
||||
echo ""
|
||||
echo "5. Remove a blocked IP:"
|
||||
echo " whmapi1 cphulkd_remove_block ip=IP.TO.UNBLOCK"
|
||||
|
||||
echo ""
|
||||
print_success "cPHulk setup complete!"
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
source "$SCRIPT_DIR/lib/common-functions.sh"
|
||||
print_banner "Firewall Activity Monitor"
|
||||
echo "Monitoring CSF/iptables activity..."
|
||||
echo "Press Ctrl+C to exit"
|
||||
echo ""
|
||||
tail -f /var/log/messages | grep --line-buffered -i "iptables\|csf\|firewall"
|
||||
Executable
+402
@@ -0,0 +1,402 @@
|
||||
#!/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
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
source "$SCRIPT_DIR/lib/common-functions.sh"
|
||||
|
||||
print_banner "SSH Attack Monitor"
|
||||
echo ""
|
||||
echo "Monitoring SSH authentication attempts in real-time..."
|
||||
echo "Press Ctrl+C to exit"
|
||||
echo ""
|
||||
|
||||
tail -f /var/log/secure | grep --line-buffered -i "failed\|authentication failure" | while read line; do
|
||||
timestamp=$(echo "$line" | awk '{print $1, $2, $3}')
|
||||
ip=$(echo "$line" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)
|
||||
printf "[%s] \033[1;31m%-15s\033[0m %s\n" "$timestamp" "$ip" "$(echo $line | cut -c50-)"
|
||||
done
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
source "$SCRIPT_DIR/lib/common-functions.sh"
|
||||
print_banner "Apache Access Log"
|
||||
echo "Tailing Apache access logs..."
|
||||
echo "Press Ctrl+C to exit"
|
||||
echo ""
|
||||
[ -d "/var/log/apache2/domlogs" ] && tail -f /var/log/apache2/domlogs/* || echo "No access logs found"
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
source "$SCRIPT_DIR/lib/common-functions.sh"
|
||||
print_banner "Apache Error Log"
|
||||
echo "Tailing Apache error logs..."
|
||||
echo "Press Ctrl+C to exit"
|
||||
echo ""
|
||||
tail -f /var/log/apache2/error_log 2>/dev/null || tail -f /var/log/httpd/error_log 2>/dev/null || echo "No error logs found"
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
source "$SCRIPT_DIR/lib/common-functions.sh"
|
||||
print_banner "Mail Log Monitor"
|
||||
echo "Tailing mail logs..."
|
||||
echo "Press Ctrl+C to exit"
|
||||
echo ""
|
||||
tail -f /var/log/maillog 2>/dev/null || tail -f /var/log/mail.log 2>/dev/null || echo "No mail logs found"
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
source "$SCRIPT_DIR/lib/common-functions.sh"
|
||||
print_banner "Security Log Monitor"
|
||||
echo "Tailing /var/log/secure..."
|
||||
echo "Press Ctrl+C to exit"
|
||||
echo ""
|
||||
tail -f /var/log/secure
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
source "$SCRIPT_DIR/lib/common-functions.sh"
|
||||
|
||||
print_banner "Web Traffic Monitor"
|
||||
echo ""
|
||||
echo "Monitoring Apache access logs in real-time..."
|
||||
echo "Press Ctrl+C to exit"
|
||||
echo ""
|
||||
|
||||
# Find apache log directory
|
||||
if [ -d "/var/log/apache2/domlogs" ]; then
|
||||
tail -f /var/log/apache2/domlogs/* 2>/dev/null | while read line; do
|
||||
ip=$(echo "$line" | awk '{print $1}')
|
||||
request=$(echo "$line" | awk '{print $6, $7}' | tr -d '"')
|
||||
status=$(echo "$line" | awk '{print $9}')
|
||||
|
||||
# Color code by status
|
||||
if [[ "$status" =~ ^5 ]]; then
|
||||
color="\033[1;31m" # Red for 5xx
|
||||
elif [[ "$status" =~ ^4 ]]; then
|
||||
color="\033[1;33m" # Yellow for 4xx
|
||||
elif [[ "$status" =~ ^2 ]]; then
|
||||
color="\033[0;32m" # Green for 2xx
|
||||
else
|
||||
color="\033[0;37m" # White for others
|
||||
fi
|
||||
|
||||
printf "${color}%-15s %s %s\033[0m\n" "$ip" "$status" "$request"
|
||||
done
|
||||
else
|
||||
print_error "Apache domlogs directory not found"
|
||||
fi
|
||||
Reference in New Issue
Block a user