diff --git a/modules/security/live-attack-monitor.sh b/modules/security/live-attack-monitor.sh index a942feb..9e3c750 100755 --- a/modules/security/live-attack-monitor.sh +++ b/modules/security/live-attack-monitor.sh @@ -1006,12 +1006,20 @@ draw_intelligence_panel() { fi # Get top IPs by threat score (exclude already blocked IPs) + # Load blocked IPs cache into associative array for O(1) lookups + declare -A blocked_ips_lookup + if [ -f "$TEMP_DIR/blocked_ips_cache" ]; then + while IFS= read -r blocked_ip; do + [ -n "$blocked_ip" ] && blocked_ips_lookup[$blocked_ip]=1 + done < "$TEMP_DIR/blocked_ips_cache" + fi + local ip_list="" local blocked_count=0 local displayed_count=0 for ip in "${!IP_DATA[@]}"; do - # Skip IPs that are already blocked - if is_ip_blocked "$ip" 2>/dev/null; then + # Skip IPs that are already blocked (O(1) lookup in hash) + if [ -n "${blocked_ips_lookup[$ip]}" ]; then ((blocked_count++)) echo " Filtering out blocked IP: $ip" >> "$TEMP_DIR/debug.log" continue @@ -1053,12 +1061,12 @@ draw_intelligence_panel() { # Threat level status_line+=$(printf " [%-8s]" "$level") - # Attacks + # Attacks (use bash parameter expansion instead of cut) if [ -n "$attacks" ]; then # Show first attack type - local first_attack=$(echo "$attacks" | cut -d',' -f1) + local first_attack="${attacks%%,*}" local icon=$(get_attack_icon "$first_attack") - status_line+=" $icon$(echo "$attacks" | cut -d',' -f1)" + status_line+=" $icon$first_attack" fi # Ban count @@ -2204,12 +2212,27 @@ detect_distributed_attacks() { # 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 + # Check for same attack type from 5+ different IPs (use awk for performance) for attack_type in RCE SQL_INJECTION XSS PATH_TRAVERSAL BRUTEFORCE; do - local attack_count=$(echo "$recent" | grep -c "$attack_type") + # Single AWK pass to count attacks and unique IPs + local result=$(echo "$recent" | awk -v pattern="$attack_type" ' + $0 ~ pattern { + count++ + # Extract IP (first field matching IP pattern) + for(i=1; i<=NF; i++) { + if($i ~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/) { + ips[$i]=1 + break + } + } + } + END { + print count "|" length(ips) + } + ') + IFS='|' read -r attack_count unique_ips <<< "$result" - 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 [ "${attack_count:-0}" -ge 5 ]; then if [ "$unique_ips" -ge 5 ]; then # Distributed attack detected!