Compare commits
6 Commits
179ae9dbc9
...
ade33f0257
| Author | SHA1 | Date | |
|---|---|---|---|
| ade33f0257 | |||
| c0dc917a84 | |||
| bc4c8104a7 | |||
| 66b797286e | |||
| 200b992cb6 | |||
| d31dcf63e1 |
+4
-2
@@ -91,7 +91,7 @@ show_main_menu() {
|
||||
echo ""
|
||||
echo -e " ${GREEN}2)${NC} 🛡️ Security & Monitoring"
|
||||
echo -e " ${BLUE}3)${NC} 🌐 Website Diagnostics"
|
||||
echo -e " ${MAGENTA}4)${NC} 🔧 Performance Analysis"
|
||||
echo -e " ${MAGENTA}4)${NC} 🔧 Performance & Maintenance"
|
||||
echo -e " ${YELLOW}5)${NC} 💾 Backup & Recovery"
|
||||
echo ""
|
||||
echo -e "${BOLD}System:${NC}"
|
||||
@@ -221,7 +221,7 @@ handle_website_menu() {
|
||||
|
||||
show_performance_menu() {
|
||||
show_banner
|
||||
echo -e "${MAGENTA}${BOLD}🔧 Performance Analysis${NC}"
|
||||
echo -e "${MAGENTA}${BOLD}🔧 Performance & Maintenance${NC}"
|
||||
echo ""
|
||||
echo -e "${BOLD}Database:${NC}"
|
||||
echo ""
|
||||
@@ -239,6 +239,7 @@ show_performance_menu() {
|
||||
echo -e "${BOLD}System Health:${NC}"
|
||||
echo ""
|
||||
echo -e " ${MAGENTA}5)${NC} 📊 Loadwatch Health Analyzer - Historical system analysis"
|
||||
echo -e " ${MAGENTA}6)${NC} 💿 Disk Space Analyzer - Find space issues & cleanup files"
|
||||
echo ""
|
||||
echo -e " ${RED}0)${NC} Back to Main Menu"
|
||||
echo ""
|
||||
@@ -257,6 +258,7 @@ handle_performance_menu() {
|
||||
3) run_module "performance" "hardware-health-check.sh" ;;
|
||||
4) run_module "performance" "php-optimizer.sh" ;;
|
||||
5) handle_loadwatch_analyzer ;;
|
||||
6) run_module "maintenance" "disk-space-analyzer.sh" ;;
|
||||
0) return ;;
|
||||
*) echo -e "${RED}Invalid option${NC}"; sleep 1 ;;
|
||||
esac
|
||||
|
||||
Executable
+1320
File diff suppressed because it is too large
Load Diff
@@ -571,6 +571,47 @@ log_message() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$SESSION_LOG"
|
||||
}
|
||||
|
||||
# Cleanup function for trap handler
|
||||
cleanup_on_exit() {
|
||||
local exit_code=$?
|
||||
echo ""
|
||||
|
||||
# Only log if session log exists
|
||||
if [ -f "$SESSION_LOG" ]; then
|
||||
log_message "Cleanup triggered (exit code: $exit_code)"
|
||||
fi
|
||||
|
||||
# Remove temporarily installed RKHunter
|
||||
if [ "${RKHUNTER_TEMP_INSTALLED:-false}" = "true" ]; then
|
||||
if [ -f "$SESSION_LOG" ]; then
|
||||
log_message "Removing temporarily installed RKHunter..."
|
||||
fi
|
||||
echo "→ Cleaning up: Removing Rootkit Hunter..."
|
||||
if command -v yum &>/dev/null; then
|
||||
yum remove -y rkhunter &>/dev/null 2>&1
|
||||
if [ -f "$SESSION_LOG" ]; then
|
||||
log_message "RKHunter removed"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Save interrupted status (only if summary file directory exists)
|
||||
if [ $exit_code -ne 0 ] && [ -d "$RESULTS_DIR" ]; then
|
||||
{
|
||||
echo ""
|
||||
echo "SCAN INTERRUPTED"
|
||||
echo "Exit code: $exit_code"
|
||||
echo "Time: $(date)"
|
||||
} >> "$SUMMARY_FILE"
|
||||
if [ -f "$SESSION_LOG" ]; then
|
||||
log_message "Scan interrupted with exit code: $exit_code"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Set trap for cleanup on exit, interrupt, or termination
|
||||
trap cleanup_on_exit EXIT INT TERM
|
||||
|
||||
# Banner
|
||||
clear
|
||||
echo "========================================"
|
||||
@@ -646,7 +687,54 @@ log_message "Found ${#AVAILABLE_SCANNERS[@]} scanner(s): ${AVAILABLE_SCANNERS[*]
|
||||
SCAN_PATHS=()
|
||||
PLACEHOLDER_SCAN_PATHS
|
||||
|
||||
log_message "Scanning ${#SCAN_PATHS[@]} path(s)"
|
||||
# Validate scan paths
|
||||
log_message "Validating scan paths..."
|
||||
VALID_PATHS=()
|
||||
for path in "${SCAN_PATHS[@]}"; do
|
||||
if [ -e "$path" ]; then
|
||||
if [ -r "$path" ]; then
|
||||
VALID_PATHS+=("$path")
|
||||
log_message "✓ Valid path: $path"
|
||||
else
|
||||
log_message "WARNING: Path not readable: $path (skipping)"
|
||||
echo "⚠️ WARNING: Cannot read $path (permission denied) - skipping"
|
||||
fi
|
||||
else
|
||||
log_message "WARNING: Path does not exist: $path (skipping)"
|
||||
echo "⚠️ WARNING: Path does not exist: $path - skipping"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#VALID_PATHS[@]} -eq 0 ]; then
|
||||
log_message "ERROR: No valid paths to scan!"
|
||||
echo -e "${RED}ERROR: No valid paths to scan!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use only valid paths
|
||||
SCAN_PATHS=("${VALID_PATHS[@]}")
|
||||
log_message "Scanning ${#SCAN_PATHS[@]} valid path(s)"
|
||||
|
||||
# Check available disk space for logs
|
||||
log_message "Checking disk space..."
|
||||
SCAN_DIR_FS=$(df -P "$SCAN_DIR" | tail -1 | awk '{print $6}')
|
||||
AVAILABLE_KB=$(df -P "$SCAN_DIR" | tail -1 | awk '{print $4}')
|
||||
AVAILABLE_MB=$((AVAILABLE_KB / 1024))
|
||||
|
||||
if [ "$AVAILABLE_MB" -lt 100 ]; then
|
||||
log_message "WARNING: Low disk space ($AVAILABLE_MB MB available)"
|
||||
echo "⚠️ WARNING: Low disk space on $SCAN_DIR_FS ($AVAILABLE_MB MB available)"
|
||||
echo "Scan logs may be large. Recommend at least 100 MB free space."
|
||||
echo ""
|
||||
read -t 10 -p "Continue anyway? (y/N): " continue_scan
|
||||
if [[ ! "$continue_scan" =~ ^[Yy]$ ]]; then
|
||||
log_message "Scan cancelled due to low disk space"
|
||||
echo "Scan cancelled."
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
log_message "Disk space OK: $AVAILABLE_MB MB available"
|
||||
fi
|
||||
|
||||
# Initialize summary
|
||||
{
|
||||
@@ -673,8 +761,12 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
|
||||
SCANNER_NUM=$((SCANNERS_COMPLETED + 1))
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}[$SCANNER_NUM/$TOTAL_SCANNERS] Starting ${scanner^} scan...${NC}"
|
||||
log_message "Starting ${scanner} scan"
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo -e "${CYAN}${BOLD}Scanner $SCANNER_NUM of $TOTAL_SCANNERS: ${scanner^}${NC}"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
log_message "Starting ${scanner} scan ($SCANNER_NUM/$TOTAL_SCANNERS)"
|
||||
|
||||
{
|
||||
echo "Scanner: ${scanner^}"
|
||||
@@ -686,11 +778,16 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
|
||||
imunify)
|
||||
SCAN_START=$(date +%s)
|
||||
log_message "ImunifyAV: Updating signatures"
|
||||
imunify-antivirus update &>> "$LOG_DIR/imunify.log"
|
||||
|
||||
if ! imunify-antivirus update &>> "$LOG_DIR/imunify.log"; then
|
||||
log_message "WARNING: ImunifyAV update failed (continuing with existing signatures)"
|
||||
echo "⚠️ WARNING: Signature update failed, using existing signatures"
|
||||
fi
|
||||
|
||||
log_message "ImunifyAV: Starting on-demand scan (synchronous)"
|
||||
|
||||
# Use on-demand start (synchronous) instead of queue (asynchronous)
|
||||
LAST_SCAN=""
|
||||
for path in "${SCAN_PATHS[@]}"; do
|
||||
if [ -d "$path" ]; then
|
||||
log_message "ImunifyAV: Scanning $path"
|
||||
@@ -698,7 +795,11 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
|
||||
echo " 📁 Scanning path: $path"
|
||||
echo " ⏳ Scanner: ImunifyAV (this may take several minutes...)"
|
||||
|
||||
imunify-antivirus malware on-demand start --path="$path" &>> "$LOG_DIR/imunify.log"
|
||||
if ! imunify-antivirus malware on-demand start --path="$path" &>> "$LOG_DIR/imunify.log"; then
|
||||
log_message "ERROR: ImunifyAV scan failed for $path"
|
||||
echo " ✗ Scan failed for $path (check logs)"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Get scan results from most recent scan (newest scans are at top)
|
||||
# Skip header line (tail -n +2), then get first data line (head -1)
|
||||
@@ -715,7 +816,11 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
|
||||
|
||||
# Extract malicious file count
|
||||
# Skip header line and count data rows, or use TOTAL_MALICIOUS from most recent scan
|
||||
IMUNIFY_INFECTED=$(echo "$LAST_SCAN" | awk '{print $12}')
|
||||
if [ -n "$LAST_SCAN" ]; then
|
||||
IMUNIFY_INFECTED=$(echo "$LAST_SCAN" | awk '{print $12}')
|
||||
else
|
||||
IMUNIFY_INFECTED=0
|
||||
fi
|
||||
# Verify we got a valid number, otherwise try malicious list
|
||||
if ! [[ "$IMUNIFY_INFECTED" =~ ^[0-9]+$ ]]; then
|
||||
IMUNIFY_INFECTED=$(imunify-antivirus malware malicious list 2>/dev/null | tail -n +2 | wc -l || echo 0)
|
||||
@@ -733,7 +838,10 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
|
||||
SCAN_START=$(date +%s)
|
||||
if command -v freshclam &>/dev/null; then
|
||||
log_message "ClamAV: Updating signatures"
|
||||
freshclam &>> "$LOG_DIR/clamav.log"
|
||||
if ! freshclam &>> "$LOG_DIR/clamav.log"; then
|
||||
log_message "WARNING: ClamAV signature update failed (continuing with existing signatures)"
|
||||
echo "⚠️ WARNING: Signature update failed, using existing signatures"
|
||||
fi
|
||||
fi
|
||||
|
||||
log_message "ClamAV: Starting scan"
|
||||
@@ -741,7 +849,19 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
|
||||
echo " 📁 Scanning path(s): ${SCAN_PATHS[*]}"
|
||||
echo " ⏳ Scanner: ClamAV (comprehensive virus scan...)"
|
||||
|
||||
# ClamAV returns 1 if infected files found, 0 if clean, >1 for errors
|
||||
clamscan --infected --recursive "${SCAN_PATHS[@]}" &>> "$LOG_DIR/clamav.log"
|
||||
CLAM_EXIT=$?
|
||||
|
||||
if [ "$CLAM_EXIT" -gt 1 ]; then
|
||||
log_message "ERROR: ClamAV scan failed with exit code $CLAM_EXIT"
|
||||
echo " ✗ Scan failed (exit code: $CLAM_EXIT) - check logs"
|
||||
echo "ClamAV scan failed (exit code: $CLAM_EXIT)" >> "$SUMMARY_FILE"
|
||||
SCAN_END=$(date +%s)
|
||||
DURATION=$((SCAN_END - SCAN_START))
|
||||
echo ""
|
||||
continue
|
||||
fi
|
||||
|
||||
# Extract infected files
|
||||
grep "FOUND" "$LOG_DIR/clamav.log" | cut -d: -f1 >> "$INFECTED_LIST" 2>/dev/null
|
||||
@@ -767,7 +887,11 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
|
||||
maldet)
|
||||
SCAN_START=$(date +%s)
|
||||
log_message "Maldet: Updating signatures"
|
||||
maldet -u &>> "$LOG_DIR/maldet.log"
|
||||
|
||||
if ! maldet -u &>> "$LOG_DIR/maldet.log"; then
|
||||
log_message "WARNING: Maldet signature update failed (continuing with existing signatures)"
|
||||
echo "⚠️ WARNING: Signature update failed, using existing signatures"
|
||||
fi
|
||||
|
||||
# Create temp path list
|
||||
TEMP_PATHLIST="/tmp/maldet_paths_$$.txt"
|
||||
@@ -778,7 +902,16 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
|
||||
echo " 📁 Scanning path(s): ${SCAN_PATHS[*]}"
|
||||
echo " ⏳ Scanner: Maldet/LMD (Linux-specific malware detection...)"
|
||||
|
||||
maldet -b -f "$TEMP_PATHLIST" &>> "$LOG_DIR/maldet.log"
|
||||
if ! maldet -b -f "$TEMP_PATHLIST" &>> "$LOG_DIR/maldet.log"; then
|
||||
log_message "ERROR: Maldet scan failed"
|
||||
echo " ✗ Scan failed - check logs"
|
||||
echo "Maldet scan failed" >> "$SUMMARY_FILE"
|
||||
rm -f "$TEMP_PATHLIST"
|
||||
SCAN_END=$(date +%s)
|
||||
DURATION=$((SCAN_END - SCAN_START))
|
||||
echo ""
|
||||
continue
|
||||
fi
|
||||
|
||||
# Extract scan results
|
||||
FILES_SCANNED=$(grep "files scanned" "$LOG_DIR/maldet.log" | tail -1 | awk '{print $1}')
|
||||
@@ -806,7 +939,11 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
|
||||
rkhunter)
|
||||
SCAN_START=$(date +%s)
|
||||
log_message "RKHunter: Updating definitions"
|
||||
rkhunter --update &>> "$LOG_DIR/rkhunter.log"
|
||||
|
||||
if ! rkhunter --update &>> "$LOG_DIR/rkhunter.log"; then
|
||||
log_message "WARNING: RKHunter update failed (continuing with existing definitions)"
|
||||
echo "⚠️ WARNING: Definition update failed, using existing definitions"
|
||||
fi
|
||||
|
||||
log_message "RKHunter: Starting scan"
|
||||
echo ""
|
||||
@@ -816,7 +953,14 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
|
||||
# --check: Run all checks
|
||||
# --skip-keypress: Don't wait for user input
|
||||
# --report-warnings-only: Only show warnings/issues
|
||||
# Note: rkhunter may return non-zero even on successful scan with warnings
|
||||
rkhunter --check --skip-keypress --report-warnings-only &>> "$LOG_DIR/rkhunter.log"
|
||||
RKH_EXIT=$?
|
||||
|
||||
if [ "$RKH_EXIT" -gt 1 ] && [ "$RKH_EXIT" -ne 127 ]; then
|
||||
log_message "WARNING: RKHunter scan completed with exit code $RKH_EXIT"
|
||||
echo " ⚠️ Scan completed with warnings (exit code: $RKH_EXIT)"
|
||||
fi
|
||||
|
||||
# Extract warnings
|
||||
RKH_WARNINGS=$(grep -c "Warning:" "$LOG_DIR/rkhunter.log" 2>/dev/null || echo 0)
|
||||
@@ -985,19 +1129,7 @@ echo ""
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Cleanup: Remove rkhunter if it was temporarily installed
|
||||
if [ "$RKHUNTER_TEMP_INSTALLED" = "true" ]; then
|
||||
log_message "Removing temporarily installed RKHunter..."
|
||||
echo "→ Cleaning up: Removing Rootkit Hunter..."
|
||||
if command -v yum &>/dev/null; then
|
||||
yum remove -y rkhunter &>/dev/null
|
||||
echo " ✓ RKHunter removed"
|
||||
log_message "RKHunter successfully removed"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Prompt for cleanup
|
||||
# Prompt for cleanup (RKHunter cleanup handled by trap)
|
||||
read -p "Delete scan script? (Logs and results will be preserved) (yes/no): " cleanup_choice
|
||||
|
||||
if [ "$cleanup_choice" = "yes" ]; then
|
||||
@@ -1512,8 +1644,15 @@ delete_standalone_sessions() {
|
||||
;;
|
||||
*)
|
||||
# Delete specific session
|
||||
# Validate numeric input
|
||||
if ! [[ "$delete_choice" =~ ^[0-9]+$ ]]; then
|
||||
echo -e "${RED}Invalid choice (must be a number)${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$delete_choice" -lt 1 ] || [ "$delete_choice" -gt ${#standalone_dirs[@]} ]; then
|
||||
echo -e "${RED}Invalid choice${NC}"
|
||||
echo -e "${RED}Invalid choice (out of range)${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
return 1
|
||||
fi
|
||||
@@ -1634,8 +1773,15 @@ view_scan_results() {
|
||||
|
||||
read -p "Scanner: " scanner_choice
|
||||
|
||||
# Validate numeric input
|
||||
if ! [[ "$scanner_choice" =~ ^[0-9]+$ ]]; then
|
||||
echo -e "${RED}Invalid choice (must be a number)${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$scanner_choice" -lt 1 ] || [ "$scanner_choice" -gt ${#available_scanners[@]} ]; then
|
||||
echo -e "${RED}Invalid choice${NC}"
|
||||
echo -e "${RED}Invalid choice (out of range)${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
return 1
|
||||
fi
|
||||
@@ -1695,12 +1841,19 @@ view_scan_results() {
|
||||
|
||||
read -p "Select session (or 0 to cancel): " session_choice
|
||||
|
||||
# Validate numeric input
|
||||
if ! [[ "$session_choice" =~ ^[0-9]+$ ]]; then
|
||||
echo -e "${RED}Invalid choice (must be a number)${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$session_choice" = "0" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$session_choice" -lt 1 ] || [ "$session_choice" -gt ${#standalone_dirs[@]} ]; then
|
||||
echo -e "${RED}Invalid choice${NC}"
|
||||
echo -e "${RED}Invalid choice (out of range)${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
return 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user