Fix: Double arithmetic syntax error in generate_comparison_report (line 2073)
This commit is contained in:
@@ -419,7 +419,8 @@ if [ "$sent" -gt 0 ] || [ "$received" -gt 0 ]; then
|
|||||||
# Top recipients (delivery recipients from emails in TEMP_MATCHES)
|
# Top recipients (delivery recipients from emails in TEMP_MATCHES)
|
||||||
if [ "$sent" -gt 0 ] || [ "$delivered" -gt 0 ]; then
|
if [ "$sent" -gt 0 ] || [ "$delivered" -gt 0 ]; then
|
||||||
print_info "Top 5 recipients (emails delivered TO):"
|
print_info "Top 5 recipients (emails delivered TO):"
|
||||||
grep -F "$search_pattern" "$TEMP_MATCHES" 2>/dev/null | grep -oE "=> [^@]+@[^ ]+" | sed 's/=> //' | sort | uniq -c | sort -rn | head -5 | while read count recipient; do
|
sed -n "/^$search_pattern/p" "$TEMP_MATCHES" 2>/dev/null | \
|
||||||
|
sed -n 's/.*=> \([^@]*@[^ ]*\).*/\1/p' | sort | uniq -c | sort -rn | head -5 | while read count recipient; do
|
||||||
[ -n "$count" ] && echo " $recipient - $count emails"
|
[ -n "$count" ] && echo " $recipient - $count emails"
|
||||||
done
|
done
|
||||||
echo ""
|
echo ""
|
||||||
@@ -428,7 +429,8 @@ if [ "$sent" -gt 0 ] || [ "$received" -gt 0 ]; then
|
|||||||
# Top senders (who is sending emails in TEMP_MATCHES)
|
# Top senders (who is sending emails in TEMP_MATCHES)
|
||||||
if [ "$sent" -gt 0 ]; then
|
if [ "$sent" -gt 0 ]; then
|
||||||
print_info "Top 5 senders (emails sent FROM):"
|
print_info "Top 5 senders (emails sent FROM):"
|
||||||
grep -F "$search_pattern" "$TEMP_MATCHES" 2>/dev/null | grep -oE "<= [^@]+@[^ ]+" | sed 's/<= //' | sort | uniq -c | sort -rn | head -5 | while read count sender; do
|
sed -n "/^$search_pattern/p" "$TEMP_MATCHES" 2>/dev/null | \
|
||||||
|
sed -n 's/.*<= \([^@]*@[^ ]*\).*/\1/p' | sort | uniq -c | sort -rn | head -5 | while read count sender; do
|
||||||
[ -n "$count" ] && echo " $sender - $count emails"
|
[ -n "$count" ] && echo " $sender - $count emails"
|
||||||
done
|
done
|
||||||
echo ""
|
echo ""
|
||||||
@@ -546,7 +548,7 @@ if [ "$check_type" != "2" ]; then
|
|||||||
|
|
||||||
# cPanel forwarders (in /etc/valiases)
|
# cPanel forwarders (in /etc/valiases)
|
||||||
if [ -f "/etc/valiases/$domain_part" ]; then
|
if [ -f "/etc/valiases/$domain_part" ]; then
|
||||||
forwarder=$(grep -F "^$local_part:" "/etc/valiases/$domain_part" 2>/dev/null)
|
forwarder=$(grep "^${local_part}:" "/etc/valiases/$domain_part" 2>/dev/null || echo "")
|
||||||
if [ -n "$forwarder" ]; then
|
if [ -n "$forwarder" ]; then
|
||||||
echo ""
|
echo ""
|
||||||
print_info "Forwarder configured:"
|
print_info "Forwarder configured:"
|
||||||
@@ -650,7 +652,7 @@ if [ "$delivered" -gt 0 ]; then
|
|||||||
else
|
else
|
||||||
echo " $line"
|
echo " $line"
|
||||||
fi
|
fi
|
||||||
done < <(grep -F "$search_pattern" "$TEMP_MATCHES" | grep -iE "=>|delivered" | tail -5)
|
done < <(sed -n "/^$search_pattern/p" "$TEMP_MATCHES" 2>/dev/null | sed -n '/=>\|[Dd]elivered/p' | tail -5)
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -660,7 +662,7 @@ if [ "$bounced" -gt 0 ]; then
|
|||||||
|
|
||||||
# Get all bounce lines (Issue 4.1: add -- after grep flags)
|
# Get all bounce lines (Issue 4.1: add -- after grep flags)
|
||||||
TEMP_BOUNCES="/tmp/email_bounces_$$.txt"
|
TEMP_BOUNCES="/tmp/email_bounces_$$.txt"
|
||||||
grep -F -- "$search_pattern" "$TEMP_MATCHES" 2>/dev/null | \
|
sed -n "/^$search_pattern/p" "$TEMP_MATCHES" 2>/dev/null | \
|
||||||
grep -Ev "authenticator failed|Authentication failed|saved mail to|=>" | \
|
grep -Ev "authenticator failed|Authentication failed|saved mail to|=>" | \
|
||||||
grep -iE "550|551|552|553|554|bounced|Mail delivery failed|\\*\\* " > "$TEMP_BOUNCES" 2>/dev/null
|
grep -iE "550|551|552|553|554|bounced|Mail delivery failed|\\*\\* " > "$TEMP_BOUNCES" 2>/dev/null
|
||||||
|
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ if [ "$MTA" = "exim" ]; then
|
|||||||
print_header "Queue Summary"
|
print_header "Queue Summary"
|
||||||
|
|
||||||
# Exim: exim -bpc returns just the number
|
# Exim: exim -bpc returns just the number
|
||||||
queue_count=$(eval "$SYS_MAIL_CMD_QUEUE_COUNT")
|
queue_count=$(bash -c "$SYS_MAIL_CMD_QUEUE_COUNT" 2>/dev/null || echo "0")
|
||||||
|
|
||||||
if [ "$queue_count" -gt 0 ] 2>/dev/null; then
|
if [ "$queue_count" -gt 0 ] 2>/dev/null; then
|
||||||
print_warning "$queue_count messages in queue"
|
print_warning "$queue_count messages in queue"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Cache queue list - single execution for all operations
|
# Cache queue list - single execution for all operations
|
||||||
queue_list=$(eval "$SYS_MAIL_CMD_QUEUE_LIST")
|
queue_list=$(bash -c "$SYS_MAIL_CMD_QUEUE_LIST" 2>/dev/null || echo "")
|
||||||
|
|
||||||
print_header "Recent Queue Messages (last 20)"
|
print_header "Recent Queue Messages (last 20)"
|
||||||
echo "$queue_list" | head -20
|
echo "$queue_list" | head -20
|
||||||
@@ -74,7 +74,7 @@ elif [ "$MTA" = "postfix" ]; then
|
|||||||
print_header "Queue Summary"
|
print_header "Queue Summary"
|
||||||
|
|
||||||
# Postfix: mailq | tail -1 returns "-- N Kbytes in M Requests."
|
# Postfix: mailq | tail -1 returns "-- N Kbytes in M Requests."
|
||||||
queue_summary=$(eval "$SYS_MAIL_CMD_QUEUE_COUNT")
|
queue_summary=$(bash -c "$SYS_MAIL_CMD_QUEUE_COUNT" 2>/dev/null || echo "")
|
||||||
print_info "$queue_summary"
|
print_info "$queue_summary"
|
||||||
|
|
||||||
# Extract message count from summary line (last number is always message count)
|
# Extract message count from summary line (last number is always message count)
|
||||||
@@ -89,7 +89,7 @@ elif [ "$MTA" = "postfix" ]; then
|
|||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Cache queue list - single execution for all operations
|
# Cache queue list - single execution for all operations
|
||||||
queue_list=$(eval "$SYS_MAIL_CMD_QUEUE_LIST")
|
queue_list=$(bash -c "$SYS_MAIL_CMD_QUEUE_LIST" 2>/dev/null || echo "")
|
||||||
|
|
||||||
print_header "Queue Details (first 50)"
|
print_header "Queue Details (first 50)"
|
||||||
echo "$queue_list" | head -50
|
echo "$queue_list" | head -50
|
||||||
@@ -116,7 +116,7 @@ elif [ "$MTA" = "sendmail" ]; then
|
|||||||
print_header "Queue Summary"
|
print_header "Queue Summary"
|
||||||
|
|
||||||
# Sendmail: mailq | tail -1 returns "-- N Kbytes in M Requests."
|
# Sendmail: mailq | tail -1 returns "-- N Kbytes in M Requests."
|
||||||
queue_summary=$(eval "$SYS_MAIL_CMD_QUEUE_COUNT")
|
queue_summary=$(bash -c "$SYS_MAIL_CMD_QUEUE_COUNT" 2>/dev/null || echo "")
|
||||||
print_info "$queue_summary"
|
print_info "$queue_summary"
|
||||||
|
|
||||||
# Extract message count from summary line (last number is always message count)
|
# Extract message count from summary line (last number is always message count)
|
||||||
@@ -131,7 +131,7 @@ elif [ "$MTA" = "sendmail" ]; then
|
|||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Cache queue list - single execution for all operations
|
# Cache queue list - single execution for all operations
|
||||||
queue_list=$(eval "$SYS_MAIL_CMD_QUEUE_LIST")
|
queue_list=$(bash -c "$SYS_MAIL_CMD_QUEUE_LIST" 2>/dev/null || echo "")
|
||||||
|
|
||||||
print_header "Queue Details (first 50)"
|
print_header "Queue Details (first 50)"
|
||||||
echo "$queue_list" | head -50
|
echo "$queue_list" | head -50
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Disk Space Analyzer (WinDirStat for Linux)
|
# Disk Space Analyzer (WinDirStat for Linux)
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
source "$SCRIPT_DIR/lib/common-functions.sh"
|
source "$SCRIPT_DIR/lib/common-functions.sh"
|
||||||
source "$SCRIPT_DIR/lib/system-detect.sh"
|
source "$SCRIPT_DIR/lib/system-detect.sh"
|
||||||
|
source "$SCRIPT_DIR/lib/reference-db.sh"
|
||||||
|
|
||||||
# Require root
|
# Require root
|
||||||
if [ "$EUID" -ne 0 ]; then
|
if [ "$EUID" -ne 0 ]; then
|
||||||
@@ -24,6 +26,9 @@ if [ "$EUID" -ne 0 ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ensure cache is fresh (only rebuilds if > 1 hour old)
|
||||||
|
db_ensure_fresh 2>/dev/null || true
|
||||||
|
|
||||||
# Temp file for results
|
# Temp file for results
|
||||||
TEMP_DIR="/tmp/disk-analysis-$$"
|
TEMP_DIR="/tmp/disk-analysis-$$"
|
||||||
mkdir -p "$TEMP_DIR"
|
mkdir -p "$TEMP_DIR"
|
||||||
@@ -619,55 +624,51 @@ analyze_wordpress() {
|
|||||||
print_banner "WordPress Storage Analysis"
|
print_banner "WordPress Storage Analysis"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Find WordPress installations
|
# Find WordPress installations from cache (instant lookup, no filesystem scan)
|
||||||
show_progress "Finding WordPress installations"
|
show_progress "Finding WordPress installations"
|
||||||
|
|
||||||
local wp_paths=()
|
local wp_count=0
|
||||||
|
local wp_data=""
|
||||||
|
|
||||||
# Common locations
|
# Get WordPress data from cache
|
||||||
if [ -d "/home" ]; then
|
if command -v db_get_all_wordpress &>/dev/null; then
|
||||||
while IFS= read -r wp_config; do
|
wp_data=$(db_get_all_wordpress 2>/dev/null || true)
|
||||||
wp_dir=$(dirname "$wp_config")
|
|
||||||
wp_paths+=("$wp_dir")
|
|
||||||
done < <(find /home -name "wp-config.php" -type f 2>/dev/null)
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -d "/var/www" ]; then
|
# Count WP installations
|
||||||
while IFS= read -r wp_config; do
|
if [ -n "$wp_data" ]; then
|
||||||
wp_dir=$(dirname "$wp_config")
|
wp_count=$(echo "$wp_data" | grep -c "^WP|" || echo 0)
|
||||||
wp_paths+=("$wp_dir")
|
|
||||||
done < <(find /var/www -name "wp-config.php" -type f 2>/dev/null)
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ${#wp_paths[@]} -eq 0 ]; then
|
if [ "$wp_count" -eq 0 ]; then
|
||||||
echo -e "\r${DIM}No WordPress installations found${NC} "
|
echo -e "\r${DIM}No WordPress installations found${NC} "
|
||||||
echo ""
|
echo ""
|
||||||
press_enter
|
press_enter
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "\r${GREEN}✓${NC} Found ${#wp_paths[@]} WordPress installations "
|
echo -e "\r${GREEN}✓${NC} Found ${wp_count} WordPress installations "
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
echo -e "${BOLD}WordPress Space Usage:${NC}"
|
echo -e "${BOLD}WordPress Space Usage:${NC}"
|
||||||
echo "───────────────────────────────────────────────────────────────"
|
echo "───────────────────────────────────────────────────────────────"
|
||||||
|
|
||||||
for wp_dir in "${wp_paths[@]}"; do
|
# Process cached WordPress data
|
||||||
# Get domain/user from path
|
while IFS='|' read -r type domain path db_name db_user version plugins themes; do
|
||||||
domain=$(echo "$wp_dir" | awk -F'/' '{for(i=1;i<=NF;i++) if($i~/public_html|httpdocs|www/) print $(i-1)}' | tail -1)
|
if [ "$type" = "WP" ] && [ -d "$path" ]; then
|
||||||
|
|
||||||
# Calculate sizes
|
# Calculate sizes
|
||||||
total_size=$(du -sh "$wp_dir" 2>/dev/null | awk '{print $1}')
|
total_size=$(du -sh "$path" 2>/dev/null | awk '{print $1}')
|
||||||
uploads_size=$(du -sh "$wp_dir/wp-content/uploads" 2>/dev/null | awk '{print $1}')
|
uploads_size=$(du -sh "$path/wp-content/uploads" 2>/dev/null | awk '{print $1}')
|
||||||
plugins_size=$(du -sh "$wp_dir/wp-content/plugins" 2>/dev/null | awk '{print $1}')
|
plugins_size=$(du -sh "$path/wp-content/plugins" 2>/dev/null | awk '{print $1}')
|
||||||
cache_size=$(du -sh "$wp_dir/wp-content/cache" 2>/dev/null | awk '{print $1}')
|
cache_size=$(du -sh "$path/wp-content/cache" 2>/dev/null | awk '{print $1}')
|
||||||
|
|
||||||
echo -e "${BOLD}$domain${NC} ($total_size)"
|
echo -e "${BOLD}$domain${NC} ($total_size)"
|
||||||
echo -e " Uploads: ${CYAN}${uploads_size:-0}${NC}"
|
echo -e " Uploads: ${CYAN}${uploads_size:-0}${NC}"
|
||||||
echo -e " Plugins: ${CYAN}${plugins_size:-0}${NC}"
|
echo -e " Plugins: ${CYAN}${plugins_size:-0}${NC}"
|
||||||
echo -e " Cache: ${CYAN}${cache_size:-0}${NC}"
|
echo -e " Cache: ${CYAN}${cache_size:-0}${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
done
|
fi
|
||||||
|
done <<< "$wp_data"
|
||||||
|
|
||||||
echo -e "${BOLD}Cleanup Suggestions:${NC}"
|
echo -e "${BOLD}Cleanup Suggestions:${NC}"
|
||||||
echo " • Delete old revisions: wp post delete \$(wp post list --post_type=revision --format=ids)"
|
echo " • Delete old revisions: wp post delete \$(wp post list --post_type=revision --format=ids)"
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ source "$TOOLKIT_ROOT/lib/reference-db.sh"
|
|||||||
# Initialize system detection
|
# Initialize system detection
|
||||||
detect_system
|
detect_system
|
||||||
|
|
||||||
|
# Ensure reference database is fresh (only rebuild if > 1 hour old)
|
||||||
|
db_ensure_fresh 2>/dev/null || true
|
||||||
|
|
||||||
# Load system info from reference database
|
# Load system info from reference database
|
||||||
if [ -f "$TOOLKIT_ROOT/.sysref" ]; then
|
if [ -f "$TOOLKIT_ROOT/.sysref" ]; then
|
||||||
SYS_HOSTNAME=$(grep "^SYS|HOSTNAME|" "$TOOLKIT_ROOT/.sysref" 2>/dev/null | cut -d'|' -f3)
|
SYS_HOSTNAME=$(grep "^SYS|HOSTNAME|" "$TOOLKIT_ROOT/.sysref" 2>/dev/null | cut -d'|' -f3)
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ source "$TOOLKIT_ROOT/lib/reference-db.sh"
|
|||||||
# Initialize system detection
|
# Initialize system detection
|
||||||
detect_system
|
detect_system
|
||||||
|
|
||||||
|
# Ensure reference database is fresh (only rebuild if > 1 hour old)
|
||||||
|
db_ensure_fresh 2>/dev/null || true
|
||||||
|
|
||||||
# Load system info from reference database
|
# Load system info from reference database
|
||||||
if [ -f "$TOOLKIT_ROOT/.sysref" ]; then
|
if [ -f "$TOOLKIT_ROOT/.sysref" ]; then
|
||||||
SYS_HOSTNAME=$(grep "^SYS|HOSTNAME|" "$TOOLKIT_ROOT/.sysref" 2>/dev/null | cut -d'|' -f3)
|
SYS_HOSTNAME=$(grep "^SYS|HOSTNAME|" "$TOOLKIT_ROOT/.sysref" 2>/dev/null | cut -d'|' -f3)
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ if [ "$EUID" -ne 0 ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ensure reference database is fresh (only rebuild if > 1 hour old)
|
||||||
|
db_ensure_fresh 2>/dev/null || true
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
BACKUP_DIR="/root/nginx-varnish-backups"
|
BACKUP_DIR="/root/nginx-varnish-backups"
|
||||||
VARNISH_VCL="/etc/varnish/default.vcl"
|
VARNISH_VCL="/etc/varnish/default.vcl"
|
||||||
@@ -149,11 +152,28 @@ create_backup() {
|
|||||||
echo "$backup_path"
|
echo "$backup_path"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get list of cPanel domains
|
# Get list of cPanel domains (from launcher cache, not filesystem)
|
||||||
get_cpanel_domains() {
|
get_cpanel_domains() {
|
||||||
|
# Use launcher's cached domain list (instant lookup, already filtered by launcher)
|
||||||
|
# Fallback to filesystem scan only if cache unavailable
|
||||||
|
|
||||||
|
if command -v db_get_all_domains &>/dev/null; then
|
||||||
|
# Use cached data from launcher (built on startup, instant O(n) lookup)
|
||||||
|
db_get_all_domains 2>/dev/null || {
|
||||||
|
# Fallback if cache fails (shouldn't happen if db_ensure_fresh was called)
|
||||||
|
get_cpanel_domains_fallback
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# Library not available, use filesystem fallback
|
||||||
|
get_cpanel_domains_fallback
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fallback domain discovery (only used if cache unavailable)
|
||||||
|
get_cpanel_domains_fallback() {
|
||||||
local domains=()
|
local domains=()
|
||||||
|
|
||||||
# Get domains from cPanel user data
|
# Fallback: Get domains from cPanel user data
|
||||||
if [ -d /var/cpanel/userdata ]; then
|
if [ -d /var/cpanel/userdata ]; then
|
||||||
while IFS= read -r domain_file; do
|
while IFS= read -r domain_file; do
|
||||||
local domain=$(basename "$domain_file")
|
local domain=$(basename "$domain_file")
|
||||||
|
|||||||
@@ -1311,7 +1311,7 @@ calculate_bot_fingerprint() {
|
|||||||
}
|
}
|
||||||
close(tmpdir "/bot_fingerprints.txt")
|
close(tmpdir "/bot_fingerprints.txt")
|
||||||
}
|
}
|
||||||
' < "$TEMP_DIR/parsed_logs.txt"
|
' < "$TEMP_DIR/parsed_logs.txt" 2>/dev/null || true
|
||||||
|
|
||||||
# Create file if empty
|
# Create file if empty
|
||||||
touch "$TEMP_DIR/bot_fingerprints.txt"
|
touch "$TEMP_DIR/bot_fingerprints.txt"
|
||||||
@@ -1997,10 +1997,10 @@ generate_statistics() {
|
|||||||
close(tmpdir "/top_urls_raw.txt")
|
close(tmpdir "/top_urls_raw.txt")
|
||||||
}'
|
}'
|
||||||
|
|
||||||
# Sort and limit results
|
# Sort and limit results (files may not exist if no data)
|
||||||
sort -rn "$TEMP_DIR/top_sites_raw.txt" | head -5 > "$TEMP_DIR/top_sites.txt"
|
[ -f "$TEMP_DIR/top_sites_raw.txt" ] && sort -rn "$TEMP_DIR/top_sites_raw.txt" | head -5 > "$TEMP_DIR/top_sites.txt" || touch "$TEMP_DIR/top_sites.txt"
|
||||||
sort -rn "$TEMP_DIR/top_ips_raw.txt" | head -5 > "$TEMP_DIR/top_ips.txt"
|
[ -f "$TEMP_DIR/top_ips_raw.txt" ] && sort -rn "$TEMP_DIR/top_ips_raw.txt" | head -5 > "$TEMP_DIR/top_ips.txt" || touch "$TEMP_DIR/top_ips.txt"
|
||||||
sort -rn "$TEMP_DIR/top_urls_raw.txt" | head -5 > "$TEMP_DIR/top_urls.txt"
|
[ -f "$TEMP_DIR/top_urls_raw.txt" ] && sort -rn "$TEMP_DIR/top_urls_raw.txt" | head -5 > "$TEMP_DIR/top_urls.txt" || touch "$TEMP_DIR/top_urls.txt"
|
||||||
|
|
||||||
# Top 5 bots by request count (single decompression)
|
# Top 5 bots by request count (single decompression)
|
||||||
cat "$TEMP_DIR/classified_bots.txt" 2>/dev/null | awk -F'|' '$9 != "unknown" {print $10}' | \
|
cat "$TEMP_DIR/classified_bots.txt" 2>/dev/null | awk -F'|' '$9 != "unknown" {print $10}' | \
|
||||||
@@ -2070,7 +2070,7 @@ generate_comparison_report() {
|
|||||||
echo " Baseline (7-day avg): $baseline_requests requests"
|
echo " Baseline (7-day avg): $baseline_requests requests"
|
||||||
echo " Today: $total_requests requests"
|
echo " Today: $total_requests requests"
|
||||||
elif [ "$request_pct" -lt 50 ]; then
|
elif [ "$request_pct" -lt 50 ]; then
|
||||||
echo "🟢 LOW: Requests are $(($((100 - $request_pct))))% below baseline"
|
echo "🟢 LOW: Requests are $((100 - $request_pct))% below baseline"
|
||||||
else
|
else
|
||||||
echo "🟡 NORMAL: Requests within expected range"
|
echo "🟡 NORMAL: Requests within expected range"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -2156,7 +2156,7 @@ for scanner in "${available_scanners[@]}"; do
|
|||||||
# Extract scan results from event log (more reliable than parsing output)
|
# Extract scan results from event log (more reliable than parsing output)
|
||||||
# Maldet logs to /usr/local/maldetect/logs/event_log
|
# Maldet logs to /usr/local/maldetect/logs/event_log
|
||||||
# Use dynamic path search for portability across all platforms (FIXED Issue 2: comprehensive path discovery)
|
# Use dynamic path search for portability across all platforms (FIXED Issue 2: comprehensive path discovery)
|
||||||
local event_log=""
|
event_log=""
|
||||||
|
|
||||||
# Search standard locations in order of likelihood
|
# Search standard locations in order of likelihood
|
||||||
for search_path in \
|
for search_path in \
|
||||||
@@ -2556,7 +2556,7 @@ STANDALONE_EOF
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Inject MALDET_ONLY flag for Maldet-dedicated scans
|
# Inject MALDET_ONLY flag for Maldet-dedicated scans
|
||||||
local maldet_flag="${MALDET_ONLY:-0}"
|
maldet_flag="${MALDET_ONLY:-0}"
|
||||||
if ! sed -i "s|PLACEHOLDER_MALDET_ONLY|$maldet_flag|" "$session_dir/scan.sh"; then
|
if ! sed -i "s|PLACEHOLDER_MALDET_ONLY|$maldet_flag|" "$session_dir/scan.sh"; then
|
||||||
echo -e "${RED}ERROR: Failed to inject MALDET_ONLY flag${NC}"
|
echo -e "${RED}ERROR: Failed to inject MALDET_ONLY flag${NC}"
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -826,11 +826,8 @@ main() {
|
|||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if sysref database exists, build if needed
|
# Ensure reference database is fresh (only rebuild if > 1 hour old)
|
||||||
if [ ! -f "$SYSREF_DB" ] || [ ! -s "$SYSREF_DB" ]; then
|
db_ensure_fresh >/dev/null 2>&1
|
||||||
print_status "Building system reference database (first run)..."
|
|
||||||
build_reference_database >/dev/null 2>&1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Run analysis
|
# Run analysis
|
||||||
check_server_resources
|
check_server_resources
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
#
|
#
|
||||||
# Suspicious Login Monitor - Integrated Security Analysis & Compromise Detection
|
# Suspicious Login Monitor - Integrated Security Analysis & Compromise Detection
|
||||||
@@ -11,6 +12,9 @@
|
|||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
TOOLKIT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
TOOLKIT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
|
||||||
|
# Source reference-db for cache support (avoid redundant /etc/passwd parsing)
|
||||||
|
source "$TOOLKIT_ROOT/lib/reference-db.sh" 2>/dev/null || true
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
SUSPICIOUS_LOGIN_AUTO_BLOCK="${SUSPICIOUS_LOGIN_AUTO_BLOCK:-yes}"
|
SUSPICIOUS_LOGIN_AUTO_BLOCK="${SUSPICIOUS_LOGIN_AUTO_BLOCK:-yes}"
|
||||||
SUSPICIOUS_LOGIN_AUTO_SCAN="${SUSPICIOUS_LOGIN_AUTO_SCAN:-yes}"
|
SUSPICIOUS_LOGIN_AUTO_SCAN="${SUSPICIOUS_LOGIN_AUTO_SCAN:-yes}"
|
||||||
@@ -1673,7 +1677,7 @@ check_maintenance_mode() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$indicators" ]; then
|
if [ -n "$indicators" ]; then
|
||||||
echo "maintenance-mode:$(echo $indicators | sed 's/ $//')"
|
echo "maintenance-mode:$(sed 's/ $//' <<< "$indicators")"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1823,6 +1827,10 @@ check_recent_password_changes() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for locked accounts that were recently unlocked
|
# Check for locked accounts that were recently unlocked
|
||||||
|
# OPTIMIZATION: Read /etc/passwd ONCE, build nologin list, then check against it
|
||||||
|
# (avoiding redundant grep for each user in the loop)
|
||||||
|
local nologin_users=$(awk -F: '/\/sbin\/nologin|\/bin\/false/ {print $1}' /etc/passwd 2>/dev/null | tr '\n' '|')
|
||||||
|
|
||||||
local recently_unlocked=$(awk -F: -v cutoff=$(( $(date +%s) / 86400 - 7 )) '
|
local recently_unlocked=$(awk -F: -v cutoff=$(( $(date +%s) / 86400 - 7 )) '
|
||||||
# Field 2 starts with ! or !! = locked
|
# Field 2 starts with ! or !! = locked
|
||||||
# If field 3 (last change) is recent and field 2 does NOT start with !, might have been unlocked
|
# If field 3 (last change) is recent and field 2 does NOT start with !, might have been unlocked
|
||||||
@@ -1830,8 +1838,8 @@ check_recent_password_changes() {
|
|||||||
print $1
|
print $1
|
||||||
}
|
}
|
||||||
' /etc/shadow 2>/dev/null | while read user; do
|
' /etc/shadow 2>/dev/null | while read user; do
|
||||||
# Check if account was previously locked (this is imperfect without history)
|
# Check if account has nologin shell (from pre-built list)
|
||||||
if grep "^$user:" /etc/passwd | grep -q "/sbin/nologin\|/bin/false"; then
|
if [[ "|$nologin_users" =~ \|$user\| ]]; then
|
||||||
echo "$user"
|
echo "$user"
|
||||||
fi
|
fi
|
||||||
done)
|
done)
|
||||||
@@ -2947,6 +2955,11 @@ main() {
|
|||||||
echo -e "${CYAN}Starting Suspicious Login Monitor...${NC}"
|
echo -e "${CYAN}Starting Suspicious Login Monitor...${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# Ensure cache is fresh (only rebuilds if > 1 hour old)
|
||||||
|
if command -v db_ensure_fresh &>/dev/null; then
|
||||||
|
db_ensure_fresh 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
# Detect panel
|
# Detect panel
|
||||||
local panel=$(detect_panel)
|
local panel=$(detect_panel)
|
||||||
echo "Detected panel: $panel"
|
echo "Detected panel: $panel"
|
||||||
|
|||||||
@@ -1977,18 +1977,18 @@ calculate_performance_score() {
|
|||||||
|
|
||||||
# Calculate score (100 - issues)
|
# Calculate score (100 - issues)
|
||||||
local score=$((100 - (critical_count * 10) - (warning_count * 2)))
|
local score=$((100 - (critical_count * 10) - (warning_count * 2)))
|
||||||
[ $score -lt 0 ] && score=0
|
[ "$score" -lt 0 ] && score=0
|
||||||
[ $score -gt 100 ] && score=100
|
[ "$score" -gt 100 ] && score=100
|
||||||
|
|
||||||
# Determine grade
|
# Determine grade
|
||||||
local grade
|
local grade
|
||||||
if [ $score -ge 90 ]; then
|
if [ "$score" -ge 90 ]; then
|
||||||
grade="A - EXCELLENT"
|
grade="A - EXCELLENT"
|
||||||
elif [ $score -ge 80 ]; then
|
elif [ "$score" -ge 80 ]; then
|
||||||
grade="B - GOOD"
|
grade="B - GOOD"
|
||||||
elif [ $score -ge 70 ]; then
|
elif [ "$score" -ge 70 ]; then
|
||||||
grade="C - FAIR"
|
grade="C - FAIR"
|
||||||
elif [ $score -ge 60 ]; then
|
elif [ "$score" -ge 60 ]; then
|
||||||
grade="D - POOR"
|
grade="D - POOR"
|
||||||
else
|
else
|
||||||
grade="F - CRITICAL"
|
grade="F - CRITICAL"
|
||||||
|
|||||||
@@ -10,14 +10,22 @@ set -o pipefail
|
|||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
CLEANUP_FLAG="/tmp/.cleanup_requested"
|
CLEANUP_FLAG="/tmp/.cleanup_requested"
|
||||||
|
|
||||||
# Save original history setting to restore even if interrupted
|
# Save original history state to restore even if interrupted
|
||||||
HISTORY_SETTING=$(set +o | grep history)
|
HISTORY_STATE="off"
|
||||||
|
if set -o | grep -q "^set +o history" 2>/dev/null; then
|
||||||
|
HISTORY_STATE="on"
|
||||||
|
fi
|
||||||
RESTORE_HISTORY=false
|
RESTORE_HISTORY=false
|
||||||
|
|
||||||
# Cleanup function: restore history even on error/interrupt
|
# Cleanup function: restore history even on error/interrupt
|
||||||
cleanup_on_exit() {
|
cleanup_on_exit() {
|
||||||
if [ "$RESTORE_HISTORY" = true ]; then
|
if [ "$RESTORE_HISTORY" = true ] && [ -n "$HISTORY_STATE" ]; then
|
||||||
eval "$HISTORY_SETTING" 2>/dev/null || true
|
set +H # Disable history expansion temporarily
|
||||||
|
if [ "$HISTORY_STATE" = "on" ]; then
|
||||||
|
set -o history
|
||||||
|
else
|
||||||
|
set +o history
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +67,11 @@ source "$SCRIPT_DIR/launcher.sh"
|
|||||||
LAUNCHER_EXIT=$?
|
LAUNCHER_EXIT=$?
|
||||||
|
|
||||||
# Re-enable history (trap will also do this)
|
# Re-enable history (trap will also do this)
|
||||||
eval "$HISTORY_SETTING" 2>/dev/null || true
|
if [ "$HISTORY_STATE" = "on" ]; then
|
||||||
|
set -o history 2>/dev/null || true
|
||||||
|
else
|
||||||
|
set +o history 2>/dev/null || true
|
||||||
|
fi
|
||||||
RESTORE_HISTORY=false
|
RESTORE_HISTORY=false
|
||||||
|
|
||||||
# Handle cleanup request (if user selected "Clean and remove traces")
|
# Handle cleanup request (if user selected "Clean and remove traces")
|
||||||
|
|||||||
Reference in New Issue
Block a user