diff --git a/lib/system-detect.sh b/lib/system-detect.sh index 42516a9..5c7fbe4 100755 --- a/lib/system-detect.sh +++ b/lib/system-detect.sh @@ -67,7 +67,9 @@ detect_control_panel() { if [ -f "/usr/local/interworx/iworx/version.php" ]; then SYS_CONTROL_PANEL_VERSION=$(grep -oP "VERSION = '\K[^']+" /usr/local/interworx/iworx/version.php 2>/dev/null || echo "Unknown") fi - SYS_LOG_DIR="/home" + # InterWorx stores logs in /home/user/var/domain.com/logs/ + # We set a marker path that tools will recognize needs special handling + SYS_LOG_DIR="/home/*/var/*/logs" SYS_USER_HOME_BASE="/home" print_success "Detected InterWorx v${SYS_CONTROL_PANEL_VERSION}" @@ -263,6 +265,77 @@ detect_cloudflare() { fi } +############################################################################# +# FIREWALL DETECTION +############################################################################# + +detect_firewall() { + print_info "Detecting firewall..." + + # CSF/LFD + if [ -f "/etc/csf/csf.conf" ]; then + SYS_FIREWALL="csf" + SYS_FIREWALL_VERSION=$(csf -v 2>/dev/null | grep -oP 'v\K[\d.]+' | head -1 || echo "unknown") + if systemctl is-active --quiet lfd 2>/dev/null || service lfd status 2>/dev/null | grep -q running; then + SYS_FIREWALL_ACTIVE="yes" + print_success "Detected CSF ${SYS_FIREWALL_VERSION} (active)" + else + SYS_FIREWALL_ACTIVE="no" + print_warning "Detected CSF ${SYS_FIREWALL_VERSION} (inactive)" + fi + export SYS_CSF_ACTIVE="${SYS_FIREWALL_ACTIVE}" + return 0 + fi + + # firewalld + if command_exists firewall-cmd; then + SYS_FIREWALL="firewalld" + SYS_FIREWALL_VERSION=$(firewall-cmd --version 2>/dev/null || echo "unknown") + if systemctl is-active --quiet firewalld 2>/dev/null; then + SYS_FIREWALL_ACTIVE="yes" + print_success "Detected firewalld ${SYS_FIREWALL_VERSION} (active)" + else + SYS_FIREWALL_ACTIVE="no" + print_warning "Detected firewalld ${SYS_FIREWALL_VERSION} (inactive)" + fi + return 0 + fi + + # iptables + if command_exists iptables; then + SYS_FIREWALL="iptables" + SYS_FIREWALL_VERSION=$(iptables --version 2>/dev/null | grep -oP 'v\K[\d.]+' | head -1 || echo "unknown") + # Check if iptables has any rules + if [ "$(iptables -L -n 2>/dev/null | wc -l)" -gt 8 ]; then + SYS_FIREWALL_ACTIVE="yes" + print_success "Detected iptables ${SYS_FIREWALL_VERSION} (active)" + else + SYS_FIREWALL_ACTIVE="no" + print_warning "Detected iptables ${SYS_FIREWALL_VERSION} (no rules)" + fi + return 0 + fi + + # UFW + if command_exists ufw; then + SYS_FIREWALL="ufw" + SYS_FIREWALL_VERSION=$(ufw version 2>/dev/null | grep -oP '\d+\.\d+\.\d+' | head -1 || echo "unknown") + if ufw status 2>/dev/null | grep -q "Status: active"; then + SYS_FIREWALL_ACTIVE="yes" + print_success "Detected UFW ${SYS_FIREWALL_VERSION} (active)" + else + SYS_FIREWALL_ACTIVE="no" + print_warning "Detected UFW ${SYS_FIREWALL_VERSION} (inactive)" + fi + return 0 + fi + + SYS_FIREWALL="none" + SYS_FIREWALL_ACTIVE="no" + print_warning "No firewall detected" + return 1 +} + ############################################################################# # SYSTEM RESOURCES (Comprehensive - like user's example) ############################################################################# @@ -427,6 +500,7 @@ initialize_system_detection() { detect_database detect_php_versions detect_cloudflare + detect_firewall get_system_resources # Mark as initialized diff --git a/modules/security/bot-analyzer.sh b/modules/security/bot-analyzer.sh index 57b6ceb..583ba9f 100755 --- a/modules/security/bot-analyzer.sh +++ b/modules/security/bot-analyzer.sh @@ -279,7 +279,11 @@ print_success() { ############################################################################# parse_logs() { - print_info "Parsing logs from: $LOG_DIR" + if [ "$INTERWORX_MODE" = "yes" ]; then + print_info "Parsing InterWorx domain logs from: /home/*/var/*/logs/" + else + print_info "Parsing logs from: $LOG_DIR" + fi local find_opts=() @@ -293,16 +297,38 @@ parse_logs() { print_info "Filtering logs from last $DAYS_BACK days" fi - # Parse all domain logs (excluding -bytes_log, .offset, and error_log files) - # cPanel creates files like: domain.com, domain.com-ssl_log + # Determine log file search pattern based on control panel + local log_search_path + local log_search_name + if [ "$INTERWORX_MODE" = "yes" ]; then + # InterWorx: /home/user/var/domain.com/logs/access_log + log_search_path="/home/*/var/*/logs" + log_search_name="access_log" + else + # cPanel/Plesk: /var/log/apache2/domlogs/domain.com + log_search_path="$LOG_DIR" + log_search_name="*" + fi + + # Parse all domain logs local file_count=0 local progress_interval=50 echo "" - find "$LOG_DIR" -type f ! -name "*-bytes_log" ! -name "*.offset" ! -name "*error_log" "${find_opts[@]}" 2>/dev/null | while read -r logfile; do + find "$log_search_path" -type f -name "$log_search_name" ! -name "*-bytes_log" ! -name "*.offset" ! -name "*error_log" "${find_opts[@]}" 2>/dev/null | while read -r logfile; do # Skip empty files [ -s "$logfile" ] || continue - domain=$(basename "$logfile" | sed 's/-ssl_log$//') + # Extract domain name based on control panel + if [ "$INTERWORX_MODE" = "yes" ]; then + # InterWorx: extract from path /home/user/var/domain.com/logs/access_log + domain=$(echo "$logfile" | sed -n 's|^/home/.*/var/\([^/]*\)/logs/.*|\1|p') + else + # cPanel: extract from filename + domain=$(basename "$logfile" | sed 's/-ssl_log$//') + fi + + # Skip if domain extraction failed + [ -z "$domain" ] && continue # User filtering: skip domains not belonging to the specified user if [ -n "$FILTER_USER" ]; then @@ -1766,20 +1792,67 @@ main() { echo "" print_header "Starting Apache/cPanel Bot Analysis" - # Check if log directory exists - if [ ! -d "$LOG_DIR" ]; then - print_alert "Error: Log directory not found: $LOG_DIR" - echo "Please specify the correct log directory with -l option" - exit 1 - fi + # InterWorx requires special log discovery (logs are in /home/user/var/domain.com/logs/) + if [ "$SYS_CONTROL_PANEL" = "interworx" ]; then + print_info "InterWorx detected - discovering domain logs..." - # Check if logs exist - local find_opts=() - if [ -n "$HOURS_BACK" ]; then - local minutes=$((HOURS_BACK * 60)) - find_opts+=(-mmin -"$minutes") - elif [ -n "$DAYS_BACK" ]; then - find_opts+=(-mtime -"$DAYS_BACK") + # Build time filter options + local find_opts=() + if [ -n "$HOURS_BACK" ]; then + local minutes=$((HOURS_BACK * 60)) + find_opts+=(-mmin -"$minutes") + elif [ -n "$DAYS_BACK" ]; then + find_opts+=(-mtime -"$DAYS_BACK") + fi + + # Find all access_log files in InterWorx structure + log_count=$(find /home/*/var/*/logs -type f -name "access_log" "${find_opts[@]}" 2>/dev/null | wc -l) + + if [ "$log_count" -eq 0 ]; then + print_alert "Error: No InterWorx access logs found in /home/*/var/*/logs/" + if [ -n "$HOURS_BACK" ]; then + echo "No logs found from the last $HOURS_BACK hours" + elif [ -n "$DAYS_BACK" ]; then + echo "No logs found from the last $DAYS_BACK days" + fi + exit 1 + fi + + print_info "Found $log_count InterWorx domain log files to analyze" + + # Override LOG_DIR for parse_logs function to use + export INTERWORX_MODE="yes" + export INTERWORX_FIND_OPTS="${find_opts[*]}" + else + # Standard cPanel/Plesk log discovery + # Check if log directory exists + if [ ! -d "$LOG_DIR" ]; then + print_alert "Error: Log directory not found: $LOG_DIR" + echo "Please specify the correct log directory with -l option" + exit 1 + fi + + # Check if logs exist + local find_opts=() + if [ -n "$HOURS_BACK" ]; then + local minutes=$((HOURS_BACK * 60)) + find_opts+=(-mmin -"$minutes") + elif [ -n "$DAYS_BACK" ]; then + find_opts+=(-mtime -"$DAYS_BACK") + fi + + log_count=$(find "$LOG_DIR" -type f ! -name "*-bytes_log" ! -name "*.offset" ! -name "*error_log" "${find_opts[@]}" 2>/dev/null | wc -l) + if [ "$log_count" -eq 0 ]; then + print_alert "Error: No log files found in $LOG_DIR" + if [ -n "$HOURS_BACK" ]; then + echo "No logs found from the last $HOURS_BACK hours" + elif [ -n "$DAYS_BACK" ]; then + echo "No logs found from the last $DAYS_BACK days" + fi + exit 1 + fi + + print_info "Found $log_count log files to analyze" fi # User filtering @@ -1795,18 +1868,7 @@ main() { export user_domains="" fi - log_count=$(find "$LOG_DIR" -type f ! -name "*-bytes_log" ! -name "*.offset" ! -name "*error_log" "${find_opts[@]}" 2>/dev/null | wc -l) - if [ "$log_count" -eq 0 ]; then - print_alert "Error: No log files found in $LOG_DIR" - if [ -n "$HOURS_BACK" ]; then - echo "No logs found from the last $HOURS_BACK hours" - elif [ -n "$DAYS_BACK" ]; then - echo "No logs found from the last $DAYS_BACK days" - fi - exit 1 - fi - - print_info "Found $log_count log files to analyze" + # Print time range info if [ -n "$HOURS_BACK" ]; then print_info "Analyzing logs from the last $HOURS_BACK hours" elif [ -n "$DAYS_BACK" ]; then