From f0d53322e61c4b6ca1efc6caf74f1224dc4ab886 Mon Sep 17 00:00:00 2001 From: cschantz Date: Fri, 14 Nov 2025 20:52:07 -0500 Subject: [PATCH] Fix Email, FTP, and Database monitoring to use file-based IP storage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All background monitoring functions had same subshell bug as SSH: - Cannot access IP_DATA associative array from subshells - Switched to file-based storage: individual ip_* files per IP - Main loop consolidates files into ip_data for auto-mitigation - Fixes Email bruteforce detection (dovecot auth failures) - Fixes FTP bruteforce detection (vsftpd/xferlog) - Fixes Database attack detection (MySQL auth failures) Now ALL monitoring channels work properly: - SSH: file-based ✓ - Email: file-based ✓ - FTP: file-based ✓ - Database: file-based ✓ - Web/Apache: direct display (no subshell) ✓ --- modules/security/live-attack-monitor.sh | 33 ++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/modules/security/live-attack-monitor.sh b/modules/security/live-attack-monitor.sh index 1b35257..e081abe 100755 --- a/modules/security/live-attack-monitor.sh +++ b/modules/security/live-attack-monitor.sh @@ -1550,7 +1550,12 @@ monitor_email_attacks() { [[ "$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}" + # Read from file (subshells can't access IP_DATA array) + local ip_file="$TEMP_DIR/ip_${ip//\./_}" + local current_data="0|0|human||0|0" + if [ -f "$ip_file" ]; then + current_data=$(cat "$ip_file") + fi IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current_data" hits=$((hits + 1)) @@ -1612,7 +1617,9 @@ monitor_email_attacks() { [ $score -gt 100 ] && score=100 - IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score" + # Update ip_data file directly (subshells can't access IP_DATA array) + local ip_file="$TEMP_DIR/ip_${ip//\./_}" + echo "$score|$hits|$bot_type|$attacks|$ban_count|$rep_score" > "$ip_file" # Store block reasons for CSF if [ -n "$block_reasons" ]; then @@ -1657,7 +1664,12 @@ monitor_ftp_attacks() { [[ "$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}" + # Read from file (subshells can't access IP_DATA array) + local ip_file="$TEMP_DIR/ip_${ip//\./_}" + local current_data="0|0|human||0|0" + if [ -f "$ip_file" ]; then + current_data=$(cat "$ip_file") + fi IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current_data" hits=$((hits + 1)) @@ -1719,7 +1731,9 @@ monitor_ftp_attacks() { [ $score -gt 100 ] && score=100 - IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score" + # Update ip_data file directly (subshells can't access IP_DATA array) + local ip_file="$TEMP_DIR/ip_${ip//\./_}" + echo "$score|$hits|$bot_type|$attacks|$ban_count|$rep_score" > "$ip_file" # Store block reasons for CSF if [ -n "$block_reasons" ]; then @@ -1764,7 +1778,12 @@ monitor_database_attacks() { [[ "$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}" + # Read from file (subshells can't access IP_DATA array) + local ip_file="$TEMP_DIR/ip_${ip//\./_}" + local current_data="0|0|human||0|0" + if [ -f "$ip_file" ]; then + current_data=$(cat "$ip_file") + fi IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$current_data" hits=$((hits + 1)) @@ -1828,7 +1847,9 @@ monitor_database_attacks() { [ $score -gt 100 ] && score=100 - IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score" + # Update ip_data file directly (subshells can't access IP_DATA array) + local ip_file="$TEMP_DIR/ip_${ip//\./_}" + echo "$score|$hits|$bot_type|$attacks|$ban_count|$rep_score" > "$ip_file" # Store block reasons for CSF if [ -n "$block_reasons" ]; then