diff --git a/lib/system-detect.sh b/lib/system-detect.sh index 9a8f921..64f3ed7 100755 --- a/lib/system-detect.sh +++ b/lib/system-detect.sh @@ -106,7 +106,7 @@ detect_control_panel() { SYS_USER_HOME_BASE="/home" print_warning "No control panel detected (standalone server)" - return 1 + return 0 } ############################################################################# diff --git a/modules/security/malware-scanner.sh b/modules/security/malware-scanner.sh index 2a2968b..d338b53 100755 --- a/modules/security/malware-scanner.sh +++ b/modules/security/malware-scanner.sh @@ -385,69 +385,191 @@ install_all_scanners() { echo -e "${CYAN}[3/4] Installing ImunifyAV (FREE)...${NC}" echo " This may take several minutes - please wait..." - # Use deployment script method (most reliable) - cd /tmp - if [ -f "imav-deploy.sh" ]; then - rm -f imav-deploy.sh + # ── STANDALONE DETECTION ───────────────────────────────────────── + # Detect whether this is a standalone system (no cPanel, no Plesk). + # InterWorx is also treated as standalone for ImunifyAV purposes + # because imav-deploy.sh does not recognise it as a "panel". + local imav_is_standalone=0 + if [ ! -f "/usr/local/cpanel/cpanel" ] && [ ! -f "/usr/local/psa/version" ]; then + imav_is_standalone=1 fi - # Download deployment script with timeout - if timeout 30 wget -q -O imav-deploy.sh https://repo.imunify360.cloudlinux.com/defence360/imav-deploy.sh 2>/dev/null; then - if [ ! -f imav-deploy.sh ] || [ ! -s imav-deploy.sh ]; then - echo -e "${RED} Failed to download installation script (empty file)${NC}" + # ── STANDALONE: INTEGRATION.CONF SETUP ─────────────────────────── + if [ "$imav_is_standalone" -eq 1 ]; then + echo "" + echo -e "${YELLOW} ⚠ Standalone system detected (no cPanel or Plesk found)${NC}" + echo " ImunifyAV requires a web server path for its UI on standalone systems." + echo "" + + local imav_conf_dir="/etc/sysconfig/imunify360" + local imav_conf_file="$imav_conf_dir/integration.conf" + local imav_ui_path="" + + # Check if integration.conf already exists with ui_path set + if [ -f "$imav_conf_file" ] && grep -q "^ui_path" "$imav_conf_file" 2>/dev/null; then + # Already configured - read existing value for display only + imav_ui_path=$(grep "^ui_path" "$imav_conf_file" | head -1 | cut -d'=' -f2 | tr -d ' ') + echo -e " ${GREEN}✓${NC} integration.conf already exists with ui_path: $imav_ui_path" + echo " Proceeding with existing configuration." else - # Run deployment script with timeout and capture output - echo " → Running deployment script..." - local deploy_log="/tmp/imav-deploy-$$.log" - if timeout 300 bash imav-deploy.sh > "$deploy_log" 2>&1; then - # Check if any actual installation happened - if grep -qiE "installed|complete|success" "$deploy_log"; then - echo " → Deployment script executed" + # Prompt user for ui_path with sensible default + echo " Enter the web server document root path for the ImunifyAV UI." + echo " This directory will be served by your web server (Apache/Nginx)." + echo " Example: /var/www/html/imunifyav" + echo " Enter 0 to cancel ImunifyAV installation." + echo "" + read -p " ui_path [/var/www/html/imunifyav]: " imav_ui_input + + # Handle cancel + if [ "$imav_ui_input" = "0" ]; then + echo " → Skipping ImunifyAV installation." + # Jump past the download/deploy block entirely + imav_is_standalone=2 + fi + + if [ "$imav_is_standalone" -ne 2 ]; then + # Apply default if blank + if [ -z "$imav_ui_input" ]; then + imav_ui_path="/var/www/html/imunifyav" else - echo " → Deployment script ran (check for errors below)" + imav_ui_path="$imav_ui_input" fi - # Show any errors from deployment - if grep -qi "error\|failed\|conflict" "$deploy_log"; then - echo -e " ${YELLOW}⚠ Warnings detected:${NC}" - grep -iE "error|failed|conflict" "$deploy_log" | sed 's/^/ /' | head -3 + # Input validation: must be an absolute path, no spaces + if [[ "$imav_ui_path" != /* ]]; then + echo -e "${RED} ✗ Path must be absolute (start with /). Skipping ImunifyAV.${NC}" + imav_is_standalone=2 + elif [[ "$imav_ui_path" =~ [[:space:]] ]]; then + echo -e "${RED} ✗ Path must not contain spaces. Skipping ImunifyAV.${NC}" + imav_is_standalone=2 fi - else - echo -e "${YELLOW} ⚠ Deployment script timed out or failed${NC}" fi - rm -f "$deploy_log" + + if [ "$imav_is_standalone" -ne 2 ]; then + # Create config directory if needed + echo " → Creating $imav_conf_dir ..." + mkdir -p "$imav_conf_dir" || { + echo -e "${RED} ✗ Cannot create $imav_conf_dir - check permissions. Skipping ImunifyAV.${NC}" + imav_is_standalone=2 + } + fi + + if [ "$imav_is_standalone" -ne 2 ]; then + # Write minimal integration.conf (only ui_path is required) + printf '[paths]\nui_path = %s\n' "$imav_ui_path" > "$imav_conf_file" || { + echo -e "${RED} ✗ Cannot write $imav_conf_file. Skipping ImunifyAV.${NC}" + imav_is_standalone=2 + } + fi + + if [ "$imav_is_standalone" -ne 2 ]; then + echo -e " ${GREEN}✓${NC} integration.conf written: ui_path = $imav_ui_path" + fi + fi + + # SELinux warning for RHEL-family systems + if [ "$imav_is_standalone" -ne 2 ] && command -v getenforce &>/dev/null; then + local selinux_status + selinux_status=$(getenforce 2>/dev/null || echo "Unknown") + if [ "$selinux_status" = "Enforcing" ]; then + echo "" + echo -e " ${YELLOW}⚠ SELinux is Enforcing${NC}" + echo " After installation, ImunifyAV may need an SELinux policy module." + echo " If the UI is inaccessible, run:" + echo " ausearch -c 'imunify' | audit2allow -M imunify && semodule -i imunify.pp" + fi + fi + + echo "" + fi + # ── END STANDALONE SETUP ───────────────────────────────────────── + + # Only proceed with download/deploy if not cancelled (imav_is_standalone != 2) + if [ "${imav_is_standalone:-0}" -ne 2 ]; then + + # Use deployment script method (most reliable) + cd /tmp + if [ -f "imav-deploy.sh" ]; then rm -f imav-deploy.sh - - # Try to start the service if installed - if command -v systemctl &>/dev/null && is_imunify_installed; then - echo " → Starting ImunifyAV service..." - systemctl start imunify-antivirus 2>/dev/null || true - fi fi - else - echo -e "${RED} Failed to download installation script (network error or timeout)${NC}" - fi - if is_imunify_installed; then - echo -e "${GREEN}✓ ImunifyAV (FREE) installed${NC}" - echo " No license key required - this is the FREE version" - - # Find imunify-antivirus binary - local imunify_bin=$(command -v imunify-antivirus || find /usr -name imunify-antivirus 2>/dev/null | head -1) - - # Update malware signatures immediately - if [ -n "$imunify_bin" ]; then - echo " → Updating malware signatures..." - if timeout 60 "$imunify_bin" update 2>&1 | grep -qiE "updated|Success|completed"; then - echo -e " ${GREEN}✓${NC} Signatures updated" + # Download deployment script with timeout + if timeout 30 wget -q -O imav-deploy.sh https://repo.imunify360.cloudlinux.com/defence360/imav-deploy.sh 2>/dev/null; then + if [ ! -f imav-deploy.sh ] || [ ! -s imav-deploy.sh ]; then + echo -e "${RED} Failed to download installation script (empty file)${NC}" else - echo -e " ${YELLOW}⚠${NC} Signature update inconclusive (continuing with current definitions)" + # Run deployment script with timeout and capture output + echo " → Running deployment script..." + local deploy_log="/tmp/imav-deploy-$$.log" + if timeout 300 bash imav-deploy.sh > "$deploy_log" 2>&1; then + # Check if any actual installation happened + if grep -qiE "installed|complete|success" "$deploy_log"; then + echo " → Deployment script executed" + else + echo " → Deployment script ran (check for errors below)" + fi + + # Show any errors from deployment + if grep -qi "error\|failed\|conflict" "$deploy_log"; then + echo -e " ${YELLOW}⚠ Warnings detected:${NC}" + grep -iE "error|failed|conflict" "$deploy_log" | sed 's/^/ /' | head -3 + fi + else + echo -e "${YELLOW} ⚠ Deployment script timed out or failed${NC}" + fi + rm -f "$deploy_log" + rm -f imav-deploy.sh + + # Try to start the service if installed + if command -v systemctl &>/dev/null && is_imunify_installed; then + echo " → Starting ImunifyAV service..." + systemctl start imunify-antivirus 2>/dev/null || true + fi + fi + else + echo -e "${RED} Failed to download installation script (network error or timeout)${NC}" + fi + + if is_imunify_installed; then + echo -e "${GREEN}✓ ImunifyAV (FREE) installed${NC}" + echo " No license key required - this is the FREE version" + + # Find imunify-antivirus binary + local imunify_bin=$(command -v imunify-antivirus || find /usr -name imunify-antivirus 2>/dev/null | head -1) + + # Update malware signatures immediately + if [ -n "$imunify_bin" ]; then + echo " → Updating malware signatures..." + if timeout 60 "$imunify_bin" update 2>&1 | grep -qiE "updated|Success|completed"; then + echo -e " ${GREEN}✓${NC} Signatures updated" + else + echo -e " ${YELLOW}⚠${NC} Signature update inconclusive (continuing with current definitions)" + fi + fi + + # ── STANDALONE: POST-INSTALL UI URL HINT ───────────────── + if [ "$imav_is_standalone" -eq 1 ] && [ -n "${imav_ui_path:-}" ]; then + echo "" + echo -e " ${CYAN}ImunifyAV UI path:${NC} $imav_ui_path" + echo " Configure your web server to serve that directory, then" + echo " access the UI at: http://YOUR-SERVER-IP//" + echo " (Replace with the last component of the path above)" + fi + # ── END POST-INSTALL HINT ───────────────────────────────── + + else + echo -e "${RED}✗ ImunifyAV installation failed${NC}" + if [ "$imav_is_standalone" -eq 1 ]; then + echo -e "${YELLOW} Note: Verify integration.conf at $imav_conf_file is correct${NC}" + echo -e "${YELLOW} and that $imav_ui_path is accessible by your web server.${NC}" + else + echo -e "${YELLOW} Note: ImunifyAV FREE is primarily supported on CloudLinux, cPanel, and Plesk systems${NC}" fi fi - else - echo -e "${RED}✗ ImunifyAV installation failed${NC}" - echo -e "${YELLOW} Note: ImunifyAV FREE is primarily supported on CloudLinux, cPanel, and Plesk systems${NC}" + fi + # ── END CANCELLED GUARD ─────────────────────────────────────────── + else echo -e "${GREEN}✓ ImunifyAV already installed${NC}" fi