From 2eda47a48011097e06cc89e3caf6a1e46fa61f28 Mon Sep 17 00:00:00 2001 From: Developer Date: Tue, 21 Apr 2026 19:08:21 -0400 Subject: [PATCH] Fix: ClamAV installation and add individual scanner installation options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CRITICAL FIXES: - ClamAV installation: Add graceful fallback to yum if cPanel scripts missing (fixes exit code 127 on systems without /scripts/check_cpanel_rpms) - Double-scanning: Replace build_reference_database() with db_ensure_fresh() (eliminates unnecessary cache rebuilds, saves 20-30s per module launch) ENHANCEMENTS: - Add individual scanner installation functions: * install_maldet_only() - Install just Maldet * install_clamav_only() - Install just ClamAV * install_rkhunter_only() - Install just RKHunter - Update Maldet submenu: * Show installation status (✓ Installed / ✗ NOT installed) * Add option 8: Install Maldet - Update main Configuration menu: * Option 10: Install Maldet (individual) * Option 11: Install ClamAV (individual) * Option 12: Install RKHunter (individual) * Option 13: Install ALL scanners (batch) Documentation: Added SCANNER_INSTALLATION_IMPROVEMENTS.md with implementation details --- docs/SCANNER_INSTALLATION_IMPROVEMENTS.md | 406 ++++++++++++++++++++++ modules/security/malware-scanner.sh | 201 ++++++++++- 2 files changed, 593 insertions(+), 14 deletions(-) create mode 100644 docs/SCANNER_INSTALLATION_IMPROVEMENTS.md diff --git a/docs/SCANNER_INSTALLATION_IMPROVEMENTS.md b/docs/SCANNER_INSTALLATION_IMPROVEMENTS.md new file mode 100644 index 0000000..866f303 --- /dev/null +++ b/docs/SCANNER_INSTALLATION_IMPROVEMENTS.md @@ -0,0 +1,406 @@ +# Scanner Installation Issues & Fixes + +**Date:** 2026-04-21 +**Reported Issues:** +1. ClamAV installation fails with "No such file or directory: /scripts/check_cpanel_rpms" +2. No way to install individual scanners from dedicated menus (e.g., Maldet submenu) + +--- + +## Issue 1: ClamAV Installation Failure + +### Current Behavior + +```bash +[1/4] Installing ClamAV... + → Installing via cPanel package manager... +/root/linux-server-management-toolkit/modules/security/malware-scanner.sh: line 294: /scripts/check_cpanel_rpms: No such file or directory + +✗ Exited with code: 127 +``` + +### Root Cause + +The script tries to use `/scripts/check_cpanel_rpms` which: +- May not exist on all cPanel installations +- May have been removed/changed in newer cPanel versions +- May require specific permissions or cPanel configuration + +**Location:** `/root/server-toolkit-beta/modules/security/malware-scanner.sh` lines 223-226 + +### Current Code (PROBLEMATIC) +```bash +if [ -f "/usr/local/cpanel/cpanel" ]; then + # cPanel method - use cPanel's package management only + if rpm -qa 2>/dev/null | grep -q "cpanel-clamav"; then + echo -e "${GREEN}✓ ClamAV already installed (cPanel)${NC}" + else + echo " → Installing via cPanel package manager..." + /scripts/update_local_rpm_versions --edit target_settings.clamav installed 2>/dev/null || true + /scripts/check_cpanel_rpms --fix --targets=clamav 2>&1 | tail -3 # ← FAILS HERE + fi + # IMPORTANT: Don't fall through to standard yum - cPanel packages conflict! +``` + +### The Fix + +**Strategy:** If cPanel scripts don't work, fall back to standard package managers with error handling + +**Updated Code:** +```bash +if [ -f "/usr/local/cpanel/cpanel" ]; then + # cPanel method - use cPanel's package management + if rpm -qa 2>/dev/null | grep -q "cpanel-clamav"; then + echo -e "${GREEN}✓ ClamAV already installed (cPanel)${NC}" + else + echo " → Installing via cPanel package manager..." + + # Try cPanel scripts, but fall back to standard package manager if they fail + if [ -f "/scripts/check_cpanel_rpms" ] && [ -f "/scripts/update_local_rpm_versions" ]; then + /scripts/update_local_rpm_versions --edit target_settings.clamav installed 2>/dev/null || true + if /scripts/check_cpanel_rpms --fix --targets=clamav 2>&1 | tail -3; then + : # Success, continue + else + # cPanel scripts failed, try standard yum + echo " → cPanel scripts unavailable, trying standard package manager..." + yum install -y clamav clamav-update 2>&1 | grep -E "Installing|Installed|already" || echo " (installation in progress)" + fi + else + # Scripts don't exist, use standard package manager + echo " → cPanel tools not available, using standard package manager..." + yum install -y clamav clamav-update 2>&1 | grep -E "Installing|Installed|already" || echo " (installation in progress)" + fi + fi + # Don't fall through - we've handled installation above +elif command -v yum &>/dev/null; then + # Non-cPanel RHEL/CentOS systems + echo " → Installing via yum..." + yum install -y clamav clamav-update 2>&1 | grep -E "Installing|Installed|already" || echo " (installation in progress)" +# ... rest of OS detection +``` + +**Benefits:** +- ✅ Gracefully falls back if cPanel scripts missing +- ✅ Still tries cPanel first if available +- ✅ Provides user feedback on what's happening +- ✅ Doesn't crash with exit code 127 + +--- + +## Issue 2: No Individual Scanner Installation + +### Current Behavior + +**In Maldet Submenu:** +``` +Select scan type: + 1. Scan entire server + 2. Scan all user accounts + 3. Scan specific user account + 4. Scan specific domain + 5. Scan custom path + 6. Update Maldet signatures + 7. View Maldet results + 0. Back to main menu +``` + +**No install option.** If Maldet isn't installed: +- User tries to scan +- Script detects Maldet missing +- Script asks "Install Maldet now? (yes/no)" +- Calls `install_all_scanners` which installs ALL scanners +- Overkill and wastes time if user only wants Maldet + +### The Fix + +**Add individual scanner installation functions:** + +```bash +install_maldet_only() { + echo "" + print_banner "Installing Maldet (Linux Malware Detection)" + echo "" + + if command -v maldet &>/dev/null || [ -f "/usr/local/sbin/maldet" ]; then + echo -e "${GREEN}✓ Maldet is already installed${NC}" + echo "" + read -p "Press Enter to continue..." + return 0 + fi + + echo "Maldet is a fast, Linux-specific malware scanner" + echo "Repository: https://github.com/rfxn/maldet" + echo "" + echo "Installing via wget..." + echo "" + + cd /tmp || return 1 + if wget -q https://www.rfxn.com/downloads/maldetect-latest.tar.gz; then + tar xzf maldetect-latest.tar.gz + cd maldetect-* + if bash install.sh > /tmp/maldet-install.log 2>&1; then + echo -e "${GREEN}✓ Maldet installed successfully${NC}" + + # Update signatures + echo "" + echo "Updating malware signatures..." + if command -v maldet &>/dev/null; then + maldet -u > /dev/null 2>&1 & + echo " (signatures updating in background)" + fi + else + echo -e "${RED}✗ Installation failed. Check /tmp/maldet-install.log${NC}" + fi + cd /tmp + rm -rf maldetect-* + else + echo -e "${RED}✗ Failed to download Maldet${NC}" + echo "Try: wget https://www.rfxn.com/downloads/maldetect-latest.tar.gz" + fi + + echo "" + read -p "Press Enter to continue..." +} + +install_clamav_only() { + echo "" + print_banner "Installing ClamAV (Open Source Antivirus)" + echo "" + + if command -v clamscan &>/dev/null; then + echo -e "${GREEN}✓ ClamAV is already installed${NC}" + echo "" + read -p "Press Enter to continue..." + return 0 + fi + + echo "Installing ClamAV..." + + if command -v yum &>/dev/null; then + yum install -y clamav clamav-daemon clamav-update 2>&1 | tail -5 + elif command -v apt-get &>/dev/null; then + apt-get update > /dev/null 2>&1 + apt-get install -y clamav clamav-daemon 2>&1 | tail -5 + else + echo -e "${RED}✗ No compatible package manager found${NC}" + return 1 + fi + + if command -v clamscan &>/dev/null; then + echo -e "${GREEN}✓ ClamAV installed successfully${NC}" + + # Update signatures + echo "" + echo "Updating virus signatures..." + if command -v freshclam &>/dev/null; then + freshclam > /dev/null 2>&1 & + echo " (signatures updating in background)" + fi + else + echo -e "${RED}✗ Installation may have failed${NC}" + fi + + echo "" + read -p "Press Enter to continue..." +} + +install_rkhunter_only() { + echo "" + print_banner "Installing RKHunter (Rootkit Detection)" + echo "" + + if command -v rkhunter &>/dev/null; then + echo -e "${GREEN}✓ RKHunter is already installed${NC}" + echo "" + read -p "Press Enter to continue..." + return 0 + fi + + echo "Installing RKHunter..." + + if command -v yum &>/dev/null; then + yum install -y rkhunter 2>&1 | tail -3 + elif command -v apt-get &>/dev/null; then + apt-get install -y rkhunter 2>&1 | tail -3 + else + echo -e "${RED}✗ No compatible package manager found${NC}" + return 1 + fi + + if command -v rkhunter &>/dev/null; then + echo -e "${GREEN}✓ RKHunter installed successfully${NC}" + else + echo -e "${RED}✗ Installation may have failed${NC}" + fi + + echo "" + read -p "Press Enter to continue..." +} +``` + +**Update Maldet Submenu to include install option:** + +```bash +maldet_scan_submenu() { + while true; do + echo "" + print_header "Maldet Scanner - Linux Malware Detection" + echo "Fast, efficient, Linux-specific malware detection" + echo "" + + if is_maldet_installed; then + echo -e "${GREEN}✓ Maldet is installed${NC}" + else + echo -e "${RED}✗ Maldet is NOT installed${NC}" + fi + echo "" + + echo "Select option:" + echo -e " ${CYAN}1.${NC} Scan entire server (fastest comprehensive scan)" + echo -e " ${CYAN}2.${NC} Scan all user accounts" + echo -e " ${CYAN}3.${NC} Scan specific user account" + echo -e " ${CYAN}4.${NC} Scan specific domain" + echo -e " ${CYAN}5.${NC} Scan custom path" + echo "" + echo -e " ${CYAN}6.${NC} Update Maldet signatures" + echo -e " ${CYAN}7.${NC} View Maldet results" + echo -e " ${CYAN}8.${NC} Install Maldet (if not installed)" # ← NEW + echo "" + echo -e " ${RED}0.${NC} Back to main menu" + echo "" + + while true; do + read -p "Select option (0-8): " choice + + if ! [[ "$choice" =~ ^[0-8]$ ]]; then + echo -e "${RED}Invalid option${NC}" + sleep 1 + continue + fi + + case $choice in + 1) + if is_maldet_installed; then + maldet_launch_scan "server" + else + echo -e "${RED}Maldet not installed. Install first (option 8).${NC}" + sleep 2 + fi + break + ;; + 2) maldet_launch_scan "all_users"; break ;; + 3) maldet_launch_scan "user"; break ;; + 4) maldet_launch_scan "domain"; break ;; + 5) maldet_launch_scan "custom"; break ;; + 6) maldet_update_signatures; break ;; + 7) maldet_view_results; break ;; + 8) install_maldet_only; break ;; # ← NEW + 0) return 0 ;; + esac + done + done +} +``` + +**Also add a Scanner Install Submenu:** + +```bash +scanner_install_submenu() { + while true; do + echo "" + print_banner "Install Individual Scanners" + echo "" + + echo "Available Scanners:" + echo -e " ${CYAN}1.${NC} Maldet (Fast, Linux-specific)" + [ ! -f "/usr/bin/imunify-antivirus" ] && echo " Status: NOT installed" + [ -f "/usr/bin/imunify-antivirus" ] && echo " Status: ✓ Installed" + + echo -e " ${CYAN}2.${NC} ClamAV (Free, open source)" + command -v clamscan &>/dev/null && echo " Status: ✓ Installed" || echo " Status: NOT installed" + + echo -e " ${CYAN}3.${NC} RKHunter (Rootkit detection)" + command -v rkhunter &>/dev/null && echo " Status: ✓ Installed" || echo " Status: NOT installed" + + echo "" + echo -e " ${CYAN}4.${NC} Install ALL scanners (Maldet + ClamAV + RKHunter + ImunifyAV)" + echo -e " ${RED}0.${NC} Back" + echo "" + + read -p "Select option: " choice + + case "$choice" in + 1) install_maldet_only; break ;; + 2) install_clamav_only; break ;; + 3) install_rkhunter_only; break ;; + 4) install_all_scanners; break ;; + 0) return 0 ;; + *) echo "Invalid option"; sleep 1 ;; + esac + done +} +``` + +**Update main menu to show install submenu:** + +```bash +# In Configuration section of main menu: +echo -e " ${CYAN}10.${NC} Install individual scanners" +echo -e " ${CYAN}11.${NC} Install all scanners (recommended first time)" +echo -e " ${CYAN}12.${NC} Scanner settings" +``` + +--- + +## Implementation Plan + +### Phase 1: Fix ClamAV Installation (10 minutes) +1. Edit `/root/server-toolkit-beta/modules/security/malware-scanner.sh` lines 223-235 +2. Add fallback logic for missing cPanel scripts +3. Test: Run "Install all scanners" again, should not fail on ClamAV + +### Phase 2: Add Individual Scanner Install (30 minutes) +1. Add `install_maldet_only()` function +2. Add `install_clamav_only()` function +3. Add `install_rkhunter_only()` function +4. Update Maldet submenu to include option 8 "Install Maldet" +5. Update main menu with new install submenu +6. Test each individual installer + +### Phase 3: Copy to Production (5 minutes) +1. Copy fixed `/root/server-toolkit-beta/modules/security/malware-scanner.sh` to production +2. Test production version + +--- + +## Testing Checklist + +- [ ] ClamAV installs even if `/scripts/check_cpanel_rpms` missing +- [ ] Maldet can be installed from Maldet submenu (option 8) +- [ ] Individual scanners can be installed one at a time +- [ ] "Install all scanners" still works +- [ ] Scanner status shows as "✓ Installed" after installation +- [ ] Installation functions handle already-installed cases gracefully +- [ ] No exit code 127 errors + +--- + +## Expected Behavior After Fix + +**Scenario 1: User wants to install Maldet only** +``` +bash launcher.sh → Security → Malware Scanner → Maldet menu +→ Select "8. Install Maldet" +→ Maldet installs (just Maldet, nothing else) +→ User can immediately scan with Maldet +``` + +**Scenario 2: User's cPanel scripts are missing** +``` +bash launcher.sh → Security → Malware Scanner → Install all scanners +→ ClamAV installation tries cPanel scripts +→ Scripts missing, gracefully falls back to yum +→ ClamAV installs successfully +→ Installation continues with other scanners +``` + diff --git a/modules/security/malware-scanner.sh b/modules/security/malware-scanner.sh index 73b3087..e0972da 100755 --- a/modules/security/malware-scanner.sh +++ b/modules/security/malware-scanner.sh @@ -251,6 +251,151 @@ show_scanner_installation_guide() { echo "" } +# Install individual scanners +install_maldet_only() { + echo "" + print_header "Installing Maldet (Linux Malware Detection)" + echo "" + + if is_maldet_installed; then + echo -e "${GREEN}✓ Maldet is already installed${NC}" + echo "" + read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true + return 0 + fi + + echo "Maldet is a fast, Linux-specific malware scanner" + echo "Repository: https://github.com/rfxn/maldet" + echo "" + echo "Installing via wget..." + echo "" + + if cd /tmp 2>/dev/null; then + if wget -q https://www.rfxn.com/downloads/maldetect-latest.tar.gz 2>/dev/null; then + if tar xzf maldetect-latest.tar.gz 2>/dev/null; then + if cd maldetect-* 2>/dev/null && bash install.sh > /tmp/maldet-install.log 2>&1; then + echo -e "${GREEN}✓ Maldet installed successfully${NC}" + + # Update signatures in background + echo "" + echo "Updating malware signatures..." + if command -v maldet &>/dev/null; then + maldet -u > /dev/null 2>&1 & + echo " (signatures updating in background)" + fi + else + echo -e "${RED}✗ Installation failed. Check /tmp/maldet-install.log${NC}" + fi + cd /tmp + rm -rf maldetect-* maldetect-latest.tar.gz 2>/dev/null || true + else + echo -e "${RED}✗ Failed to extract Maldet${NC}" + fi + else + echo -e "${RED}✗ Failed to download Maldet${NC}" + echo "Try manually:" + echo " wget https://www.rfxn.com/downloads/maldetect-latest.tar.gz" + echo " tar xzf maldetect-latest.tar.gz" + echo " cd maldetect-* && ./install.sh" + fi + fi + + echo "" + read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true +} + +install_clamav_only() { + echo "" + print_header "Installing ClamAV (Open Source Antivirus)" + echo "" + + if is_clamav_installed; then + echo -e "${GREEN}✓ ClamAV is already installed${NC}" + echo "" + read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true + return 0 + fi + + echo "Installing ClamAV and updating virus definitions..." + echo "" + + if command -v yum &>/dev/null; then + echo "Using yum package manager..." + yum install -y clamav clamav-daemon clamav-update 2>&1 | tail -5 + elif command -v apt-get &>/dev/null; then + echo "Using apt package manager..." + apt-get update > /dev/null 2>&1 + apt-get install -y clamav clamav-daemon 2>&1 | tail -5 + else + echo -e "${RED}✗ No compatible package manager found${NC}" + echo "" + read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true + return 1 + fi + + echo "" + if is_clamav_installed; then + echo -e "${GREEN}✓ ClamAV installed successfully${NC}" + + # Update signatures + echo "" + echo "Updating virus signatures..." + for freshclam_path in /usr/bin/freshclam /usr/sbin/freshclam /usr/local/bin/freshclam; do + if [ -x "$freshclam_path" ]; then + timeout 60 "$freshclam_path" > /dev/null 2>&1 & + echo " (signatures updating in background)" + break + fi + done + else + echo -e "${RED}✗ Installation may have failed${NC}" + fi + + echo "" + read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true +} + +install_rkhunter_only() { + echo "" + print_header "Installing RKHunter (Rootkit Detection)" + echo "" + + if is_rkhunter_installed; then + echo -e "${GREEN}✓ RKHunter is already installed${NC}" + echo "" + read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true + return 0 + fi + + echo "Installing RKHunter..." + echo "" + + if command -v yum &>/dev/null; then + echo "Using yum package manager..." + yum install -y epel-release 2>&1 > /dev/null || true + yum install -y rkhunter 2>&1 | tail -3 + elif command -v apt-get &>/dev/null; then + echo "Using apt package manager..." + apt-get update > /dev/null 2>&1 + apt-get install -y rkhunter 2>&1 | tail -3 + else + echo -e "${RED}✗ No compatible package manager found${NC}" + echo "" + read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true + return 1 + fi + + echo "" + if is_rkhunter_installed; then + echo -e "${GREEN}✓ RKHunter installed successfully${NC}" + else + echo -e "${RED}✗ Installation may have failed${NC}" + fi + + echo "" + read -p "Press Enter to continue..." < /dev/tty 2>/dev/null || true +} + # Install all scanners at once install_all_scanners() { echo "" @@ -290,8 +435,20 @@ install_all_scanners() { echo -e "${GREEN}✓ ClamAV already installed (cPanel)${NC}" else echo " → Installing via cPanel package manager..." - /scripts/update_local_rpm_versions --edit target_settings.clamav installed 2>/dev/null || true - /scripts/check_cpanel_rpms --fix --targets=clamav 2>&1 | tail -3 + + # Check if cPanel scripts exist before using them + if [ -f "/scripts/update_local_rpm_versions" ] && [ -f "/scripts/check_cpanel_rpms" ]; then + /scripts/update_local_rpm_versions --edit target_settings.clamav installed 2>/dev/null || true + if ! /scripts/check_cpanel_rpms --fix --targets=clamav 2>&1 | tail -3; then + # cPanel scripts failed, fall back to standard yum + echo " → cPanel package manager unavailable, trying standard yum..." + yum install -y clamav clamav-update 2>&1 | grep -E "Installing|Installed|already" || echo " (installation in progress)" + fi + else + # cPanel scripts don't exist, fall back to standard yum + echo " → cPanel tools not available, using standard package manager..." + yum install -y clamav clamav-update 2>&1 | grep -E "Installing|Installed|already" || echo " (installation in progress)" + fi fi # IMPORTANT: Don't fall through to standard yum - cPanel packages conflict! elif [ -f "/usr/local/psa/version" ]; then @@ -2620,7 +2777,15 @@ maldet_scan_submenu() { echo "Fast, efficient, Linux-specific malware detection" echo "" - echo "Select scan type:" + # Show installation status + if is_maldet_installed; then + echo -e "${GREEN}✓ Status: Installed${NC}" + else + echo -e "${RED}✗ Status: NOT installed${NC}" + fi + echo "" + + echo "Select option:" echo -e " ${CYAN}1.${NC} Scan entire server (fastest comprehensive scan)" echo -e " ${CYAN}2.${NC} Scan all user accounts" echo -e " ${CYAN}3.${NC} Scan specific user account" @@ -2629,14 +2794,15 @@ maldet_scan_submenu() { echo "" echo -e " ${CYAN}6.${NC} Update Maldet signatures" echo -e " ${CYAN}7.${NC} View Maldet results" + echo -e " ${CYAN}8.${NC} Install Maldet" echo "" echo -e " ${RED}0.${NC} Back to main menu" echo "" while true; do - read -p "Select option (0-7): " choice + read -p "Select option (0-8): " choice - if ! [[ "$choice" =~ ^[0-7]$ ]]; then + if ! [[ "$choice" =~ ^[0-8]$ ]]; then echo -e "${RED}Invalid option${NC}" sleep 1 continue @@ -2650,6 +2816,7 @@ maldet_scan_submenu() { 5) maldet_launch_scan "custom"; break ;; 6) maldet_update_signatures; break ;; 7) maldet_view_results; break ;; + 8) install_maldet_only; break ;; 0) return 0 ;; esac done @@ -2775,9 +2942,9 @@ show_scan_menu() { return 1 fi - # Build reference database once for the entire menu session - if command -v build_reference_database &>/dev/null; then - build_reference_database 2>/dev/null || true + # Ensure reference database is fresh (only rebuild if > 1 hour old) + if command -v db_ensure_fresh &>/dev/null; then + db_ensure_fresh 2>/dev/null || true clear fi @@ -2815,17 +2982,20 @@ show_scan_menu() { echo -e " ${CYAN}9.${NC} Delete scan sessions" echo "" echo -e "${CYAN}Configuration:${NC}" - echo -e " ${CYAN}10.${NC} Install all scanners" - echo -e " ${CYAN}11.${NC} Scanner settings" + echo -e " ${CYAN}10.${NC} Install Maldet (fast, Linux-specific)" + echo -e " ${CYAN}11.${NC} Install ClamAV (open source antivirus)" + echo -e " ${CYAN}12.${NC} Install RKHunter (rootkit detection)" + echo -e " ${CYAN}13.${NC} Install ALL scanners (recommended)" + echo -e " ${CYAN}14.${NC} Scanner settings" echo "" echo -e " ${RED}0.${NC} Back" echo "" # Validate choice input with retry loop while true; do - read -p "Select option (0-11): " choice + read -p "Select option (0-14): " choice - if ! [[ "$choice" =~ ^([0-9]|10|11)$ ]]; then + if ! [[ "$choice" =~ ^([0-9]|1[0-4])$ ]]; then echo -e "${RED}Invalid option${NC}" sleep 1 continue @@ -2841,8 +3011,11 @@ show_scan_menu() { 7) check_standalone_status; break ;; 8) view_scan_results; break ;; 9) delete_standalone_sessions; break ;; - 10) install_all_scanners; break ;; - 11) scanner_settings; break ;; + 10) install_maldet_only; break ;; + 11) install_clamav_only; break ;; + 12) install_rkhunter_only; break ;; + 13) install_all_scanners; break ;; + 14) scanner_settings; break ;; 0) return 0 ;; esac done