1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # ============================================ 6 | # Package Manager Integration - ADD THIS AT TOP 7 | # ============================================ 8 | PKG_MODE=false 9 | PKG_STATE_DIR="/var/lib/easyinstall" 10 | PKG_CONFIG_DIR="/etc/easyinstall" 11 | PKG_HOOKS_DIR="/usr/share/easyinstall/hooks" 12 | 13 | # Source package manager if available 14 | if [ -f "/usr/share/easyinstall/pkg-manager.sh" ]; then 15 | source "/usr/share/easyinstall/pkg-manager.sh" 16 | PKG_MODE=true 17 | 18 | # Create state directory if not exists 19 | mkdir -p "$PKG_STATE_DIR" "$PKG_CONFIG_DIR" 20 | 21 | # Load configuration 22 | if [ -f "$PKG_CONFIG_DIR/config" ]; then 23 | source "$PKG_CONFIG_DIR/config" 24 | fi 25 | 26 | # Begin transaction 27 | begin_transaction "full-install" 28 | fi 29 | 30 | # ============================================ 31 | # โœ… Domain Existence Check Function - ADDED 32 | # ============================================ 33 | check_domain_exists() { 34 | local domain=$1 35 | 36 | # Check for existing nginx config 37 | if [ -f "/etc/nginx/sites-available/${domain}" ] || [ -f "/etc/nginx/sites-enabled/${domain}" ]; then 38 | return 0 39 | fi 40 | 41 | # Check for WordPress installation 42 | if [ -d "/var/www/html/${domain}" ] && [ -f "/var/www/html/${domain}/wp-config.php" ]; then 43 | return 0 44 | fi 45 | 46 | # Check for multisite installation 47 | if [ -d "/var/www/sites/${domain}" ] && [ -f "/var/www/sites/${domain}/public/wp-config.php" ]; then 48 | return 0 49 | fi 50 | 51 | return 1 52 | } 53 | 54 | # ============================================ 55 | # โœ… WordPress Installation Function - ADDED 56 | # ============================================ 57 | install_wordpress() { 58 | local domain=$1 59 | local use_ssl=$2 60 | local php_version=${3:-$(ls /etc/php/ 2>/dev/null | head -1)} 61 | 62 | # Check if domain already exists 63 | if check_domain_exists "$domain"; then 64 | echo -e "${RED}โŒ Domain ${domain} already exists. WordPress installation aborted.${NC}" 65 | exit 1 66 | fi 67 | 68 | echo -e "${YELLOW}๐Ÿ“ฆ Installing WordPress for ${domain}...${NC}" 69 | 70 | # Call the existing installer with correct parameters 71 | /usr/local/bin/install-wordpress "$domain" "$([ "$use_ssl" = "true" ] && echo "--ssl")" "$php_version" 72 | } 73 | 74 | # ============================================ 75 | # โœ… PHP Site Creation Function - ADDED 76 | # ============================================ 77 | create_php_site() { 78 | local domain=$1 79 | local use_ssl=$2 80 | 81 | # Check if domain already exists 82 | if check_domain_exists "$domain"; then 83 | echo -e "${RED}โŒ Domain ${domain} already exists. PHP site creation aborted.${NC}" 84 | exit 1 85 | fi 86 | 87 | echo -e "${YELLOW}๐Ÿ˜ Creating PHP site for ${domain}...${NC}" 88 | 89 | # Create site directory 90 | SITE_DIR="/var/www/html/${domain}" 91 | mkdir -p "$SITE_DIR" 92 | 93 | # Get PHP version 94 | PHP_VERSION=$(ls /etc/php/ 2>/dev/null | head -1) 95 | [ -z "$PHP_VERSION" ] && PHP_VERSION="8.2" 96 | 97 | # Create sample index.php 98 | cat > "$SITE_DIR/index.php" < 104 | 105 | 106 | 107 | 108 | 109 | ${domain} 110 | 135 | 136 | 137 |

Welcome to

138 | 139 |
140 |

This is a PHP site created with EasyInstall

141 |

PHP Version:

142 |

Server:

143 |

Date:

144 |
145 | 146 |

Edit this file at:

147 | 148 | 149 | EOF 150 | 151 | # Find PHP socket 152 | PHP_SOCKET="unix:/run/php/php${PHP_VERSION}-fpm.sock" 153 | if [ ! -S "${PHP_SOCKET#unix:}" ]; then 154 | for sock in /run/php/php*-fpm.sock; do 155 | if [ -S "$sock" ]; then 156 | PHP_SOCKET="unix:$sock" 157 | break 158 | fi 159 | done 160 | fi 161 | 162 | # Create nginx config 163 | cat > "/etc/nginx/sites-available/${domain}" </dev/null || true; 177 | 178 | location / { 179 | try_files \$uri \$uri/ =404; 180 | } 181 | 182 | location ~ \.php$ { 183 | include fastcgi_params; 184 | fastcgi_pass ${PHP_SOCKET}; 185 | fastcgi_index index.php; 186 | fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; 187 | } 188 | 189 | location ~ /\. { 190 | deny all; 191 | } 192 | 193 | location = /favicon.ico { 194 | log_not_found off; 195 | access_log off; 196 | } 197 | 198 | location = /robots.txt { 199 | allow all; 200 | log_not_found off; 201 | access_log off; 202 | } 203 | } 204 | EOF 205 | 206 | ln -sf "/etc/nginx/sites-available/${domain}" "/etc/nginx/sites-enabled/" 207 | chown -R www-data:www-data "$SITE_DIR" 208 | 209 | # Test and reload nginx 210 | if nginx -t 2>/dev/null; then 211 | systemctl reload nginx 2>/dev/null 212 | echo -e "${GREEN}โœ… Nginx configuration created${NC}" 213 | else 214 | echo -e "${RED}โŒ Nginx configuration test failed${NC}" 215 | nginx -t 216 | exit 1 217 | fi 218 | 219 | # Enable SSL if requested 220 | if [ "$use_ssl" = "true" ]; then 221 | echo -e "${YELLOW}๐Ÿ” Enabling SSL for ${domain}...${NC}" 222 | certbot --nginx -d "$domain" -d "www.$domain" --non-interactive --agree-tos --email "admin@$domain" 2>/dev/null 223 | 224 | if [ $? -eq 0 ]; then 225 | echo -e "${GREEN}โœ… SSL enabled for ${domain}${NC}" 226 | else 227 | echo -e "${RED}โŒ SSL installation failed${NC}" 228 | fi 229 | fi 230 | 231 | echo -e "${GREEN}โœ… PHP site created for ${domain}${NC}" 232 | echo -e "${GREEN}๐ŸŒ URL: http://${domain}${NC}" 233 | [ "$use_ssl" = "true" ] && echo -e "${GREEN}๐Ÿ”’ Secure URL: https://${domain}${NC}" 234 | } 235 | 236 | # ============================================ 237 | # โœ… HTML Site Creation Function - ADDED 238 | # ============================================ 239 | create_html_site() { 240 | local domain=$1 241 | local use_ssl=$2 242 | 243 | # Check if domain already exists 244 | if check_domain_exists "$domain"; then 245 | echo -e "${RED}โŒ Domain ${domain} already exists. HTML site creation aborted.${NC}" 246 | exit 1 247 | fi 248 | 249 | echo -e "${YELLOW}๐ŸŒ Creating HTML site for ${domain}...${NC}" 250 | 251 | # Create site directory 252 | SITE_DIR="/var/www/html/${domain}" 253 | mkdir -p "$SITE_DIR" 254 | 255 | # Create sample index.html 256 | cat > "$SITE_DIR/index.html" < 258 | 259 | 260 | 261 | 262 | ${domain} 263 | 284 | 285 | 286 |

Welcome to ${domain}

287 | 288 |
289 |

This is an HTML site created with EasyInstall

290 |

Server: $(hostname)

291 |

Date: $(date)

292 |
293 | 294 |

Edit this file at: ${SITE_DIR}/index.html

295 | 296 | 297 | EOF 298 | 299 | # Create nginx config for HTML site 300 | cat > "/etc/nginx/sites-available/${domain}" </dev/null || true; 314 | 315 | location / { 316 | try_files \$uri \$uri/ =404; 317 | } 318 | 319 | location ~ /\. { 320 | deny all; 321 | } 322 | 323 | location = /favicon.ico { 324 | log_not_found off; 325 | access_log off; 326 | } 327 | 328 | location = /robots.txt { 329 | allow all; 330 | log_not_found off; 331 | access_log off; 332 | } 333 | } 334 | EOF 335 | 336 | ln -sf "/etc/nginx/sites-available/${domain}" "/etc/nginx/sites-enabled/" 337 | chown -R www-data:www-data "$SITE_DIR" 338 | 339 | # Test and reload nginx 340 | if nginx -t 2>/dev/null; then 341 | systemctl reload nginx 2>/dev/null 342 | echo -e "${GREEN}โœ… Nginx configuration created${NC}" 343 | else 344 | echo -e "${RED}โŒ Nginx configuration test failed${NC}" 345 | nginx -t 346 | exit 1 347 | fi 348 | 349 | # Enable SSL if requested 350 | if [ "$use_ssl" = "true" ]; then 351 | echo -e "${YELLOW}๐Ÿ” Enabling SSL for ${domain}...${NC}" 352 | certbot --nginx -d "$domain" -d "www.$domain" --non-interactive --agree-tos --email "admin@$domain" 2>/dev/null 353 | 354 | if [ $? -eq 0 ]; then 355 | echo -e "${GREEN}โœ… SSL enabled for ${domain}${NC}" 356 | else 357 | echo -e "${RED}โŒ SSL installation failed${NC}" 358 | fi 359 | fi 360 | 361 | echo -e "${GREEN}โœ… HTML site created for ${domain}${NC}" 362 | echo -e "${GREEN}๐ŸŒ URL: http://${domain}${NC}" 363 | [ "$use_ssl" = "true" ] && echo -e "${GREEN}๐Ÿ”’ Secure URL: https://${domain}${NC}" 364 | } 365 | 366 | # ============================================ 367 | # โœ… SSL Enable Function for Existing Sites - ADDED 368 | # ============================================ 369 | enable_ssl_for_site() { 370 | local domain=$1 371 | 372 | # Check if domain exists 373 | if [ ! -f "/etc/nginx/sites-available/${domain}" ]; then 374 | echo -e "${RED}โŒ Domain ${domain} not found.${NC}" 375 | exit 1 376 | fi 377 | 378 | echo -e "${YELLOW}๐Ÿ” Enabling SSL for ${domain}...${NC}" 379 | 380 | # Check if SSL already exists 381 | if grep -q "listen 443 ssl" "/etc/nginx/sites-available/${domain}" 2>/dev/null; then 382 | echo -e "${YELLOW}โš ๏ธ SSL already enabled for ${domain}${NC}" 383 | return 0 384 | fi 385 | 386 | # Get SSL certificate 387 | certbot --nginx -d "$domain" -d "www.$domain" --non-interactive --agree-tos --email "admin@$domain" 2>/dev/null 388 | 389 | if [ $? -eq 0 ]; then 390 | echo -e "${GREEN}โœ… SSL enabled for ${domain}${NC}" 391 | echo -e "${GREEN}๐Ÿ”’ Secure URL: https://${domain}${NC}" 392 | else 393 | echo -e "${RED}โŒ Failed to enable SSL for ${domain}${NC}" 394 | exit 1 395 | fi 396 | } 397 | 398 | # ============================================ 399 | # โœ… FIX: Postfix Non-Interactive Configuration 400 | # ============================================ 401 | export DEBIAN_FRONTEND=noninteractive 402 | 403 | # Pre-configure Postfix to avoid interactive prompts 404 | debconf-set-selections <<< "postfix postfix/mailname string $(hostname -f 2>/dev/null || echo 'localhost')" 405 | debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Local only'" 406 | debconf-set-selections <<< "postfix postfix/destinations string localhost.localdomain, localhost" 407 | debconf-set-selections <<< "postfix postfix/protocols string ipv4" 408 | 409 | # Also pre-configure any other packages that might ask questions 410 | debconf-set-selections <<< "mariadb-server-10.5 mysql-server/root_password password root" 2>/dev/null || true 411 | debconf-set-selections <<< "mariadb-server-10.5 mysql-server/root_password_again password root" 2>/dev/null || true 412 | debconf-set-selections <<< "grub-pc grub-pc/install_devices_empty boolean true" 2>/dev/null || true 413 | 414 | # ============================================ 415 | # EasyInstall Enterprise Stack v3.0 416 | # Ultra-Optimized 512MB VPS โ†’ Enterprise Grade Hosting Engine 417 | # Complete with Advanced CDN & Monitoring Features 418 | # ============================================ 419 | 420 | GREEN='\033[0;32m' 421 | YELLOW='\033[1;33m' 422 | RED='\033[0;31m' 423 | BLUE='\033[0;34m' 424 | PURPLE='\033[0;35m' 425 | CYAN='\033[0;36m' 426 | NC='\033[0m' 427 | 428 | echo -e "${GREEN}๐Ÿš€ EasyInstall Enterprise Stack v3.0${NC}" 429 | echo -e "${GREEN}๐Ÿ“ฆ Complete with Advanced CDN & Monitoring Features${NC}" 430 | echo "" 431 | 432 | # Root check 433 | if [ "$EUID" -ne 0 ]; then 434 | echo -e "${RED}โŒ Please run as root${NC}" 435 | exit 1 436 | fi 437 | 438 | # ============================================ 439 | # System Detection & Optimization 440 | # ============================================ 441 | TOTAL_RAM=$(free -m | awk '/Mem:/ {print $2}') 442 | TOTAL_CORES=$(nproc) 443 | IP_ADDRESS=$(hostname -I | awk '{print $1}' | head -1) 444 | OS_VERSION=$(lsb_release -sc 2>/dev/null || echo "focal") 445 | HOSTNAME_FQDN=$(hostname -f 2>/dev/null || hostname) 446 | 447 | echo -e "${YELLOW}๐Ÿ“Š System Information:${NC}" 448 | echo " โ€ข RAM: ${TOTAL_RAM}MB" 449 | echo " โ€ข CPU Cores: ${TOTAL_CORES}" 450 | echo " โ€ข IP Address: ${IP_ADDRESS}" 451 | echo " โ€ข OS: Ubuntu/Debian ${OS_VERSION}" 452 | echo " โ€ข Hostname: ${HOSTNAME_FQDN}" 453 | echo "" 454 | 455 | # ============================================ 456 | # Adaptive Swap Configuration 457 | # ============================================ 458 | setup_swap() { 459 | echo -e "${YELLOW}๐Ÿ“€ Configuring swap space...${NC}" 460 | 461 | if [ ! -f /swapfile ]; then 462 | if [ "$TOTAL_RAM" -le 512 ]; then 463 | SWAPSIZE=1G 464 | SWAPPINESS=60 465 | elif [ "$TOTAL_RAM" -le 1024 ]; then 466 | SWAPSIZE=2G 467 | SWAPPINESS=50 468 | else 469 | SWAPSIZE=4G 470 | SWAPPINESS=40 471 | fi 472 | 473 | fallocate -l $SWAPSIZE /swapfile 2>/dev/null || dd if=/dev/zero of=/swapfile bs=1M count=2048 2>/dev/null 474 | chmod 600 /swapfile 475 | mkswap /swapfile 476 | swapon /swapfile 477 | echo '/swapfile none swap sw 0 0' >> /etc/fstab 478 | 479 | # Optimize swap usage 480 | echo "vm.swappiness=$SWAPPINESS" >> /etc/sysctl.conf 481 | echo "vm.vfs_cache_pressure=50" >> /etc/sysctl.conf 482 | 483 | echo -e "${GREEN} โœ… Swap created: $SWAPSIZE${NC}" 484 | 485 | # Track in package manager 486 | if [ "$PKG_MODE" = true ]; then 487 | mark_component_installed "swap" "3.0" 488 | fi 489 | else 490 | echo -e " โš ๏ธ Swap already exists" 491 | fi 492 | } 493 | 494 | # ============================================ 495 | # Kernel Tuning 496 | # ============================================ 497 | kernel_tuning() { 498 | echo -e "${YELLOW}โš™๏ธ Applying kernel optimizations...${NC}" 499 | 500 | cat > /etc/sysctl.d/99-easyinstall.conf </dev/null || true 535 | echo -e "${GREEN} โœ… Kernel tuning applied${NC}" 536 | 537 | if [ "$PKG_MODE" = true ]; then 538 | mark_component_installed "kernel" "3.0" 539 | fi 540 | } 541 | 542 | # ============================================ 543 | # Nginx Cleanup Function - Run before Nginx configuration 544 | # ============================================ 545 | cleanup_nginx_config() { 546 | echo -e "${YELLOW}๐Ÿงน Cleaning up existing Nginx configurations...${NC}" 547 | 548 | # Stop nginx if running 549 | systemctl stop nginx 2>/dev/null || true 550 | 551 | # Remove all cache configuration files completely 552 | rm -rf /etc/nginx/conf.d/fastcgi-cache.conf 553 | rm -rf /etc/nginx/conf.d/fastcgi-cache.conf.* 554 | rm -rf /etc/nginx/conf.d/*cache* 555 | rm -rf /etc/nginx/conf.d/*.bak 556 | rm -rf /etc/nginx/conf.d/*.old 557 | rm -rf /etc/nginx/conf.d/*~ 558 | 559 | # Remove any duplicate or backup files 560 | find /etc/nginx/conf.d/ -name "fastcgi-cache.conf*" -type f -delete 2>/dev/null || true 561 | find /etc/nginx/conf.d/ -name "*fastcgi*" -type f -delete 2>/dev/null || true 562 | find /etc/nginx/conf.d/ -name "*cache*" -type f -delete 2>/dev/null || true 563 | 564 | # Remove any symbolic links that might cause issues 565 | find /etc/nginx/ -type l -name "*fastcgi*" -delete 2>/dev/null || true 566 | 567 | # Clean the cache directory 568 | rm -rf /var/cache/nginx/* 569 | mkdir -p /var/cache/nginx 570 | chown -R www-data:www-data /var/cache/nginx 2>/dev/null || chown -R nginx:nginx /var/cache/nginx 2>/dev/null || true 571 | chmod -R 755 /var/cache/nginx 572 | 573 | # Also clean sites-enabled 574 | rm -f /etc/nginx/sites-enabled/wordpress 575 | rm -f /etc/nginx/sites-enabled/default 576 | 577 | echo -e "${GREEN} โœ… Nginx cleanup completed${NC}" 578 | } 579 | 580 | # ============================================ 581 | # Install Required Packages (with newest PHP) 582 | # ============================================ 583 | install_packages() { 584 | echo -e "${YELLOW}๐Ÿ“ฆ Installing enterprise stack with latest PHP...${NC}" 585 | 586 | # Update package list 587 | apt update 588 | 589 | # Install prerequisites 590 | apt install -y software-properties-common curl wget gnupg2 ca-certificates lsb-release \ 591 | apt-transport-https bc jq python3-pip pipx 592 | 593 | # Add PHP repository 594 | echo -e "${YELLOW} ๐Ÿ“Œ Adding PHP repository (ondrej/php)...${NC}" 595 | 596 | if ! add-apt-repository -y ppa:ondrej/php 2>/dev/null; then 597 | wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg 2>/dev/null || \ 598 | curl -fsSL https://packages.sury.org/php/apt.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/php.gpg 599 | echo "deb https://packages.sury.org/php/ $(lsb_release -sc 2>/dev/null || echo 'focal') main" > /etc/apt/sources.list.d/php.list 600 | fi 601 | 602 | # Add official Nginx repository 603 | echo -e "${YELLOW} ๐Ÿ“Œ Adding official Nginx repository...${NC}" 604 | rm -f /etc/apt/sources.list.d/nginx.list 605 | 606 | # Add Nginx signing key 607 | curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg 2>/dev/null 608 | 609 | # Add Nginx repository for mainline version 610 | echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/ubuntu $(lsb_release -sc 2>/dev/null || echo 'focal') nginx" > /etc/apt/sources.list.d/nginx.list 611 | 612 | # Pin Nginx packages 613 | cat > /etc/apt/preferences.d/nginx </dev/null 2>&1; then 625 | PHP_VERSION="php${version}" 626 | echo -e "${GREEN} โœ… Found PHP ${version}${NC}" 627 | break 628 | fi 629 | done 630 | 631 | if [ -z "$PHP_VERSION" ]; then 632 | PHP_VERSION="php8.2" 633 | echo -e "${YELLOW} โš ๏ธ Using fallback PHP 8.2${NC}" 634 | fi 635 | 636 | echo -e "${YELLOW} ๐Ÿ“Œ Installing PHP ${PHP_VERSION} and modules...${NC}" 637 | 638 | # Install base packages 639 | apt install -y nginx mariadb-server ${PHP_VERSION}-fpm ${PHP_VERSION}-mysql \ 640 | ${PHP_VERSION}-cli ${PHP_VERSION}-curl ${PHP_VERSION}-xml ${PHP_VERSION}-mbstring \ 641 | ${PHP_VERSION}-zip ${PHP_VERSION}-gd ${PHP_VERSION}-imagick ${PHP_VERSION}-opcache \ 642 | ${PHP_VERSION}-redis ${PHP_VERSION}-intl ${PHP_VERSION}-bcmath ${PHP_VERSION}-gmp \ 643 | ${PHP_VERSION}-xmlrpc ${PHP_VERSION}-memcache ${PHP_VERSION}-memcached \ 644 | redis-server memcached ufw fail2ban curl wget unzip openssl \ 645 | certbot python3-certbot-nginx \ 646 | htop neofetch git cron dnsutils \ 647 | automysqlbackup rclone netdata glances \ 648 | bc jq python3-pip python3-venv python3-full postfix 649 | 650 | # Install nginx modules and modsecurity 651 | echo -e "${YELLOW} ๐Ÿ“Œ Installing nginx modules and modsecurity...${NC}" 652 | 653 | apt install -y nginx-module-geoip nginx-module-image-filter nginx-module-njs \ 654 | nginx-module-perl nginx-module-xslt 2>/dev/null || echo -e "${YELLOW} โš ๏ธ Some nginx modules skipped, continuing...${NC}" 655 | 656 | apt install -y libnginx-mod-http-modsecurity modsecurity-crs 2>/dev/null || echo -e "${YELLOW} โš ๏ธ Modsecurity packages installation skipped, continuing...${NC}" 657 | 658 | echo -e "${GREEN} โœ… All packages installed with PHP ${PHP_VERSION}${NC}" 659 | 660 | if [ "$PKG_MODE" = true ]; then 661 | mark_component_installed "packages" "3.0" 662 | fi 663 | } 664 | 665 | # ============================================ 666 | # ModSecurity WAF Setup 667 | # ============================================ 668 | setup_modsecurity() { 669 | echo -e "${YELLOW}๐Ÿ›ก๏ธ Configuring ModSecurity WAF...${NC}" 670 | 671 | if [ -f /etc/nginx/modsecurity/modsecurity.conf-recommended ]; then 672 | mkdir -p /etc/nginx/modsecurity 673 | 674 | cp /etc/nginx/modsecurity/modsecurity.conf-recommended /etc/nginx/modsecurity/modsecurity.conf 2>/dev/null || \ 675 | cp /etc/modsecurity/modsecurity.conf-recommended /etc/nginx/modsecurity/modsecurity.conf 2>/dev/null || true 676 | 677 | if [ -f /etc/nginx/modsecurity/modsecurity.conf ]; then 678 | sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/nginx/modsecurity/modsecurity.conf 679 | 680 | if [ ! -d /usr/share/modsecurity-crs/owasp-crs ]; then 681 | mkdir -p /usr/share/modsecurity-crs 682 | cd /usr/share/modsecurity-crs 683 | git clone https://github.com/coreruleset/coreruleset.git owasp-crs 2>/dev/null || true 684 | cd owasp-crs 685 | cp crs-setup.conf.example crs-setup.conf 2>/dev/null || true 686 | fi 687 | 688 | cat > /etc/nginx/modsecurity-rules.conf < /usr/local/bin/autoheal <<'EOF' 722 | #!/bin/bash 723 | 724 | SERVICES=("nginx" "php*-fpm" "mariadb" "redis-server" "memcached" "fail2ban" "netdata") 725 | LOG_FILE="/var/log/autoheal.log" 726 | MAX_RESTART_ATTEMPTS=3 727 | 728 | log_message() { 729 | echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" 730 | } 731 | 732 | check_service() { 733 | local service=$1 734 | local service_name=$(echo $service | sed 's/\*//') 735 | local counter_file="/tmp/autoheal_${service_name//[^a-zA-Z0-9]/}_counter" 736 | 737 | if ! systemctl is-active --quiet $service 2>/dev/null; then 738 | log_message "โš ๏ธ Service $service is down. Attempting restart..." 739 | 740 | local restart_count=0 741 | [ -f "$counter_file" ] && restart_count=$(cat "$counter_file") 742 | 743 | if [ $restart_count -lt $MAX_RESTART_ATTEMPTS ]; then 744 | systemctl restart $service 2>/dev/null 745 | sleep 5 746 | 747 | if systemctl is-active --quiet $service 2>/dev/null; then 748 | log_message "โœ… Service $service restarted successfully" 749 | echo 0 > "$counter_file" 750 | else 751 | restart_count=$((restart_count + 1)) 752 | echo $restart_count > "$counter_file" 753 | log_message "โŒ Failed to restart $service (attempt $restart_count/$MAX_RESTART_ATTEMPTS)" 754 | fi 755 | else 756 | log_message "๐Ÿšจ Service $service failed to restart after $MAX_RESTART_ATTEMPTS attempts" 757 | 758 | if [ -f "/root/.admin_email" ]; then 759 | ADMIN_EMAIL=$(cat /root/.admin_email) 760 | echo "Service $service failed to restart automatically on $(hostname)" | \ 761 | mail -s "๐Ÿšจ CRITICAL: Service $service failed" "$ADMIN_EMAIL" 2>/dev/null || true 762 | fi 763 | 764 | echo 0 > "$counter_file" 765 | fi 766 | fi 767 | } 768 | 769 | check_disk_space() { 770 | local disk_usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//') 771 | if [ $disk_usage -gt 95 ]; then 772 | log_message "โš ๏ธ Critical disk usage: $disk_usage% - Running cleanup" 773 | 774 | find /var/log -name "*.log" -mtime +7 -delete 2>/dev/null 775 | find /backups/weekly -type d -mtime +14 -delete 2>/dev/null 776 | apt clean 2>/dev/null 777 | 778 | log_message "โœ… Disk cleanup completed. New usage: $(df / | awk 'NR==2 {print $5}')" 779 | fi 780 | } 781 | 782 | check_memory_pressure() { 783 | local mem_usage=$(free -m | awk '/Mem:/ {print int($3/$2*100)}') 784 | if [ $mem_usage -gt 90 ]; then 785 | log_message "โš ๏ธ High memory usage: $mem_usage%" 786 | 787 | if systemctl is-active --quiet redis-server 2>/dev/null; then 788 | redis-cli FLUSHALL > /dev/null 2>&1 789 | log_message " Redis cache cleared" 790 | fi 791 | fi 792 | } 793 | 794 | check_load_average() { 795 | local load=$(uptime | awk -F'load average:' '{print $2}' | cut -d, -f1 | sed 's/ //g') 796 | local cores=$(nproc) 797 | 798 | if command -v bc >/dev/null 2>&1; then 799 | if (( $(echo "$load > $cores * 2" | bc -l 2>/dev/null) )); then 800 | log_message "โš ๏ธ High load average: $load" 801 | systemctl restart php*-fpm 2>/dev/null 802 | systemctl restart nginx 2>/dev/null 803 | log_message " Services restarted to reduce load" 804 | fi 805 | fi 806 | } 807 | 808 | while true; do 809 | log_message "Running auto-heal checks..." 810 | 811 | for service in "${SERVICES[@]}"; do 812 | if systemctl list-units --type=service --all 2>/dev/null | grep -q "$service" || \ 813 | [ -f "/etc/systemd/system/${service}.service" ] || \ 814 | [ -f "/lib/systemd/system/${service}.service" ]; then 815 | check_service "$service" 816 | fi 817 | done 818 | 819 | check_disk_space 820 | check_memory_pressure 821 | check_load_average 822 | 823 | sleep 60 824 | done 825 | EOF 826 | 827 | chmod +x /usr/local/bin/autoheal 828 | 829 | cat > /etc/systemd/system/autoheal.service </dev/null 847 | systemctl start autoheal 2>/dev/null 848 | 849 | echo -e "${GREEN} โœ… Auto-healing service configured${NC}" 850 | 851 | if [ "$PKG_MODE" = true ]; then 852 | mark_component_installed "autoheal" "3.0" 853 | fi 854 | } 855 | 856 | # ============================================ 857 | # Database Security & Configuration with Performance Tuning - FIXED 858 | # ============================================ 859 | setup_database() { 860 | echo -e "${YELLOW}๐Ÿ” Securing database with performance tuning...${NC}" 861 | 862 | sleep 5 863 | 864 | # Start MariaDB if not running 865 | systemctl start mariadb 2>/dev/null || true 866 | 867 | # Wait for MariaDB to be ready 868 | until mysqladmin ping >/dev/null 2>&1; do 869 | echo " Waiting for MariaDB to start..." 870 | sleep 2 871 | done 872 | 873 | # Set root password and secure installation 874 | mysql < /root/.my.cnf < /etc/mysql/mariadb.conf.d/99-easyinstall.cnf </dev/null || true 946 | 947 | # Wait for MariaDB to restart 948 | sleep 3 949 | 950 | echo -e "${GREEN} โœ… Database configured with performance tuning${NC}" 951 | 952 | if [ "$PKG_MODE" = true ]; then 953 | mark_component_installed "database" "3.0" 954 | fi 955 | } 956 | 957 | # ============================================ 958 | # PHP-FPM Optimization with Auto Memory Adjustment - FIXED 959 | # ============================================ 960 | optimize_php() { 961 | echo -e "${YELLOW}โšก Optimizing PHP-FPM...${NC}" 962 | 963 | sleep 2 964 | 965 | PHP_VERSION="" 966 | if command -v php >/dev/null 2>&1; then 967 | PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;' 2>/dev/null) 968 | fi 969 | 970 | if [ -z "$PHP_VERSION" ]; then 971 | PHP_VERSION=$(ls /etc/php/ 2>/dev/null | head -1) 972 | fi 973 | 974 | if [ -z "$PHP_VERSION" ]; then 975 | PHP_VERSION="8.2" 976 | fi 977 | 978 | PHP_INI="/etc/php/${PHP_VERSION}/fpm/php.ini" 979 | PHP_POOL="/etc/php/${PHP_VERSION}/fpm/pool.d/www.conf" 980 | 981 | if [ "$TOTAL_RAM" -le 512 ]; then 982 | MAX_CHILDREN=4 983 | START_SERVERS=2 984 | MIN_SPARE=1 985 | MAX_SPARE=3 986 | MEMORY_LIMIT="128M" 987 | OPcache_MEMORY=64 988 | elif [ "$TOTAL_RAM" -le 1024 ]; then 989 | MAX_CHILDREN=8 990 | START_SERVERS=3 991 | MIN_SPARE=2 992 | MAX_SPARE=6 993 | MEMORY_LIMIT="256M" 994 | OPcache_MEMORY=128 995 | else 996 | MAX_CHILDREN=16 997 | START_SERVERS=4 998 | MIN_SPARE=2 999 | MAX_SPARE=8 1000 | MEMORY_LIMIT="512M" 1001 | OPcache_MEMORY=256 1002 | fi 1003 | 1004 | if [ -f "$PHP_POOL" ]; then 1005 | sed -i "s/^pm.max_children =.*/pm.max_children = ${MAX_CHILDREN}/" $PHP_POOL 2>/dev/null || true 1006 | sed -i "s/^pm.start_servers =.*/pm.start_servers = ${START_SERVERS}/" $PHP_POOL 2>/dev/null || true 1007 | sed -i "s/^pm.min_spare_servers =.*/pm.min_spare_servers = ${MIN_SPARE}/" $PHP_POOL 2>/dev/null || true 1008 | sed -i "s/^pm.max_spare_servers =.*/pm.max_spare_servers = ${MAX_SPARE}/" $PHP_POOL 2>/dev/null || true 1009 | fi 1010 | 1011 | if [ -f "$PHP_INI" ]; then 1012 | sed -i "s/^memory_limit =.*/memory_limit = ${MEMORY_LIMIT}/" $PHP_INI 2>/dev/null || true 1013 | sed -i "s/^max_execution_time =.*/max_execution_time = 300/" $PHP_INI 2>/dev/null || true 1014 | sed -i "s/^max_input_time =.*/max_input_time = 300/" $PHP_INI 2>/dev/null || true 1015 | sed -i "s/^post_max_size =.*/post_max_size = 64M/" $PHP_INI 2>/dev/null || true 1016 | sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 64M/" $PHP_INI 2>/dev/null || true 1017 | 1018 | if ! grep -q "opcache.enable" "$PHP_INI"; then 1019 | cat >> $PHP_INI < /etc/nginx/conf.d/php-status.conf </dev/null 2>&1; then 1067 | PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;' 2>/dev/null) 1068 | fi 1069 | 1070 | if [ -z "$PHP_VERSION" ]; then 1071 | PHP_VERSION=$(ls /etc/php/ 2>/dev/null | head -1) 1072 | fi 1073 | 1074 | if [ -z "$PHP_VERSION" ]; then 1075 | PHP_VERSION="8.2" 1076 | fi 1077 | 1078 | if [ "$TOTAL_RAM" -le 512 ]; then 1079 | CACHE_SIZE="100m" 1080 | CACHE_INACTIVE="30m" 1081 | elif [ "$TOTAL_RAM" -le 1024 ]; then 1082 | CACHE_SIZE="200m" 1083 | CACHE_INACTIVE="60m" 1084 | else 1085 | CACHE_SIZE="500m" 1086 | CACHE_INACTIVE="120m" 1087 | fi 1088 | 1089 | mkdir -p /var/cache/nginx 1090 | mkdir -p /etc/nginx/sites-available 1091 | mkdir -p /etc/nginx/sites-enabled 1092 | mkdir -p /etc/nginx/conf.d 1093 | 1094 | chown -R www-data:www-data /var/cache/nginx 2>/dev/null || chown -R nginx:nginx /var/cache/nginx 2>/dev/null || true 1095 | chmod -R 755 /var/cache/nginx 1096 | 1097 | PHP_SOCKET="/run/php/php${PHP_VERSION}-fpm.sock" 1098 | if [ ! -S "$PHP_SOCKET" ]; then 1099 | for sock in /run/php/php*-fpm.sock; do 1100 | if [ -S "$sock" ]; then 1101 | PHP_SOCKET="$sock" 1102 | break 1103 | fi 1104 | done 1105 | fi 1106 | 1107 | cat > /etc/nginx/security-headers.conf < /etc/nginx/conf.d/fastcgi-cache.conf < /etc/nginx/nginx.conf < /etc/nginx/sites-available/wordpress <&1; then 1270 | systemctl restart nginx 1271 | echo -e "${GREEN} โœ… Nginx configured with FastCGI cache (${CACHE_SIZE}) and security headers${NC}" 1272 | 1273 | if [ "$PKG_MODE" = true ]; then 1274 | mark_component_installed "nginx" "3.0" 1275 | fi 1276 | else 1277 | echo -e "${RED} โŒ Nginx configuration test failed. Running emergency fix...${NC}" 1278 | 1279 | systemctl stop nginx 1280 | 1281 | rm -rf /etc/nginx/conf.d/* 1282 | rm -rf /etc/nginx/sites-enabled/* 1283 | 1284 | cat > /etc/nginx/conf.d/fastcgi-cache.conf < /etc/nginx/nginx.conf < /etc/nginx/sites-available/wordpress < /usr/local/bin/xmlrpc-manager <<'EOF' 1347 | #!/bin/bash 1348 | 1349 | GREEN='\033[0;32m' 1350 | YELLOW='\033[1;33m' 1351 | RED='\033[0;31m' 1352 | NC='\033[0m' 1353 | 1354 | NGINX_SITE="/etc/nginx/sites-available/wordpress" 1355 | MODSECURITY_RULES="/etc/nginx/modsecurity-rules.conf" 1356 | 1357 | case "$1" in 1358 | enable) 1359 | echo -e "${YELLOW}Enabling XML-RPC...${NC}" 1360 | 1361 | # Remove XML-RPC block from nginx config if present 1362 | if [ -f "$NGINX_SITE" ]; then 1363 | sed -i '/location = \/xmlrpc.php/,+4d' "$NGINX_SITE" 2>/dev/null || true 1364 | sed -i 's/# XML-RPC is enabled by default//' "$NGINX_SITE" 2>/dev/null || true 1365 | fi 1366 | 1367 | # Comment out ModSecurity XML-RPC rule if present 1368 | if [ -f "$MODSECURITY_RULES" ]; then 1369 | sed -i 's/^SecRule REQUEST_URI "@contains xmlrpc.php"/# SecRule REQUEST_URI "@contains xmlrpc.php"/' "$MODSECURITY_RULES" 2>/dev/null || true 1370 | fi 1371 | 1372 | # Test and reload nginx 1373 | if nginx -t 2>/dev/null; then 1374 | systemctl reload nginx 2>/dev/null 1375 | echo -e "${GREEN}โœ… XML-RPC has been ENABLED${NC}" 1376 | echo " WordPress XML-RPC is now accessible at: http://yourdomain.com/xmlrpc.php" 1377 | else 1378 | echo -e "${RED}โŒ Nginx configuration test failed${NC}" 1379 | nginx -t 1380 | fi 1381 | ;; 1382 | 1383 | disable) 1384 | echo -e "${YELLOW}Disabling XML-RPC...${NC}" 1385 | 1386 | # Add XML-RPC block to nginx config 1387 | if [ -f "$NGINX_SITE" ]; then 1388 | # Check if already has XML-RPC block 1389 | if ! grep -q "location = /xmlrpc.php" "$NGINX_SITE"; then 1390 | # Add XML-RPC block before the closing } 1391 | sed -i '/^}/i \ \n # Block XML-RPC\n location = /xmlrpc.php {\n deny all;\n access_log off;\n log_not_found off;\n }' "$NGINX_SITE" 2>/dev/null 1392 | fi 1393 | fi 1394 | 1395 | # Uncomment ModSecurity XML-RPC rule if present 1396 | if [ -f "$MODSECURITY_RULES" ]; then 1397 | sed -i 's/^# SecRule REQUEST_URI "@contains xmlrpc.php"/SecRule REQUEST_URI "@contains xmlrpc.php"/' "$MODSECURITY_RULES" 2>/dev/null || true 1398 | fi 1399 | 1400 | # Test and reload nginx 1401 | if nginx -t 2>/dev/null; then 1402 | systemctl reload nginx 2>/dev/null 1403 | echo -e "${GREEN}โœ… XML-RPC has been DISABLED${NC}" 1404 | echo " WordPress XML-RPC is now blocked" 1405 | else 1406 | echo -e "${RED}โŒ Nginx configuration test failed${NC}" 1407 | nginx -t 1408 | fi 1409 | ;; 1410 | 1411 | status) 1412 | echo -e "${YELLOW}XML-RPC Status:${NC}" 1413 | 1414 | # Check nginx config 1415 | if [ -f "$NGINX_SITE" ]; then 1416 | if grep -q "location = /xmlrpc.php" "$NGINX_SITE"; then 1417 | echo -e " โ€ข Nginx: ${RED}DISABLED (blocked in nginx)${NC}" 1418 | else 1419 | echo -e " โ€ข Nginx: ${GREEN}ENABLED${NC}" 1420 | fi 1421 | fi 1422 | 1423 | # Check ModSecurity 1424 | if [ -f "$MODSECURITY_RULES" ]; then 1425 | if grep -q "^SecRule REQUEST_URI \"@contains xmlrpc.php\"" "$MODSECURITY_RULES" 2>/dev/null; then 1426 | echo -e " โ€ข ModSecurity: ${RED}DISABLED (blocked by WAF)${NC}" 1427 | elif grep -q "^# SecRule REQUEST_URI \"@contains xmlrpc.php\"" "$MODSECURITY_RULES" 2>/dev/null; then 1428 | echo -e " โ€ข ModSecurity: ${GREEN}ENABLED${NC}" 1429 | fi 1430 | fi 1431 | 1432 | # Test actual endpoint if domain is configured 1433 | DOMAIN=$(grep -m1 "server_name" "$NGINX_SITE" 2>/dev/null | awk '{print $2}' | sed 's/;//') 1434 | if [ -n "$DOMAIN" ] && [ "$DOMAIN" != "_" ]; then 1435 | echo -e "\nTesting XML-RPC endpoint: http://$DOMAIN/xmlrpc.php" 1436 | if curl -s -o /dev/null -w "%{http_code}" "http://$DOMAIN/xmlrpc.php" 2>/dev/null | grep -q "200\|405"; then 1437 | echo -e " โ€ข Endpoint: ${GREEN}Accessible${NC}" 1438 | else 1439 | echo -e " โ€ข Endpoint: ${RED}Blocked${NC}" 1440 | fi 1441 | fi 1442 | ;; 1443 | 1444 | test) 1445 | DOMAIN=$2 1446 | if [ -z "$DOMAIN" ]; then 1447 | DOMAIN=$(grep -m1 "server_name" "$NGINX_SITE" 2>/dev/null | awk '{print $2}' | sed 's/;//') 1448 | fi 1449 | 1450 | if [ -z "$DOMAIN" ] || [ "$DOMAIN" = "_" ]; then 1451 | echo -e "${RED}No domain configured. Please specify a domain:${NC}" 1452 | echo " xmlrpc-manager test yourdomain.com" 1453 | exit 1 1454 | fi 1455 | 1456 | echo -e "${YELLOW}Testing XML-RPC on http://$DOMAIN/xmlrpc.php${NC}" 1457 | 1458 | # Simple test to see if endpoint responds 1459 | RESPONSE=$(curl -s -X POST -H "Content-Type: text/xml" \ 1460 | --data 'system.listMethods' \ 1461 | "http://$DOMAIN/xmlrpc.php" 2>/dev/null) 1462 | 1463 | if echo "$RESPONSE" | grep -q "methodResponse"; then 1464 | echo -e "${GREEN}โœ… XML-RPC is responding${NC}" 1465 | echo " Available methods can be retrieved" 1466 | elif curl -s -o /dev/null -w "%{http_code}" "http://$DOMAIN/xmlrpc.php" 2>/dev/null | grep -q "405"; then 1467 | echo -e "${YELLOW}โš ๏ธ XML-RPC endpoint exists but method not allowed${NC}" 1468 | elif curl -s -o /dev/null -w "%{http_code}" "http://$DOMAIN/xmlrpc.php" 2>/dev/null | grep -q "403"; then 1469 | echo -e "${RED}โŒ XML-RPC is blocked (403 Forbidden)${NC}" 1470 | elif curl -s -o /dev/null -w "%{http_code}" "http://$DOMAIN/xmlrpc.php" 2>/dev/null | grep -q "404"; then 1471 | echo -e "${RED}โŒ XML-RPC endpoint not found (404)${NC}" 1472 | else 1473 | HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://$DOMAIN/xmlrpc.php" 2>/dev/null) 1474 | echo -e "${YELLOW}โš ๏ธ XML-RPC returned HTTP code: $HTTP_CODE${NC}" 1475 | fi 1476 | ;; 1477 | 1478 | help) 1479 | echo "XML-RPC Manager for EasyInstall" 1480 | echo "" 1481 | echo "Commands:" 1482 | echo " enable - Enable XML-RPC access" 1483 | echo " disable - Disable/block XML-RPC access" 1484 | echo " status - Show XML-RPC status" 1485 | echo " test [domain] - Test XML-RPC endpoint" 1486 | echo " help - Show this help" 1487 | echo "" 1488 | echo "Examples:" 1489 | echo " xmlrpc-manager enable" 1490 | echo " xmlrpc-manager disable" 1491 | echo " xmlrpc-manager status" 1492 | echo " xmlrpc-manager test example.com" 1493 | ;; 1494 | 1495 | *) 1496 | if [ -z "$1" ]; then 1497 | echo "XML-RPC Manager - Use 'xmlrpc-manager help' for commands" 1498 | else 1499 | echo -e "${RED}Unknown command: $1${NC}" 1500 | echo "Use 'xmlrpc-manager help' for available commands" 1501 | fi 1502 | ;; 1503 | esac 1504 | EOF 1505 | 1506 | chmod +x /usr/local/bin/xmlrpc-manager 1507 | 1508 | # Add alias to easyinstall 1509 | if [ -f /usr/local/bin/easyinstall ]; then 1510 | # Will be updated in install_commands function 1511 | echo -e "${GREEN} โœ… XML-RPC manager installed${NC}" 1512 | fi 1513 | 1514 | if [ "$PKG_MODE" = true ]; then 1515 | mark_component_installed "xmlrpc" "3.0" 1516 | fi 1517 | } 1518 | 1519 | # ============================================ 1520 | # Advanced Redis + Memcached Configuration - FIXED 1521 | # ============================================ 1522 | configure_redis_memcached() { 1523 | echo -e "${YELLOW}โšก Configuring Redis and Memcached...${NC}" 1524 | 1525 | REDIS_MAXMEMORY="64mb" 1526 | if [ "$TOTAL_RAM" -le 512 ]; then 1527 | REDIS_MAXMEMORY="32mb" 1528 | elif [ "$TOTAL_RAM" -le 1024 ]; then 1529 | REDIS_MAXMEMORY="128mb" 1530 | else 1531 | REDIS_MAXMEMORY="256mb" 1532 | fi 1533 | 1534 | if [ -f /etc/redis/redis.conf ]; then 1535 | cp /etc/redis/redis.conf /etc/redis/redis.conf.backup 2>/dev/null || true 1536 | fi 1537 | 1538 | cat > /etc/redis/redis.conf < /etc/memcached.conf </dev/null || true 1588 | systemctl restart memcached 2>/dev/null || true 1589 | 1590 | echo -e "${GREEN} โœ… Redis and Memcached optimized (Redis: ${REDIS_MAXMEMORY}, Memcached: ${MEMCACHED_MEMORY}MB)${NC}" 1591 | 1592 | if [ "$PKG_MODE" = true ]; then 1593 | mark_component_installed "redis" "3.0" 1594 | mark_component_installed "memcached" "3.0" 1595 | fi 1596 | } 1597 | 1598 | # ============================================ 1599 | # Fail2ban Enhanced WordPress Rules - FIXED 1600 | # ============================================ 1601 | setup_fail2ban() { 1602 | echo -e "${YELLOW}๐Ÿ›ก๏ธ Configuring enhanced Fail2ban WordPress rules...${NC}" 1603 | 1604 | ufw --force disable 2>/dev/null 1605 | ufw default deny incoming 2>/dev/null 1606 | ufw default allow outgoing 2>/dev/null 1607 | ufw allow 22/tcp comment 'SSH' 2>/dev/null 1608 | ufw allow 80/tcp comment 'HTTP' 2>/dev/null 1609 | ufw allow 443/tcp comment 'HTTPS' 2>/dev/null 1610 | ufw allow 19999/tcp comment 'Netdata' 2>/dev/null 1611 | ufw allow 61208/tcp comment 'Glances' 2>/dev/null 1612 | echo "y" | ufw enable 2>/dev/null || true 1613 | 1614 | mkdir -p /etc/fail2ban 1615 | cat > /etc/fail2ban/jail.local < /etc/fail2ban/filter.d/wordpress-login.conf < .* "POST .*wp-login\.php 1652 | ^ .* "POST .*wp-admin/admin-ajax\.php.*action=.*login 1653 | ^ .* "GET .*wp-login\.php.*action=register 1654 | ignoreregex = 1655 | EOF 1656 | 1657 | cat > /etc/fail2ban/filter.d/wordpress-xmlrpc.conf < .* "POST .*xmlrpc\.php 1660 | ^ .* "POST .*wp.*\.php.*methodCall 1661 | ignoreregex = 1662 | EOF 1663 | 1664 | cat > /etc/fail2ban/filter.d/wordpress-hardening.conf < .* "GET .*wp-config\.php 1667 | ^ .* "GET .*\.sql 1668 | ^ .* "GET .*\.bak 1669 | ^ .* "GET .*\.old 1670 | ^ .* "GET .*/\.git/ 1671 | ^ .* "GET .*/\.svn/ 1672 | ignoreregex = 1673 | EOF 1674 | 1675 | systemctl restart fail2ban 2>/dev/null || true 1676 | 1677 | echo -e "${GREEN} โœ… Enhanced Fail2ban WordPress rules configured${NC}" 1678 | 1679 | if [ "$PKG_MODE" = true ]; then 1680 | mark_component_installed "fail2ban" "3.0" 1681 | fi 1682 | } 1683 | 1684 | # ============================================ 1685 | # WordPress Security Keys Update (Monthly Cron) - FIXED 1686 | # ============================================ 1687 | setup_security_keys_cron() { 1688 | echo -e "${YELLOW}๐Ÿ”‘ Setting up monthly WordPress security keys update...${NC}" 1689 | 1690 | cat > /usr/local/bin/update-wp-keys <<'EOF' 1691 | #!/bin/bash 1692 | 1693 | WP_CONFIG="/var/www/html/wordpress/wp-config.php" 1694 | 1695 | if [ ! -f "$WP_CONFIG" ]; then 1696 | echo "WordPress config not found" 1697 | exit 0 1698 | fi 1699 | 1700 | cp "$WP_CONFIG" "$WP_CONFIG.backup.$(date +%Y%m%d)" 2>/dev/null 1701 | 1702 | SALT_DATA=$(curl -s https://api.wordpress.org/secret-key/1.1/salt/ 2>/dev/null) 1703 | 1704 | if [ -n "$SALT_DATA" ]; then 1705 | sed -i '/AUTH_KEY/d' "$WP_CONFIG" 2>/dev/null 1706 | sed -i '/SECURE_AUTH_KEY/d' "$WP_CONFIG" 2>/dev/null 1707 | sed -i '/LOGGED_IN_KEY/d' "$WP_CONFIG" 2>/dev/null 1708 | sed -i '/NONCE_KEY/d' "$WP_CONFIG" 2>/dev/null 1709 | sed -i '/AUTH_SALT/d' "$WP_CONFIG" 2>/dev/null 1710 | sed -i '/SECURE_AUTH_SALT/d' "$WP_CONFIG" 2>/dev/null 1711 | sed -i '/LOGGED_IN_SALT/d' "$WP_CONFIG" 2>/dev/null 1712 | sed -i '/NONCE_SALT/d' "$WP_CONFIG" 2>/dev/null 1713 | 1714 | sed -i "/.*That's all.*/i $SALT_DATA" "$WP_CONFIG" 2>/dev/null 1715 | 1716 | echo "WordPress security keys updated successfully" 1717 | else 1718 | echo "Failed to fetch new salts" 1719 | exit 0 1720 | fi 1721 | EOF 1722 | 1723 | chmod +x /usr/local/bin/update-wp-keys 1724 | 1725 | mkdir -p /etc/cron.d 1726 | cat > /etc/cron.d/wp-security-keys < /dev/null 2>&1 1729 | EOF 1730 | 1731 | echo -e "${GREEN} โœ… Monthly WordPress security keys update configured${NC}" 1732 | 1733 | if [ "$PKG_MODE" = true ]; then 1734 | mark_component_installed "security-keys" "3.0" 1735 | fi 1736 | } 1737 | 1738 | # ============================================ 1739 | # WordPress Installation Functions - COMPLETELY REWRITTEN AND FIXED 1740 | # ============================================ 1741 | prepare_wordpress() { 1742 | echo -e "${YELLOW}๐Ÿ“ Preparing WordPress installer...${NC}" 1743 | 1744 | mkdir -p /var/www/html/wordpress 1745 | chown www-data:www-data /var/www/html 2>/dev/null || chown nginx:nginx /var/www/html 2>/dev/null || true 1746 | 1747 | cd /var/www/html 1748 | 1749 | if [ ! -f latest.zip ]; then 1750 | curl -O https://wordpress.org/latest.zip 2>/dev/null 1751 | fi 1752 | 1753 | unzip -o latest.zip > /dev/null 2>&1 1754 | rm -f /var/www/html/latest.zip 1755 | 1756 | # Create the FIXED installer script with proper database authentication 1757 | cat > /usr/local/bin/install-wordpress <<'EOF' 1758 | #!/bin/bash 1759 | 1760 | GREEN='\033[0;32m' 1761 | YELLOW='\033[1;33m' 1762 | RED='\033[0;31m' 1763 | NC='\033[0m' 1764 | 1765 | DOMAIN=$1 1766 | ENABLE_SSL=$2 1767 | PHP_VERSION=${3:-$(ls /etc/php/ 2>/dev/null | head -1)} 1768 | [ -z "$PHP_VERSION" ] && PHP_VERSION="8.2" 1769 | WP_PATH="/var/www/html" 1770 | WP_CONFIG="$WP_PATH/wordpress/wp-config.php" 1771 | MYSQL_CNF="/root/.my.cnf" 1772 | 1773 | if [ -z "$DOMAIN" ]; then 1774 | echo "Usage: install-wordpress domain.com [--ssl] [php-version]" 1775 | echo "Examples:" 1776 | echo " install-wordpress example.com" 1777 | echo " install-wordpress example.com --ssl" 1778 | exit 1 1779 | fi 1780 | 1781 | echo -e "${YELLOW}Installing WordPress for domain: $DOMAIN${NC}" 1782 | 1783 | # Ensure MariaDB is running 1784 | echo -n "Checking MariaDB... " 1785 | systemctl start mariadb 2>/dev/null 1786 | sleep 2 1787 | 1788 | if mysqladmin ping >/dev/null 2>&1; then 1789 | echo -e "${GREEN}โœ“${NC}" 1790 | else 1791 | echo -e "${RED}โœ—${NC}" 1792 | echo "Failed to start MariaDB. Please check: systemctl status mariadb" 1793 | exit 1 1794 | fi 1795 | 1796 | # Create WordPress directory 1797 | mkdir -p "$WP_PATH/wordpress" 1798 | 1799 | # Download WordPress if needed 1800 | cd "$WP_PATH" 1801 | if [ ! -f "$WP_PATH/wordpress/wp-config-sample.php" ]; then 1802 | echo "Downloading WordPress..." 1803 | curl -O https://wordpress.org/latest.zip 2>/dev/null 1804 | unzip -o latest.zip > /dev/null 2>&1 1805 | rm -f latest.zip 1806 | fi 1807 | 1808 | # Generate database name from domain 1809 | DB_NAME="wp_$(echo $DOMAIN | sed 's/\./_/g' | sed 's/-/_/g')" 1810 | DB_USER="user_$(openssl rand -hex 4 2>/dev/null | head -c8)" 1811 | DB_PASS=$(openssl rand -base64 24 2>/dev/null | tr -dc 'a-zA-Z0-9' | head -c20) 1812 | 1813 | # Fallback if random generation fails 1814 | if [ -z "$DB_PASS" ] || [ ${#DB_PASS} -lt 8 ]; then 1815 | DB_PASS="$(date +%s | sha256sum | base64 | head -c 20)" 1816 | fi 1817 | if [ -z "$DB_USER" ] || [ ${#DB_USER} -lt 4 ]; then 1818 | DB_USER="wpuser_$(date +%s | tail -c 5)" 1819 | fi 1820 | 1821 | echo -e "Creating database: ${YELLOW}$DB_NAME${NC}" 1822 | 1823 | # Drop existing database if exists (clean slate) 1824 | mysql --defaults-file="$MYSQL_CNF" -e "DROP DATABASE IF EXISTS \`$DB_NAME\`;" 2>/dev/null 1825 | 1826 | # Create database and user with proper permissions 1827 | mysql --defaults-file="$MYSQL_CNF" </dev/null; then 1836 | echo -e "${GREEN}โœ“ Database created and verified${NC}" 1837 | else 1838 | echo -e "${RED}โœ— Database verification failed. Trying alternative method...${NC}" 1839 | 1840 | # Alternative method using root with password 1841 | mysql --defaults-file="$MYSQL_CNF" </dev/null; then 1847 | echo -e "${GREEN}โœ“ Database verified with alternative method${NC}" 1848 | else 1849 | echo -e "${RED}โœ— Cannot connect to database. Please check manually.${NC}" 1850 | exit 1 1851 | fi 1852 | fi 1853 | 1854 | # Save credentials 1855 | echo "$DB_NAME:$DB_USER:$DB_PASS" > /root/.wp_db_credentials 1856 | chmod 600 /root/.wp_db_credentials 1857 | 1858 | cd "$WP_PATH/wordpress" 1859 | 1860 | if [ ! -f "wp-config-sample.php" ]; then 1861 | echo -e "${RED}Error: wp-config-sample.php not found${NC}" 1862 | exit 1 1863 | fi 1864 | 1865 | cp wp-config-sample.php wp-config.php 1866 | 1867 | # Update database credentials in wp-config.php 1868 | sed -i "s/database_name_here/$DB_NAME/" wp-config.php 1869 | sed -i "s/username_here/$DB_USER/" wp-config.php 1870 | sed -i "s/password_here/$DB_PASS/" wp-config.php 1871 | 1872 | # Add salts 1873 | echo "Adding security salts..." 1874 | SALTS=$(curl -s https://api.wordpress.org/secret-key/1.1/salt/ 2>/dev/null) 1875 | if [ -n "$SALTS" ]; then 1876 | # Remove existing salt defines 1877 | sed -i '/AUTH_KEY/d' wp-config.php 2>/dev/null 1878 | sed -i '/SECURE_AUTH_KEY/d' wp-config.php 2>/dev/null 1879 | sed -i '/LOGGED_IN_KEY/d' wp-config.php 2>/dev/null 1880 | sed -i '/NONCE_KEY/d' wp-config.php 2>/dev/null 1881 | sed -i '/AUTH_SALT/d' wp-config.php 2>/dev/null 1882 | sed -i '/SECURE_AUTH_SALT/d' wp-config.php 2>/dev/null 1883 | sed -i '/LOGGED_IN_SALT/d' wp-config.php 2>/dev/null 1884 | sed -i '/NONCE_SALT/d' wp-config.php 2>/dev/null 1885 | 1886 | # Insert salts before the "That's all" line 1887 | sed -i "/.*That's all.*/i $SALTS" wp-config.php 2>/dev/null 1888 | fi 1889 | 1890 | # Add performance optimizations 1891 | cat >> wp-config.php <<'EOL' 1892 | 1893 | /** Redis Cache Configuration */ 1894 | define('WP_REDIS_HOST', '127.0.0.1'); 1895 | define('WP_REDIS_PORT', 6379); 1896 | define('WP_REDIS_DATABASE', 0); 1897 | define('WP_REDIS_TIMEOUT', 1); 1898 | define('WP_REDIS_READ_TIMEOUT', 1); 1899 | 1900 | /** Memcached Configuration */ 1901 | global $memcached_servers; 1902 | $memcached_servers = array( 1903 | 'default' => array( 1904 | '127.0.0.1:11211' 1905 | ) 1906 | ); 1907 | 1908 | /** Performance Optimizations */ 1909 | define('WP_MEMORY_LIMIT', '256M'); 1910 | define('WP_MAX_MEMORY_LIMIT', '512M'); 1911 | define('WP_POST_REVISIONS', 5); 1912 | define('EMPTY_TRASH_DAYS', 7); 1913 | define('DISALLOW_FILE_EDIT', false); # Changed to false to enable theme/plugin editor 1914 | define('FS_METHOD', 'direct'); 1915 | define('AUTOMATIC_UPDATER_DISABLED', false); 1916 | define('WP_AUTO_UPDATE_CORE', 'minor'); 1917 | 1918 | /** Cache */ 1919 | define('WP_CACHE', true); 1920 | define('ENABLE_CACHE', true); 1921 | 1922 | /** Debug Mode */ 1923 | define('WP_DEBUG', false); 1924 | define('WP_DEBUG_LOG', false); 1925 | define('WP_DEBUG_DISPLAY', false); 1926 | EOL 1927 | 1928 | # Update Nginx configuration 1929 | if [ -f "/etc/nginx/sites-available/wordpress" ]; then 1930 | cp /etc/nginx/sites-available/wordpress /etc/nginx/sites-available/wordpress.backup 2>/dev/null 1931 | 1932 | sed -i "s/server_name _;/server_name $DOMAIN www.$DOMAIN;/" /etc/nginx/sites-available/wordpress 2>/dev/null 1933 | sed -i "s|root /var/www/html/wordpress;|root $WP_PATH/wordpress;|" /etc/nginx/sites-available/wordpress 2>/dev/null 1934 | 1935 | # Find and update PHP socket 1936 | PHP_SOCKET="unix:/run/php/php$PHP_VERSION-fpm.sock" 1937 | if [ ! -S "$PHP_SOCKET" ]; then 1938 | for sock in /run/php/php*-fpm.sock; do 1939 | if [ -S "$sock" ]; then 1940 | PHP_SOCKET="unix:$sock" 1941 | break 1942 | fi 1943 | done 1944 | fi 1945 | sed -i "s|unix:/run/php/php[0-9]\.[0-9]-fpm.sock|$PHP_SOCKET|g" /etc/nginx/sites-available/wordpress 2>/dev/null 1946 | fi 1947 | 1948 | # Test and reload Nginx 1949 | echo "Testing Nginx configuration..." 1950 | if nginx -t 2>/dev/null; then 1951 | systemctl reload nginx 2>/dev/null 1952 | echo -e "${GREEN}โœ“ Nginx configuration valid${NC}" 1953 | else 1954 | echo -e "${RED}โœ— Nginx configuration test failed${NC}" 1955 | nginx -t 1956 | fi 1957 | 1958 | # Set proper permissions 1959 | chown -R www-data:www-data "$WP_PATH/wordpress" 2>/dev/null || chown -R nginx:nginx "$WP_PATH/wordpress" 2>/dev/null || true 1960 | find "$WP_PATH/wordpress" -type d -exec chmod 755 {} \; 2>/dev/null 1961 | find "$WP_PATH/wordpress" -type f -exec chmod 644 {} \; 2>/dev/null 1962 | [ -d "$WP_PATH/wordpress/wp-content" ] && chmod 775 "$WP_PATH/wordpress/wp-content" 2>/dev/null 1963 | 1964 | # Install performance plugins (optional) 1965 | echo "Installing performance plugins..." 1966 | cd "$WP_PATH/wordpress" 1967 | mkdir -p wp-content/plugins 1968 | 1969 | for plugin in nginx-helper redis-cache w3-total-cache; do 1970 | curl -L "https://downloads.wordpress.org/plugin/$plugin.zip" -o "/tmp/$plugin.zip" 2>/dev/null 1971 | unzip -q "/tmp/$plugin.zip" -d wp-content/plugins/ 2>/dev/null || true 1972 | rm -f "/tmp/$plugin.zip" 2>/dev/null 1973 | done 1974 | 1975 | # Final verification 1976 | echo "" 1977 | echo "======================================================" 1978 | echo -e "${GREEN}โœ… WordPress installation completed for $DOMAIN${NC}" 1979 | echo "======================================================" 1980 | echo "" 1981 | echo "๐Ÿ“Š Database Information:" 1982 | echo " Database: $DB_NAME" 1983 | echo " Username: $DB_USER" 1984 | echo " Password: $DB_PASS" 1985 | echo "" 1986 | echo "๐Ÿ” Testing final database connection..." 1987 | if mysql -u "$DB_USER" -p"$DB_PASS" -e "USE \`$DB_NAME\`; SHOW TABLES;" 2>/dev/null; then 1988 | echo -e "${GREEN}โœ“ Database connection successful${NC}" 1989 | else 1990 | echo -e "${RED}โœ— Database connection failed${NC}" 1991 | fi 1992 | echo "" 1993 | echo "๐ŸŒ Site URL: http://$DOMAIN" 1994 | echo "๐Ÿ” Admin URL: http://$DOMAIN/wp-admin" 1995 | echo "" 1996 | echo "๐Ÿ“ Next steps:" 1997 | echo " 1. Complete WordPress installation at: http://$DOMAIN/wp-admin/install.php" 1998 | echo " 2. Use the database credentials above during installation" 1999 | echo " 3. After installation, you can change permalinks in Settings > Permalinks" 2000 | echo " The nginx configuration already supports pretty permalinks" 2001 | echo " 4. Theme/Plugin editor is ENABLED (DISALLOW_FILE_EDIT is set to false)" 2002 | echo " You can edit themes/plugins from WordPress admin" 2003 | echo "======================================================" 2004 | 2005 | # Enable SSL if requested 2006 | if [ "$ENABLE_SSL" = "--ssl" ]; then 2007 | echo "" 2008 | echo "๐Ÿ” Enabling SSL for $DOMAIN..." 2009 | 2010 | if nginx -t 2>/dev/null; then 2011 | certbot --nginx -d "$DOMAIN" -d "www.$DOMAIN" --non-interactive --agree-tos --email "admin@$DOMAIN" 2>/dev/null 2012 | if [ $? -eq 0 ]; then 2013 | echo -e "${GREEN}โœ“ SSL enabled for $DOMAIN${NC}" 2014 | echo "๐ŸŒ Your site is now available at: https://$DOMAIN" 2015 | else 2016 | echo -e "${RED}โœ— SSL installation failed. Run manually: certbot --nginx -d $DOMAIN${NC}" 2017 | fi 2018 | fi 2019 | fi 2020 | EOF 2021 | 2022 | chmod +x /usr/local/bin/install-wordpress 2023 | 2024 | echo -e "${GREEN} โœ… WordPress installer prepared and FIXED${NC}" 2025 | echo -e "${YELLOW} ๐Ÿ“Œ Run: install-wordpress yourdomain.com${NC}" 2026 | echo -e "${YELLOW} ๐Ÿ“Œ Run with SSL: install-wordpress yourdomain.com --ssl${NC}" 2027 | 2028 | if [ "$PKG_MODE" = true ]; then 2029 | mark_component_installed "wordpress-installer" "3.0" 2030 | fi 2031 | } 2032 | 2033 | # ============================================ 2034 | # Multi-site Panel Support - FIXED 2035 | # ============================================ 2036 | setup_panel() { 2037 | echo -e "${YELLOW}๐Ÿข Setting up multi-site panel support...${NC}" 2038 | 2039 | mkdir -p /var/www/sites 2040 | 2041 | cat > /usr/local/bin/easy-site <<'EOF' 2042 | #!/bin/bash 2043 | 2044 | GREEN='\033[0;32m' 2045 | YELLOW='\033[1;33m' 2046 | RED='\033[0;31m' 2047 | BLUE='\033[0;34m' 2048 | NC='\033[0m' 2049 | 2050 | SITES_DIR="/var/www/sites" 2051 | NGINX_AVAILABLE="/etc/nginx/sites-available" 2052 | NGINX_ENABLED="/etc/nginx/sites-enabled" 2053 | MYSQL_CNF="/root/.my.cnf" 2054 | 2055 | case "$1" in 2056 | create) 2057 | DOMAIN=$2 2058 | PHP_VERSION=${3:-$(ls /etc/php/ 2>/dev/null | head -1)} 2059 | [ -z "$PHP_VERSION" ] && PHP_VERSION="8.2" 2060 | 2061 | if [ -z "$DOMAIN" ]; then 2062 | echo -e "${RED}Error: Domain name required${NC}" 2063 | exit 1 2064 | fi 2065 | 2066 | SITE_DIR="$SITES_DIR/$DOMAIN" 2067 | echo -e "${YELLOW}Creating site for $DOMAIN...${NC}" 2068 | 2069 | mkdir -p "$SITE_DIR"/{public,logs,backups} 2070 | 2071 | cd "$SITE_DIR/public" 2072 | curl -O https://wordpress.org/latest.zip 2>/dev/null 2073 | unzip -o latest.zip > /dev/null 2>&1 2074 | mv wordpress/* . 2>/dev/null 2075 | rm -rf wordpress latest.zip 2076 | 2077 | DB_NAME="site_$(echo $DOMAIN | sed 's/\./_/g' | sed 's/-/_/g')" 2078 | DB_USER="user_$(openssl rand -hex 4 2>/dev/null | head -c8)" 2079 | DB_PASS=$(openssl rand -base64 24 2>/dev/null | tr -dc 'a-zA-Z0-9' | head -c20) 2080 | 2081 | # Fallback if random generation fails 2082 | [ -z "$DB_PASS" ] && DB_PASS="$(date +%s | sha256sum | base64 | head -c 20)" 2083 | [ -z "$DB_USER" ] && DB_USER="wpuser_$(date +%s | tail -c 5)" 2084 | 2085 | mysql --defaults-file="$MYSQL_CNF" -e "CREATE DATABASE IF NOT EXISTS \`$DB_NAME\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null 2086 | mysql --defaults-file="$MYSQL_CNF" -e "CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" 2>/dev/null 2087 | mysql --defaults-file="$MYSQL_CNF" -e "GRANT ALL PRIVILEGES ON \`$DB_NAME\`.* TO '$DB_USER'@'localhost';" 2>/dev/null 2088 | mysql --defaults-file="$MYSQL_CNF" -e "FLUSH PRIVILEGES;" 2>/dev/null 2089 | 2090 | cp wp-config-sample.php wp-config.php 2>/dev/null 2091 | sed -i "s/database_name_here/$DB_NAME/" wp-config.php 2>/dev/null 2092 | sed -i "s/username_here/$DB_USER/" wp-config.php 2>/dev/null 2093 | sed -i "s/password_here/$DB_PASS/" wp-config.php 2>/dev/null 2094 | curl -s https://api.wordpress.org/secret-key/1.1/salt/ 2>/dev/null >> wp-config.php 2095 | 2096 | cat >> wp-config.php <<'EOL' 2097 | 2098 | /** Redis Cache */ 2099 | define('WP_REDIS_HOST', '127.0.0.1'); 2100 | define('WP_REDIS_PORT', 6379); 2101 | define('WP_CACHE', true); 2102 | 2103 | /** Enable Theme/Plugin Editor */ 2104 | define('DISALLOW_FILE_EDIT', false); 2105 | EOL 2106 | 2107 | # Find PHP socket 2108 | PHP_SOCKET="unix:/run/php/php$PHP_VERSION-fpm.sock" 2109 | if [ ! -S "${PHP_SOCKET#unix:}" ]; then 2110 | for sock in /run/php/php*-fpm.sock; do 2111 | if [ -S "$sock" ]; then 2112 | PHP_SOCKET="unix:$sock" 2113 | break 2114 | fi 2115 | done 2116 | fi 2117 | 2118 | cat > "$NGINX_AVAILABLE/$DOMAIN" </dev/null || true; 2129 | 2130 | location / { 2131 | try_files \$uri \$uri/ /index.php?\$args; 2132 | } 2133 | 2134 | location ~ \.php$ { 2135 | include fastcgi_params; 2136 | fastcgi_pass $PHP_SOCKET; 2137 | fastcgi_index index.php; 2138 | fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; 2139 | } 2140 | 2141 | location ~ /\. { 2142 | deny all; 2143 | } 2144 | } 2145 | NGINXEOF 2146 | 2147 | ln -sf "$NGINX_AVAILABLE/$DOMAIN" "$NGINX_ENABLED/" 2148 | chown -R www-data:www-data "$SITE_DIR" 2>/dev/null || chown -R nginx:nginx "$SITE_DIR" 2>/dev/null || true 2149 | nginx -t 2>/dev/null && systemctl reload nginx 2>/dev/null 2150 | 2151 | cat > "$SITE_DIR/site-info.txt" </dev/null || echo "Enabled") 2177 | echo " DB:$DB | Editor: $EDITOR" 2178 | fi 2179 | fi 2180 | done 2181 | else 2182 | echo "No sites found" 2183 | fi 2184 | ;; 2185 | 2186 | delete) 2187 | DOMAIN=$2 2188 | if [ -z "$DOMAIN" ]; then 2189 | echo -e "${RED}Error: Domain name required${NC}" 2190 | exit 1 2191 | fi 2192 | 2193 | echo -e "${RED}โš ๏ธ Delete $DOMAIN? (y/n)${NC}" 2194 | read CONFIRM 2195 | if [ "$CONFIRM" = "y" ]; then 2196 | rm -f "$NGINX_AVAILABLE/$DOMAIN" "$NGINX_ENABLED/$DOMAIN" 2>/dev/null 2197 | rm -rf "$SITES_DIR/$DOMAIN" 2>/dev/null 2198 | nginx -t 2>/dev/null && systemctl reload nginx 2>/dev/null 2199 | echo -e "${GREEN}โœ… Site deleted${NC}" 2200 | fi 2201 | ;; 2202 | 2203 | enable-ssl) 2204 | DOMAIN=$2 2205 | EMAIL=${3:-"admin@$DOMAIN"} 2206 | 2207 | if [ -z "$DOMAIN" ]; then 2208 | echo -e "${RED}Error: Domain name required${NC}" 2209 | exit 1 2210 | fi 2211 | 2212 | echo -e "${YELLOW}๐Ÿ” Enabling SSL for $DOMAIN...${NC}" 2213 | certbot --nginx -d "$DOMAIN" -d "www.$DOMAIN" --non-interactive --agree-tos --email "$EMAIL" 2>/dev/null 2214 | 2215 | if [ $? -eq 0 ]; then 2216 | echo -e "${GREEN}โœ… SSL enabled for $DOMAIN${NC}" 2217 | fi 2218 | ;; 2219 | 2220 | *) 2221 | echo "EasyInstall Site Manager" 2222 | echo "" 2223 | echo "Commands:" 2224 | echo " create domain.com [php-version] - Create new WordPress site (Editor ENABLED)" 2225 | echo " list - List all sites" 2226 | echo " delete domain.com - Delete site" 2227 | echo " enable-ssl domain.com [email] - Enable SSL for site" 2228 | echo "" 2229 | echo "Examples:" 2230 | echo " easy-site create example.com" 2231 | echo " easy-site enable-ssl example.com" 2232 | echo "" 2233 | echo "Note: Theme/Plugin editor is ENABLED by default for all sites" 2234 | ;; 2235 | esac 2236 | EOF 2237 | 2238 | chmod +x /usr/local/bin/easy-site 2239 | echo -e "${GREEN} โœ… Multi-site panel configured (Theme Editor ENABLED)${NC}" 2240 | 2241 | if [ "$PKG_MODE" = true ]; then 2242 | mark_component_installed "panel" "3.0" 2243 | fi 2244 | } 2245 | 2246 | # ============================================ 2247 | # Backup System Setup - FIXED 2248 | # ============================================ 2249 | setup_backups() { 2250 | echo -e "${YELLOW}๐Ÿ’พ Setting up backup system...${NC}" 2251 | 2252 | mkdir -p /backups/{daily,weekly,monthly} 2253 | 2254 | cat > /usr/local/bin/easy-backup <<'EOF' 2255 | #!/bin/bash 2256 | 2257 | BACKUP_TYPE="${1:-weekly}" 2258 | BACKUP_DIR="/backups/$BACKUP_TYPE" 2259 | DATE=$(date +%Y%m%d-%H%M%S) 2260 | BACKUP_FILE="$BACKUP_DIR/backup-$DATE.tar.gz" 2261 | MYSQL_CNF="/root/.my.cnf" 2262 | 2263 | mkdir -p "$BACKUP_DIR" 2264 | 2265 | echo "Creating $BACKUP_TYPE backup: $BACKUP_FILE" 2266 | 2267 | tar -czf "$BACKUP_FILE" \ 2268 | /var/www/html \ 2269 | /etc/nginx \ 2270 | /etc/php \ 2271 | /etc/mysql \ 2272 | /etc/redis \ 2273 | /etc/fail2ban \ 2274 | /etc/modsecurity \ 2275 | 2>/dev/null || true 2276 | 2277 | if command -v mysqldump >/dev/null 2>&1; then 2278 | mysqldump --defaults-file="$MYSQL_CNF" --all-databases > "/backups/mysql-$DATE.sql" 2>/dev/null 2279 | tar -rf "$BACKUP_FILE" "/backups/mysql-$DATE.sql" 2>/dev/null 2280 | rm "/backups/mysql-$DATE.sql" 2>/dev/null 2281 | fi 2282 | 2283 | echo "Backup completed: $BACKUP_FILE" 2284 | echo "Size: $(du -h "$BACKUP_FILE" | cut -f1)" 2285 | 2286 | if [ "$BACKUP_TYPE" = "weekly" ]; then 2287 | ls -t $BACKUP_DIR/backup-* 2>/dev/null | tail -n +3 | xargs rm -f 2>/dev/null || true 2288 | fi 2289 | EOF 2290 | 2291 | chmod +x /usr/local/bin/easy-backup 2292 | 2293 | cat > /usr/local/bin/easy-restore <<'EOF' 2294 | #!/bin/bash 2295 | 2296 | echo "EasyInstall Restore Utility" 2297 | echo "===========================" 2298 | echo "" 2299 | echo "Available backups:" 2300 | ls -lh /backups/weekly/ 2>/dev/null || echo "No backups found" 2301 | echo "" 2302 | echo "To restore, use:" 2303 | echo " tar -xzf /backups/weekly/backup-FILE.tar.gz -C /" 2304 | echo "" 2305 | echo "Then restart services: systemctl restart nginx php*-fpm mariadb" 2306 | EOF 2307 | chmod +x /usr/local/bin/easy-restore 2308 | 2309 | mkdir -p /etc/cron.d 2310 | cat > /etc/cron.d/easy-backup < /dev/null 2>&1 2313 | # Weekly backup on Sunday at 3am 2314 | 0 3 * * 0 root /usr/local/bin/easy-backup weekly > /dev/null 2>&1 2315 | # Monthly backup on 1st at 4am 2316 | 0 4 1 * * root /usr/local/bin/easy-backup monthly > /dev/null 2>&1 2317 | EOF 2318 | 2319 | echo -e "${GREEN} โœ… Backup system configured${NC}" 2320 | 2321 | if [ "$PKG_MODE" = true ]; then 2322 | mark_component_installed "backup" "3.0" 2323 | fi 2324 | } 2325 | 2326 | # ============================================ 2327 | # Advanced Monitoring Setup - FIXED 2328 | # ============================================ 2329 | setup_advanced_monitoring() { 2330 | echo -e "${YELLOW}๐Ÿ“Š Setting up advanced monitoring...${NC}" 2331 | 2332 | if [ -f /etc/netdata/netdata.conf ]; then 2333 | sed -i 's/# bind to = \*/bind to = 0.0.0.0:19999/' /etc/netdata/netdata.conf 2>/dev/null 2334 | systemctl restart netdata 2>/dev/null 2335 | fi 2336 | 2337 | cat > /etc/systemd/system/glances.service <<'EOF' 2338 | [Unit] 2339 | Description=Glances 2340 | After=network.target 2341 | 2342 | [Service] 2343 | ExecStart=/usr/bin/glances -w -t 5 2344 | Restart=always 2345 | User=root 2346 | 2347 | [Install] 2348 | WantedBy=multi-user.target 2349 | EOF 2350 | 2351 | systemctl daemon-reload 2352 | systemctl enable glances 2>/dev/null || true 2353 | systemctl start glances 2>/dev/null || true 2354 | 2355 | cat > /usr/local/bin/advanced-monitor <<'EOF' 2356 | #!/bin/bash 2357 | 2358 | GREEN='\033[0;32m' 2359 | YELLOW='\033[1;33m' 2360 | RED='\033[0;31m' 2361 | NC='\033[0m' 2362 | 2363 | while true; do 2364 | clear 2365 | echo -e "${GREEN}=== Advanced Monitor (Press Ctrl+C to exit) ===${NC}" 2366 | echo "Last update: $(date)" 2367 | echo "" 2368 | 2369 | echo -e "${YELLOW}--- System Load ---${NC}" 2370 | uptime 2371 | echo "" 2372 | 2373 | echo -e "${YELLOW}--- Memory Usage ---${NC}" 2374 | free -h 2375 | echo "" 2376 | 2377 | echo -e "${YELLOW}--- Disk Usage ---${NC}" 2378 | df -h / | awk 'NR==2 {print "Usage: " $5 " of " $2}' 2379 | echo "" 2380 | 2381 | echo -e "${YELLOW}--- Top 5 CPU Processes ---${NC}" 2382 | ps aux --sort=-%cpu | head -6 | tail -5 2383 | echo "" 2384 | 2385 | echo -e "${YELLOW}--- Network Connections ---${NC}" 2386 | ss -tunap | wc -l | xargs echo "Total connections:" 2387 | echo "" 2388 | 2389 | echo -e "${YELLOW}--- Service Status ---${NC}" 2390 | for service in nginx php*-fpm mariadb redis-server memcached fail2ban autoheal netdata; do 2391 | if systemctl is-active --quiet $service 2>/dev/null; then 2392 | echo -e " ${GREEN}โœ“${NC} $service: running" 2393 | else 2394 | echo -e " ${RED}โœ—${NC} $service: stopped" 2395 | fi 2396 | done 2397 | echo "" 2398 | 2399 | echo "Press Ctrl+C to exit" 2400 | sleep 5 2401 | done 2402 | EOF 2403 | chmod +x /usr/local/bin/advanced-monitor 2404 | 2405 | echo -e "${GREEN} โœ… Advanced monitoring configured${NC}" 2406 | 2407 | if [ "$PKG_MODE" = true ]; then 2408 | mark_component_installed "monitoring" "3.0" 2409 | fi 2410 | } 2411 | 2412 | # ============================================ 2413 | # Advanced CDN Integration - FIXED 2414 | # ============================================ 2415 | setup_advanced_cdn() { 2416 | echo -e "${YELLOW}โ˜๏ธ Setting up CDN integration...${NC}" 2417 | 2418 | cat > /usr/local/bin/easy-cdn <<'EOF' 2419 | #!/bin/bash 2420 | 2421 | GREEN='\033[0;32m' 2422 | YELLOW='\033[1;33m' 2423 | RED='\033[0;31m' 2424 | NC='\033[0m' 2425 | 2426 | case "$1" in 2427 | cloudflare) 2428 | if [ -z "$2" ] || [ -z "$3" ]; then 2429 | echo "Usage: easy-cdn cloudflare domain.com email [api-key]" 2430 | echo "" 2431 | echo "This will guide you through Cloudflare setup" 2432 | exit 1 2433 | fi 2434 | DOMAIN=$2 2435 | EMAIL=$3 2436 | API_KEY=$4 2437 | 2438 | echo -e "${YELLOW}Setting up Cloudflare for $DOMAIN...${NC}" 2439 | 2440 | mkdir -p /root/.cloudflare 2441 | cat > /root/.cloudflare/$DOMAIN.conf </dev/null)" ]; then 2457 | for conf in /root/.cloudflare/*; do 2458 | if [ -f "$conf" ]; then 2459 | source "$conf" 2>/dev/null 2460 | echo " ๐ŸŒ $DOMAIN: Cloudflare configured" 2461 | fi 2462 | done 2463 | else 2464 | echo " No CDN configured" 2465 | fi 2466 | echo "" 2467 | echo "To configure CDN: easy-cdn cloudflare domain.com email [api-key]" 2468 | ;; 2469 | 2470 | purge) 2471 | echo -e "${YELLOW}Purging CDN cache...${NC}" 2472 | 2473 | rm -rf /var/cache/nginx/* 2474 | systemctl reload nginx 2>/dev/null 2475 | echo " Local nginx cache purged" 2476 | 2477 | echo -e "${GREEN}โœ… Cache purge completed${NC}" 2478 | ;; 2479 | 2480 | *) 2481 | echo "EasyInstall CDN Manager" 2482 | echo "" 2483 | echo "Commands:" 2484 | echo " cloudflare domain.com email [api-key] - Setup Cloudflare" 2485 | echo " status - CDN status report" 2486 | echo " purge - Purge all CDN caches" 2487 | echo "" 2488 | echo "Examples:" 2489 | echo " easy-cdn cloudflare example.com admin@example.com" 2490 | echo " easy-cdn purge" 2491 | ;; 2492 | esac 2493 | EOF 2494 | chmod +x /usr/local/bin/easy-cdn 2495 | echo -e "${GREEN} โœ… CDN integration configured${NC}" 2496 | 2497 | if [ "$PKG_MODE" = true ]; then 2498 | mark_component_installed "cdn" "3.0" 2499 | fi 2500 | } 2501 | 2502 | # ============================================ 2503 | # Email Configuration - FIXED 2504 | # ============================================ 2505 | setup_email() { 2506 | echo -e "${YELLOW}๐Ÿ“ง Setting up email configuration...${NC}" 2507 | 2508 | if command -v postconf >/dev/null 2>&1; then 2509 | postconf -e "myhostname=$(hostname -f 2>/dev/null || hostname)" 2>/dev/null 2510 | postconf -e "mydomain=$(hostname -d 2>/dev/null || echo 'local')" 2>/dev/null 2511 | postconf -e "myorigin=\$mydomain" 2>/dev/null 2512 | postconf -e "inet_interfaces=loopback-only" 2>/dev/null 2513 | postconf -e "mydestination=\$myhostname, localhost.\$mydomain, localhost" 2>/dev/null 2514 | postconf -e "mynetworks=127.0.0.0/8" 2>/dev/null 2515 | 2516 | systemctl restart postfix 2>/dev/null 2517 | echo -e "${GREEN} โœ… Postfix configured for local delivery${NC}" 2518 | else 2519 | echo -e "${YELLOW} โš ๏ธ Postfix not installed, skipping${NC}" 2520 | fi 2521 | 2522 | cat > /usr/local/bin/send-alert <<'EOF' 2523 | #!/bin/bash 2524 | 2525 | SUBJECT="$1" 2526 | MESSAGE="$2" 2527 | EMAIL="${3:-root@localhost}" 2528 | 2529 | echo "$MESSAGE" | mail -s "$SUBJECT" "$EMAIL" 2>/dev/null 2530 | echo "Alert sent to $EMAIL" 2531 | EOF 2532 | chmod +x /usr/local/bin/send-alert 2533 | 2534 | cat > /usr/local/bin/setup-telegram <<'EOF' 2535 | #!/bin/bash 2536 | 2537 | echo "Telegram Bot Setup" 2538 | echo "==================" 2539 | echo "" 2540 | echo "To setup Telegram alerts:" 2541 | echo "1. Open Telegram and search for @BotFather" 2542 | echo "2. Send /newbot and follow instructions to create a bot" 2543 | echo "3. Copy the bot token (looks like: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz)" 2544 | echo "4. Start a chat with your bot and send /start" 2545 | echo "5. Get your chat ID by visiting: https://api.telegram.org/bot/getUpdates" 2546 | echo "" 2547 | echo "Then create /root/.telegram.conf with:" 2548 | echo " TELEGRAM_BOT_TOKEN='your-bot-token'" 2549 | echo " TELEGRAM_CHAT_ID='your-chat-id'" 2550 | echo "" 2551 | echo "Example:" 2552 | echo " cat > /root/.telegram.conf < /usr/local/bin/easy-remote <<'EOF' 2575 | #!/bin/bash 2576 | 2577 | GREEN='\033[0;32m' 2578 | YELLOW='\033[1;33m' 2579 | RED='\033[0;31m' 2580 | NC='\033[0m' 2581 | 2582 | case "$1" in 2583 | add) 2584 | echo -e "${YELLOW}Configure remote storage:${NC}" 2585 | echo "" 2586 | echo "Available options:" 2587 | echo " 1) Google Drive (using rclone)" 2588 | echo " 2) Amazon S3 (using awscli)" 2589 | echo " 3) Backblaze B2" 2590 | echo " 4) Dropbox" 2591 | echo "" 2592 | read -p "Select option [1-4]: " OPTION 2593 | 2594 | case $OPTION in 2595 | 1) 2596 | echo "Setting up Google Drive..." 2597 | echo "Run: rclone config" 2598 | echo "Follow the prompts to configure Google Drive" 2599 | ;; 2600 | 2) 2601 | echo "Setting up Amazon S3..." 2602 | echo "Run: aws configure" 2603 | echo "Enter your AWS Access Key ID, Secret Key, and region" 2604 | ;; 2605 | 3) 2606 | echo "Setting up Backblaze B2..." 2607 | echo "Run: rclone config" 2608 | echo "Select 'b2' when prompted for storage type" 2609 | ;; 2610 | 4) 2611 | echo "Setting up Dropbox..." 2612 | echo "Run: rclone config" 2613 | echo "Select 'dropbox' when prompted for storage type" 2614 | ;; 2615 | *) 2616 | echo "Invalid option" 2617 | ;; 2618 | esac 2619 | ;; 2620 | 2621 | list) 2622 | echo -e "${YELLOW}Configured remotes:${NC}" 2623 | if command -v rclone >/dev/null 2>&1; then 2624 | rclone listremotes 2>/dev/null || echo " No remotes configured" 2625 | else 2626 | echo " rclone not installed" 2627 | fi 2628 | ;; 2629 | 2630 | status) 2631 | echo -e "${YELLOW}Remote storage status:${NC}" 2632 | echo "" 2633 | if command -v rclone >/dev/null 2>&1; then 2634 | for remote in $(rclone listremotes 2>/dev/null); do 2635 | echo " ๐Ÿ“ $remote" 2636 | rclone about $remote 2>/dev/null | head -3 || echo " Unable to get info" 2637 | done 2638 | else 2639 | echo " No remote storage configured" 2640 | fi 2641 | echo "" 2642 | echo "To add remote: easy-remote add" 2643 | ;; 2644 | 2645 | backup) 2646 | REMOTE=$2 2647 | if [ -z "$REMOTE" ]; then 2648 | echo "Usage: easy-remote backup remote-name" 2649 | exit 1 2650 | fi 2651 | 2652 | echo "Backing up to $REMOTE..." 2653 | LATEST_BACKUP=$(ls -t /backups/weekly/backup-*.tar.gz 2>/dev/null | head -1) 2654 | if [ -n "$LATEST_BACKUP" ]; then 2655 | echo "Uploading $LATEST_BACKUP to $REMOTE" 2656 | rclone copy "$LATEST_BACKUP" "$REMOTE:/easyinstall-backups/" 2>/dev/null && \ 2657 | echo "โœ… Backup uploaded" || echo "โŒ Upload failed" 2658 | else 2659 | echo "No backups found to upload" 2660 | fi 2661 | ;; 2662 | 2663 | *) 2664 | echo "EasyInstall Remote Storage Manager" 2665 | echo "" 2666 | echo "Commands:" 2667 | echo " add - Configure new remote storage" 2668 | echo " list - List configured remotes" 2669 | echo " status - Show remote storage status" 2670 | echo " backup remote - Upload latest backup to remote" 2671 | echo "" 2672 | echo "Examples:" 2673 | echo " easy-remote add" 2674 | echo " easy-remote backup gdrive:" 2675 | ;; 2676 | esac 2677 | EOF 2678 | chmod +x /usr/local/bin/easy-remote 2679 | 2680 | cat > /usr/local/bin/easy-report <<'EOF' 2681 | #!/bin/bash 2682 | 2683 | GREEN='\033[0;32m' 2684 | YELLOW='\033[1;33m' 2685 | RED='\033[0;31m' 2686 | BLUE='\033[0;34m' 2687 | NC='\033[0m' 2688 | 2689 | echo -e "${GREEN}=== System Performance Report ===${NC}" 2690 | echo "Date: $(date)" 2691 | echo "Hostname: $(hostname)" 2692 | echo "" 2693 | 2694 | echo -e "${YELLOW}--- System Uptime ---${NC}" 2695 | uptime 2696 | echo "" 2697 | 2698 | echo -e "${YELLOW}--- Memory Usage ---${NC}" 2699 | free -h 2700 | echo "" 2701 | 2702 | echo -e "${YELLOW}--- Disk Usage ---${NC}" 2703 | df -h / 2704 | echo "" 2705 | 2706 | echo -e "${YELLOW}--- Top 10 CPU Processes ---${NC}" 2707 | ps aux --sort=-%cpu | head -10 2708 | echo "" 2709 | 2710 | echo -e "${YELLOW}--- Top 10 Memory Processes ---${NC}" 2711 | ps aux --sort=-%mem | head -10 2712 | echo "" 2713 | 2714 | echo -e "${YELLOW}--- Service Status ---${NC}" 2715 | for service in nginx php*-fpm mariadb redis-server memcached fail2ban autoheal netdata; do 2716 | if systemctl is-active --quiet $service 2>/dev/null; then 2717 | echo " โœ… $service: running" 2718 | else 2719 | echo " โŒ $service: stopped" 2720 | fi 2721 | done 2722 | echo "" 2723 | 2724 | echo -e "${YELLOW}--- Redis Status ---${NC}" 2725 | if command -v redis-cli >/dev/null 2>&1; then 2726 | redis-cli INFO | grep -E "used_memory_human|total_connections_received|total_commands_processed" | head -3 || echo " Redis not responding" 2727 | fi 2728 | echo "" 2729 | 2730 | echo -e "${GREEN}=== End of Report ===${NC}" 2731 | EOF 2732 | chmod +x /usr/local/bin/easy-report 2733 | 2734 | echo -e "${GREEN} โœ… Remote storage configured${NC}" 2735 | 2736 | if [ "$PKG_MODE" = true ]; then 2737 | mark_component_installed "remote" "3.0" 2738 | fi 2739 | } 2740 | 2741 | # ============================================ 2742 | # Setup Management Commands - FIXED with new commands 2743 | # ============================================ 2744 | install_commands() { 2745 | echo -e "${YELLOW}๐Ÿ”ง Installing management commands...${NC}" 2746 | 2747 | mkdir -p /usr/local/bin 2748 | 2749 | cat > /usr/local/bin/easyinstall <<'EOF' 2750 | #!/bin/bash 2751 | 2752 | GREEN='\033[0;32m' 2753 | YELLOW='\033[1;33m' 2754 | RED='\033[0;31m' 2755 | BLUE='\033[0;34m' 2756 | PURPLE='\033[0;35m' 2757 | CYAN='\033[0;36m' 2758 | NC='\033[0m' 2759 | 2760 | VERSION="3.0" 2761 | 2762 | # Domain existence check function 2763 | check_domain_exists() { 2764 | local domain=$1 2765 | 2766 | # Check for existing nginx config 2767 | if [ -f "/etc/nginx/sites-available/${domain}" ] || [ -f "/etc/nginx/sites-enabled/${domain}" ]; then 2768 | return 0 2769 | fi 2770 | 2771 | # Check for WordPress installation 2772 | if [ -d "/var/www/html/${domain}" ] && [ -f "/var/www/html/${domain}/wp-config.php" ]; then 2773 | return 0 2774 | fi 2775 | 2776 | # Check for multisite installation 2777 | if [ -d "/var/www/sites/${domain}" ] && [ -f "/var/www/sites/${domain}/public/wp-config.php" ]; then 2778 | return 0 2779 | fi 2780 | 2781 | return 1 2782 | } 2783 | 2784 | get_php_version() { 2785 | if command -v php >/dev/null 2>&1; then 2786 | php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;' 2>/dev/null || echo "8.2" 2787 | else 2788 | echo "8.2" 2789 | fi 2790 | } 2791 | 2792 | show_help() { 2793 | echo -e "${PURPLE}โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" 2794 | echo -e "${GREEN}EasyInstall Enterprise Stack v$VERSION - Commands${NC}" 2795 | echo -e "${PURPLE}โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" 2796 | echo "" 2797 | 2798 | echo -e "${CYAN}๐ŸŒ WORDPRESS INSTALLATION${NC}" 2799 | echo " easyinstall domain example.com - Install WordPress without SSL" 2800 | echo " easyinstall domain example.com --ssl - Install WordPress with SSL" 2801 | echo " easyinstall create example.com - Install WordPress (multisite style)" 2802 | echo " easyinstall create example.com --ssl - Install WordPress with SSL (multisite style)" 2803 | echo "" 2804 | 2805 | echo -e "${CYAN}๐Ÿ˜ PHP SITE CREATION${NC}" 2806 | echo " easyinstall create example.com --php - Create PHP site without SSL" 2807 | echo " easyinstall create example.com --php --ssl - Create PHP site with SSL" 2808 | echo "" 2809 | 2810 | echo -e "${CYAN}๐ŸŒ HTML SITE CREATION${NC}" 2811 | echo " easyinstall create example.com --html - Create HTML site without SSL" 2812 | echo " easyinstall create example.com --html --ssl - Create HTML site with SSL" 2813 | echo "" 2814 | 2815 | echo -e "${CYAN}๐Ÿ”’ SSL MANAGEMENT${NC}" 2816 | echo " easyinstall site example.com --ssl=on - Enable SSL for any existing site" 2817 | echo " easyinstall site example.com --ssl=off - Disable SSL for any existing site (coming soon)" 2818 | echo " easyinstall ssl example.com [email] - Legacy SSL installation" 2819 | echo "" 2820 | 2821 | echo -e "${CYAN}๐Ÿ”Œ XML-RPC MANAGEMENT${NC}" 2822 | echo " easyinstall xmlrpc enable - Enable XML-RPC access" 2823 | echo " easyinstall xmlrpc disable - Disable/block XML-RPC access" 2824 | echo " easyinstall xmlrpc status - Show XML-RPC status" 2825 | echo " easyinstall xmlrpc test [domain] - Test XML-RPC endpoint" 2826 | echo "" 2827 | 2828 | echo -e "${CYAN}๐Ÿ’พ BACKUP & RESTORE${NC}" 2829 | echo " easyinstall backup [weekly] - Create backup (default: weekly)" 2830 | echo " easyinstall restore - Restore from backup" 2831 | echo " easyinstall remote add - Add external storage (GDrive/S3)" 2832 | echo " easyinstall remote list - List configured remotes" 2833 | echo " easyinstall remote status - Check remote status" 2834 | echo "" 2835 | 2836 | echo -e "${CYAN}๐Ÿ“Š MONITORING${NC}" 2837 | echo " easyinstall status - System status" 2838 | echo " easyinstall report - Advanced performance report" 2839 | echo " easyinstall logs [service] - View logs (nginx/php/mysql)" 2840 | echo " easyinstall monitor - Run advanced monitor" 2841 | echo " easyinstall telegram - Setup Telegram alerts" 2842 | echo "" 2843 | 2844 | echo -e "${CYAN}โ˜๏ธ CDN${NC}" 2845 | echo " easyinstall cdn cloudflare domain key email - Cloudflare setup" 2846 | echo " easyinstall cdn status - CDN status report" 2847 | echo " easyinstall cdn purge - Purge all CDN caches" 2848 | echo "" 2849 | 2850 | echo -e "${CYAN}๐Ÿข MULTI-SITE${NC}" 2851 | echo " easyinstall site create domain.com - Create new site (WordPress)" 2852 | echo " easyinstall site list - List all sites" 2853 | echo " easyinstall site delete domain.com - Delete site" 2854 | echo " easyinstall site enable-ssl domain.com - Enable SSL for site" 2855 | echo "" 2856 | 2857 | echo -e "${CYAN}โšก PERFORMANCE${NC}" 2858 | echo " easyinstall cache clear - Clear FastCGI cache" 2859 | echo " easyinstall redis flush - Flush Redis cache" 2860 | echo " easyinstall memcached flush - Flush Memcached" 2861 | echo " easyinstall restart [service] - Restart service" 2862 | echo "" 2863 | 2864 | echo -e "${CYAN}๐Ÿ›ก๏ธ SECURITY${NC}" 2865 | echo " easyinstall keys update - Update WordPress security keys" 2866 | echo " easyinstall fail2ban status - Check Fail2ban status" 2867 | echo " easyinstall waf status - Check ModSecurity status" 2868 | echo "" 2869 | 2870 | echo -e "${CYAN}๐Ÿ”ง SYSTEM${NC}" 2871 | echo " easyinstall update - Update system" 2872 | echo " easyinstall clean - Clean temp files" 2873 | echo " easyinstall help - Show this help" 2874 | echo "" 2875 | echo -e "${PURPLE}โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" 2876 | echo -e "${YELLOW}โš ๏ธ IMPORTANT: WordPress will ONLY be installed with 'domain' or 'create' commands${NC}" 2877 | echo -e "${YELLOW} Domain must be valid and not already exist on this server${NC}" 2878 | echo -e "${PURPLE}โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" 2879 | } 2880 | 2881 | # Parse main command 2882 | MAIN_COMMAND="$1" 2883 | 2884 | # Handle package manager commands first 2885 | case "$MAIN_COMMAND" in 2886 | --pkg-update|--pkg-remove|--pkg-status|--pkg-verify) 2887 | exit 0 2888 | ;; 2889 | esac 2890 | 2891 | # If no arguments, show help 2892 | if [ -z "$MAIN_COMMAND" ]; then 2893 | show_help 2894 | exit 0 2895 | fi 2896 | 2897 | # Handle regular commands 2898 | case "$MAIN_COMMAND" in 2899 | domain|create) 2900 | if [ -z "$2" ]; then 2901 | echo -e "${RED}Usage: easyinstall $MAIN_COMMAND yourdomain.com [--ssl] [--php|--html]${NC}" 2902 | exit 1 2903 | fi 2904 | DOMAIN=$2 2905 | USE_SSL="false" 2906 | SITE_TYPE="wordpress" 2907 | 2908 | shift 2 2909 | for arg in "$@"; do 2910 | case $arg in 2911 | --ssl) USE_SSL="true" ;; 2912 | --php) SITE_TYPE="php" ;; 2913 | --html) SITE_TYPE="html" ;; 2914 | -php=*) PHP_V="${arg#*=}" ;; 2915 | esac 2916 | done 2917 | 2918 | # Check if domain already exists 2919 | if check_domain_exists "$DOMAIN"; then 2920 | echo -e "${RED}โŒ Domain ${DOMAIN} already exists. Installation aborted.${NC}" 2921 | exit 1 2922 | fi 2923 | 2924 | # Execute based on site type 2925 | case $SITE_TYPE in 2926 | wordpress) 2927 | echo -e "${YELLOW}๐Ÿ“ฆ Installing WordPress for $DOMAIN...${NC}" 2928 | if [ -z "$PHP_V" ]; then 2929 | /usr/local/bin/install-wordpress "$DOMAIN" "$([ "$USE_SSL" = "true" ] && echo "--ssl")" 2930 | else 2931 | /usr/local/bin/install-wordpress "$DOMAIN" "$([ "$USE_SSL" = "true" ] && echo "--ssl")" "$PHP_V" 2932 | fi 2933 | ;; 2934 | php) 2935 | echo -e "${YELLOW}๐Ÿ˜ Creating PHP site for $DOMAIN...${NC}" 2936 | # Call PHP site creation function (will be handled by main script) 2937 | /usr/local/bin/easyinstall-internal php-site "$DOMAIN" "$USE_SSL" 2938 | ;; 2939 | html) 2940 | echo -e "${YELLOW}๐ŸŒ Creating HTML site for $DOMAIN...${NC}" 2941 | # Call HTML site creation function (will be handled by main script) 2942 | /usr/local/bin/easyinstall-internal html-site "$DOMAIN" "$USE_SSL" 2943 | ;; 2944 | esac 2945 | ;; 2946 | 2947 | site) 2948 | if [ -z "$2" ] || [ -z "$3" ]; then 2949 | echo -e "${RED}Usage: easyinstall site yourdomain.com --ssl=on|off${NC}" 2950 | exit 1 2951 | fi 2952 | DOMAIN=$2 2953 | SSL_ACTION=$3 2954 | 2955 | case $SSL_ACTION in 2956 | --ssl=on) 2957 | # Call SSL enable function 2958 | /usr/local/bin/easyinstall-internal enable-ssl "$DOMAIN" 2959 | ;; 2960 | --ssl=off) 2961 | echo -e "${RED}SSL disable not implemented yet${NC}" 2962 | ;; 2963 | *) 2964 | echo -e "${RED}Invalid option: $SSL_ACTION${NC}" 2965 | exit 1 2966 | ;; 2967 | esac 2968 | ;; 2969 | 2970 | xmlrpc) 2971 | shift 2972 | /usr/local/bin/xmlrpc-manager "$@" 2973 | ;; 2974 | 2975 | ssl) 2976 | if [ -z "$2" ]; then 2977 | echo -e "${RED}Usage: easyinstall ssl yourdomain.com [email]${NC}" 2978 | exit 1 2979 | fi 2980 | DOMAIN=$2 2981 | EMAIL=${3:-"admin@$DOMAIN"} 2982 | 2983 | echo -e "${YELLOW}๐Ÿ” Installing SSL for $DOMAIN...${NC}" 2984 | certbot --nginx -d "$DOMAIN" -d "www.$DOMAIN" --non-interactive --agree-tos --email "$EMAIL" 2>/dev/null 2985 | 2986 | if [ $? -eq 0 ]; then 2987 | echo -e "${GREEN}โœ… SSL installed${NC}" 2988 | else 2989 | echo -e "${RED}โŒ SSL installation failed${NC}" 2990 | fi 2991 | ;; 2992 | 2993 | backup) 2994 | /usr/local/bin/easy-backup "${2:-weekly}" 2995 | ;; 2996 | 2997 | restore) 2998 | /usr/local/bin/easy-restore 2999 | ;; 3000 | 3001 | remote) 3002 | shift 3003 | /usr/local/bin/easy-remote "$@" 3004 | ;; 3005 | 3006 | status) 3007 | echo -e "${YELLOW}๐Ÿ“Š System Status:${NC}" 3008 | echo -e "${PURPLE}โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€${NC}" 3009 | echo " โ€ข Nginx: $(systemctl is-active nginx 2>/dev/null || echo 'inactive')" 3010 | echo " โ€ข PHP-FPM: $(systemctl is-active php$(get_php_version)-fpm 2>/dev/null || echo 'inactive')" 3011 | echo " โ€ข MariaDB: $(systemctl is-active mariadb 2>/dev/null || echo 'inactive')" 3012 | echo " โ€ข Redis: $(systemctl is-active redis-server 2>/dev/null || echo 'inactive')" 3013 | echo " โ€ข Memcached: $(systemctl is-active memcached 2>/dev/null || echo 'inactive')" 3014 | echo " โ€ข Fail2ban: $(systemctl is-active fail2ban 2>/dev/null || echo 'inactive')" 3015 | echo " โ€ข Auto-heal: $(systemctl is-active autoheal 2>/dev/null || echo 'inactive')" 3016 | echo "" 3017 | echo " โ€ข Disk: $(df -h / | awk 'NR==2 {print $3"/"$2 " ("$5")"}')" 3018 | echo " โ€ข Memory: $(free -h | awk '/Mem:/ {print $3"/"$2}')" 3019 | echo " โ€ข Load: $(uptime | awk -F'load average:' '{print $2}')" 3020 | ;; 3021 | 3022 | report) 3023 | /usr/local/bin/easy-report 3024 | ;; 3025 | 3026 | monitor) 3027 | /usr/local/bin/advanced-monitor 3028 | ;; 3029 | 3030 | telegram) 3031 | /usr/local/bin/setup-telegram 3032 | ;; 3033 | 3034 | logs) 3035 | case "$2" in 3036 | nginx) tail -f /var/log/nginx/wordpress_*.log 2>/dev/null || tail -f /var/log/nginx/access.log 2>/dev/null || echo "No nginx logs found" ;; 3037 | php) tail -f /var/log/php*-fpm.log 2>/dev/null || echo "PHP logs not found" ;; 3038 | mysql) tail -f /var/log/mysql/error.log 2>/dev/null || echo "MySQL logs not found" ;; 3039 | *) echo "Usage: easyinstall logs [nginx|php|mysql]" ;; 3040 | esac 3041 | ;; 3042 | 3043 | cache) 3044 | if [ "$2" = "clear" ]; then 3045 | rm -rf /var/cache/nginx/* 3046 | systemctl reload nginx 2>/dev/null 3047 | echo -e "${GREEN}โœ… Nginx cache cleared${NC}" 3048 | else 3049 | echo "Usage: easyinstall cache clear" 3050 | fi 3051 | ;; 3052 | 3053 | redis) 3054 | if [ "$2" = "flush" ]; then 3055 | redis-cli FLUSHALL 2>/dev/null 3056 | echo -e "${GREEN}โœ… Redis cache flushed${NC}" 3057 | else 3058 | echo "Usage: easyinstall redis flush" 3059 | fi 3060 | ;; 3061 | 3062 | memcached) 3063 | if [ "$2" = "flush" ]; then 3064 | echo "flush_all" | nc localhost 11211 2>/dev/null 3065 | echo -e "${GREEN}โœ… Memcached flushed${NC}" 3066 | else 3067 | echo "Usage: easyinstall memcached flush" 3068 | fi 3069 | ;; 3070 | 3071 | keys) 3072 | if [ "$2" = "update" ]; then 3073 | /usr/local/bin/update-wp-keys 3074 | else 3075 | echo "Usage: easyinstall keys update" 3076 | fi 3077 | ;; 3078 | 3079 | fail2ban) 3080 | if [ "$2" = "status" ]; then 3081 | fail2ban-client status 2>/dev/null 3082 | else 3083 | echo "Usage: easyinstall fail2ban status" 3084 | fi 3085 | ;; 3086 | 3087 | waf) 3088 | if [ "$2" = "status" ]; then 3089 | if grep -q "modsecurity on" /etc/nginx/nginx.conf 2>/dev/null; then 3090 | echo -e "${GREEN}โœ… ModSecurity is enabled${NC}" 3091 | else 3092 | echo -e "${RED}โŒ ModSecurity is disabled${NC}" 3093 | fi 3094 | else 3095 | echo "Usage: easyinstall waf status" 3096 | fi 3097 | ;; 3098 | 3099 | cdn) 3100 | shift 3101 | /usr/local/bin/easy-cdn "$@" 3102 | ;; 3103 | 3104 | site-manager) 3105 | shift 3106 | /usr/local/bin/easy-site "$@" 3107 | ;; 3108 | 3109 | restart) 3110 | case "$2" in 3111 | nginx) systemctl restart nginx 2>/dev/null ;; 3112 | php) systemctl restart php*-fpm 2>/dev/null ;; 3113 | mysql) systemctl restart mariadb 2>/dev/null ;; 3114 | redis) systemctl restart redis-server 2>/dev/null ;; 3115 | memcached) systemctl restart memcached 2>/dev/null ;; 3116 | all|"") systemctl restart nginx php*-fpm mariadb redis-server memcached 2>/dev/null ;; 3117 | *) echo "Usage: easyinstall restart [nginx|php|mysql|redis|memcached|all]" ;; 3118 | esac 3119 | echo -e "${GREEN}โœ… Services restarted${NC}" 3120 | ;; 3121 | 3122 | clean) 3123 | echo -e "${YELLOW}๐Ÿงน Cleaning system...${NC}" 3124 | apt autoremove -y 2>/dev/null 3125 | apt autoclean 2>/dev/null 3126 | find /var/log -name "*.log" -mtime +30 -delete 2>/dev/null 3127 | echo -e "${GREEN}โœ… Cleanup completed${NC}" 3128 | ;; 3129 | 3130 | update) 3131 | echo -e "${YELLOW}๐Ÿ“ฆ Updating system...${NC}" 3132 | apt update 2>/dev/null 3133 | apt upgrade -y 2>/dev/null 3134 | echo -e "${GREEN}โœ… System updated${NC}" 3135 | ;; 3136 | 3137 | help) 3138 | show_help 3139 | ;; 3140 | 3141 | *) 3142 | echo -e "${RED}Unknown command: $MAIN_COMMAND${NC}" 3143 | echo "Run 'easyinstall help' for available commands" 3144 | exit 1 3145 | ;; 3146 | esac 3147 | EOF 3148 | 3149 | chmod +x /usr/local/bin/easyinstall 3150 | 3151 | # Create internal command handler for PHP/HTML site creation and SSL enable 3152 | cat > /usr/local/bin/easyinstall-internal <<'EOF' 3153 | #!/bin/bash 3154 | 3155 | GREEN='\033[0;32m' 3156 | YELLOW='\033[1;33m' 3157 | RED='\033[0;31m' 3158 | NC='\033[0m' 3159 | 3160 | COMMAND=$1 3161 | DOMAIN=$2 3162 | USE_SSL=$3 3163 | 3164 | case $COMMAND in 3165 | php-site) 3166 | echo -e "${YELLOW}๐Ÿ˜ Creating PHP site for $DOMAIN...${NC}" 3167 | 3168 | # Create site directory 3169 | SITE_DIR="/var/www/html/${DOMAIN}" 3170 | mkdir -p "$SITE_DIR" 3171 | 3172 | # Get PHP version 3173 | PHP_VERSION=$(ls /etc/php/ 2>/dev/null | head -1) 3174 | [ -z "$PHP_VERSION" ] && PHP_VERSION="8.2" 3175 | 3176 | # Create sample index.php 3177 | cat > "$SITE_DIR/index.php" < 3183 | 3184 | 3185 | 3186 | 3187 | 3188 | ${DOMAIN} 3189 | 3214 | 3215 | 3216 |

Welcome to

3217 | 3218 |
3219 |

This is a PHP site created with EasyInstall

3220 |

PHP Version:

3221 |

Server:

3222 |

Date:

3223 |
3224 | 3225 |

Edit this file at:

3226 | 3227 | 3228 | PHPEOF 3229 | 3230 | # Find PHP socket 3231 | PHP_SOCKET="unix:/run/php/php${PHP_VERSION}-fpm.sock" 3232 | if [ ! -S "${PHP_SOCKET#unix:}" ]; then 3233 | for sock in /run/php/php*-fpm.sock; do 3234 | if [ -S "$sock" ]; then 3235 | PHP_SOCKET="unix:$sock" 3236 | break 3237 | fi 3238 | done 3239 | fi 3240 | 3241 | # Create nginx config 3242 | cat > "/etc/nginx/sites-available/${DOMAIN}" </dev/null || true; 3256 | 3257 | location / { 3258 | try_files \$uri \$uri/ =404; 3259 | } 3260 | 3261 | location ~ \.php$ { 3262 | include fastcgi_params; 3263 | fastcgi_pass ${PHP_SOCKET}; 3264 | fastcgi_index index.php; 3265 | fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; 3266 | } 3267 | 3268 | location ~ /\. { 3269 | deny all; 3270 | } 3271 | 3272 | location = /favicon.ico { 3273 | log_not_found off; 3274 | access_log off; 3275 | } 3276 | 3277 | location = /robots.txt { 3278 | allow all; 3279 | log_not_found off; 3280 | access_log off; 3281 | } 3282 | } 3283 | NGINXEOF 3284 | 3285 | ln -sf "/etc/nginx/sites-available/${DOMAIN}" "/etc/nginx/sites-enabled/" 3286 | chown -R www-data:www-data "$SITE_DIR" 3287 | 3288 | # Test and reload nginx 3289 | if nginx -t 2>/dev/null; then 3290 | systemctl reload nginx 2>/dev/null 3291 | echo -e "${GREEN}โœ… Nginx configuration created${NC}" 3292 | else 3293 | echo -e "${RED}โŒ Nginx configuration test failed${NC}" 3294 | nginx -t 3295 | exit 1 3296 | fi 3297 | 3298 | # Enable SSL if requested 3299 | if [ "$USE_SSL" = "true" ]; then 3300 | echo -e "${YELLOW}๐Ÿ” Enabling SSL for ${DOMAIN}...${NC}" 3301 | certbot --nginx -d "$DOMAIN" -d "www.$DOMAIN" --non-interactive --agree-tos --email "admin@$DOMAIN" 2>/dev/null 3302 | 3303 | if [ $? -eq 0 ]; then 3304 | echo -e "${GREEN}โœ… SSL enabled for ${DOMAIN}${NC}" 3305 | else 3306 | echo -e "${RED}โŒ SSL installation failed${NC}" 3307 | fi 3308 | fi 3309 | 3310 | echo -e "${GREEN}โœ… PHP site created for ${DOMAIN}${NC}" 3311 | echo -e "${GREEN}๐ŸŒ URL: http://${DOMAIN}${NC}" 3312 | [ "$USE_SSL" = "true" ] && echo -e "${GREEN}๐Ÿ”’ Secure URL: https://${DOMAIN}${NC}" 3313 | ;; 3314 | 3315 | html-site) 3316 | echo -e "${YELLOW}๐ŸŒ Creating HTML site for $DOMAIN...${NC}" 3317 | 3318 | # Create site directory 3319 | SITE_DIR="/var/www/html/${DOMAIN}" 3320 | mkdir -p "$SITE_DIR" 3321 | 3322 | # Create sample index.html 3323 | cat > "$SITE_DIR/index.html" < 3325 | 3326 | 3327 | 3328 | 3329 | ${DOMAIN} 3330 | 3351 | 3352 | 3353 |

Welcome to ${DOMAIN}

3354 | 3355 |
3356 |

This is an HTML site created with EasyInstall

3357 |

Server: $(hostname)

3358 |

Date: $(date)

3359 |
3360 | 3361 |

Edit this file at: ${SITE_DIR}/index.html

3362 | 3363 | 3364 | HTMLEOF 3365 | 3366 | # Create nginx config for HTML site 3367 | cat > "/etc/nginx/sites-available/${DOMAIN}" </dev/null || true; 3381 | 3382 | location / { 3383 | try_files \$uri \$uri/ =404; 3384 | } 3385 | 3386 | location ~ /\. { 3387 | deny all; 3388 | } 3389 | 3390 | location = /favicon.ico { 3391 | log_not_found off; 3392 | access_log off; 3393 | } 3394 | 3395 | location = /robots.txt { 3396 | allow all; 3397 | log_not_found off; 3398 | access_log off; 3399 | } 3400 | } 3401 | NGINXEOF 3402 | 3403 | ln -sf "/etc/nginx/sites-available/${DOMAIN}" "/etc/nginx/sites-enabled/" 3404 | chown -R www-data:www-data "$SITE_DIR" 3405 | 3406 | # Test and reload nginx 3407 | if nginx -t 2>/dev/null; then 3408 | systemctl reload nginx 2>/dev/null 3409 | echo -e "${GREEN}โœ… Nginx configuration created${NC}" 3410 | else 3411 | echo -e "${RED}โŒ Nginx configuration test failed${NC}" 3412 | nginx -t 3413 | exit 1 3414 | fi 3415 | 3416 | # Enable SSL if requested 3417 | if [ "$USE_SSL" = "true" ]; then 3418 | echo -e "${YELLOW}๐Ÿ” Enabling SSL for ${DOMAIN}...${NC}" 3419 | certbot --nginx -d "$DOMAIN" -d "www.$DOMAIN" --non-interactive --agree-tos --email "admin@$DOMAIN" 2>/dev/null 3420 | 3421 | if [ $? -eq 0 ]; then 3422 | echo -e "${GREEN}โœ… SSL enabled for ${DOMAIN}${NC}" 3423 | else 3424 | echo -e "${RED}โŒ SSL installation failed${NC}" 3425 | fi 3426 | fi 3427 | 3428 | echo -e "${GREEN}โœ… HTML site created for ${DOMAIN}${NC}" 3429 | echo -e "${GREEN}๐ŸŒ URL: http://${DOMAIN}${NC}" 3430 | [ "$USE_SSL" = "true" ] && echo -e "${GREEN}๐Ÿ”’ Secure URL: https://${DOMAIN}${NC}" 3431 | ;; 3432 | 3433 | enable-ssl) 3434 | echo -e "${YELLOW}๐Ÿ” Enabling SSL for $DOMAIN...${NC}" 3435 | 3436 | # Check if domain exists 3437 | if [ ! -f "/etc/nginx/sites-available/${DOMAIN}" ]; then 3438 | echo -e "${RED}โŒ Domain ${DOMAIN} not found.${NC}" 3439 | exit 1 3440 | fi 3441 | 3442 | # Check if SSL already exists 3443 | if grep -q "listen 443 ssl" "/etc/nginx/sites-available/${DOMAIN}" 2>/dev/null; then 3444 | echo -e "${YELLOW}โš ๏ธ SSL already enabled for ${DOMAIN}${NC}" 3445 | exit 0 3446 | fi 3447 | 3448 | # Get SSL certificate 3449 | certbot --nginx -d "$DOMAIN" -d "www.$DOMAIN" --non-interactive --agree-tos --email "admin@$DOMAIN" 2>/dev/null 3450 | 3451 | if [ $? -eq 0 ]; then 3452 | echo -e "${GREEN}โœ… SSL enabled for ${DOMAIN}${NC}" 3453 | echo -e "${GREEN}๐Ÿ”’ Secure URL: https://${DOMAIN}${NC}" 3454 | else 3455 | echo -e "${RED}โŒ Failed to enable SSL for ${DOMAIN}${NC}" 3456 | exit 1 3457 | fi 3458 | ;; 3459 | 3460 | *) 3461 | echo -e "${RED}Unknown internal command${NC}" 3462 | exit 1 3463 | ;; 3464 | esac 3465 | EOF 3466 | 3467 | chmod +x /usr/local/bin/easyinstall-internal 3468 | 3469 | echo "alias e='easyinstall'" >> /root/.bashrc 3470 | echo "alias eb='easyinstall backup'" >> /root/.bashrc 3471 | echo "alias er='easyinstall restore'" >> /root/.bashrc 3472 | echo "alias es='easyinstall status'" >> /root/.bashrc 3473 | echo "alias ere='easyinstall report'" >> /root/.bashrc 3474 | 3475 | echo -e "${GREEN} โœ… Management commands installed${NC}" 3476 | 3477 | if [ "$PKG_MODE" = true ]; then 3478 | mark_component_installed "commands" "3.0" 3479 | fi 3480 | } 3481 | 3482 | # ============================================ 3483 | # Final Setup - FIXED 3484 | # ============================================ 3485 | finalize() { 3486 | echo -e "${YELLOW}๐ŸŽฏ Finalizing installation...${NC}" 3487 | 3488 | systemctl enable nginx 2>/dev/null 3489 | systemctl enable mariadb 2>/dev/null 3490 | systemctl enable redis-server 2>/dev/null 3491 | systemctl enable memcached 2>/dev/null 3492 | systemctl enable fail2ban 2>/dev/null 3493 | systemctl enable netdata 2>/dev/null 3494 | systemctl enable postfix 2>/dev/null 3495 | systemctl enable autoheal 2>/dev/null 3496 | systemctl enable glances 2>/dev/null || true 3497 | 3498 | if command -v php >/dev/null 2>&1; then 3499 | PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;' 2>/dev/null) 3500 | systemctl enable php$PHP_VERSION-fpm 2>/dev/null || true 3501 | fi 3502 | 3503 | # Run post-installation hooks if in package mode 3504 | if [ "$PKG_MODE" = true ] && [ -d "$PKG_HOOKS_DIR" ]; then 3505 | for hook in "$PKG_HOOKS_DIR"/*.sh; do 3506 | if [ -f "$hook" ]; then 3507 | echo -e "${BLUE} ๐Ÿ”ง Running hook: $(basename "$hook")${NC}" 3508 | bash "$hook" 3509 | fi 3510 | done 3511 | fi 3512 | 3513 | cat > /root/easyinstall-info.txt < Permalinks 3533 | Theme/Plugin Editor: ENABLED (DISALLOW_FILE_EDIT = false) 3534 | 3535 | PHP & HTML SITES: 3536 | PHP Site: easyinstall create example.com --php [--ssl] 3537 | HTML Site: easyinstall create example.com --html [--ssl] 3538 | 3539 | SSL MANAGEMENT: 3540 | Enable SSL: easyinstall site example.com --ssl=on 3541 | Legacy SSL: easyinstall ssl example.com [email] 3542 | 3543 | XML-RPC MANAGEMENT: 3544 | Commands: easyinstall xmlrpc enable|disable|status|test 3545 | Default: XML-RPC is ENABLED 3546 | Use 'easyinstall xmlrpc disable' to block for security 3547 | 3548 | BACKUP (Weekly only, Hybrid): 3549 | Local: Keep last 2 backups 3550 | External: All backups (when configured) 3551 | Command: easyinstall backup weekly 3552 | 3553 | AUTO-HEALING: 3554 | โ€ข Service monitoring every 60 seconds 3555 | โ€ข Auto-restart failed services 3556 | โ€ข Disk space monitoring 3557 | โ€ข Memory pressure detection 3558 | 3559 | SECURITY: 3560 | โ€ข ModSecurity WAF with OWASP rules (if installed) 3561 | โ€ข Enhanced Fail2ban WordPress rules 3562 | โ€ข Security headers enabled 3563 | โ€ข Monthly WordPress key rotation 3564 | โ€ข XML-RPC can be disabled via command 3565 | 3566 | PERFORMANCE: 3567 | โ€ข Redis Object Cache 3568 | โ€ข Memcached 3569 | โ€ข PHP OPcache enabled 3570 | โ€ข Nginx FastCGI cache 3571 | โ€ข Auto-tuned MySQL 3572 | 3573 | MAIN COMMANDS: 3574 | easyinstall domain example.com # Install WordPress for domain 3575 | easyinstall domain example.com --ssl # Install WordPress with SSL 3576 | easyinstall create example.com # Install WordPress (alternative) 3577 | easyinstall create example.com --ssl # Install WordPress with SSL (alternative) 3578 | easyinstall create example.com --php # Create PHP site 3579 | easyinstall create example.com --html # Create HTML site 3580 | easyinstall site example.com --ssl=on # Enable SSL for any site 3581 | easyinstall ssl example.com # Legacy SSL installation 3582 | easyinstall xmlrpc disable # Block XML-RPC for security 3583 | easyinstall xmlrpc enable # Re-enable XML-RPC 3584 | easyinstall xmlrpc status # Check XML-RPC status 3585 | easyinstall status # System status 3586 | easyinstall report # Performance report 3587 | easyinstall backup weekly # Create backup 3588 | easyinstall site create example.com # Create additional WordPress site (Editor ENABLED) 3589 | 3590 | โš ๏ธ IMPORTANT: 3591 | โ€ข WordPress will ONLY be installed with 'domain' or 'create' commands 3592 | โ€ข Domain must be valid and not already exist on this server 3593 | 3594 | DATABASE ROOT CREDENTIALS: 3595 | Username: root 3596 | Password: root 3597 | Config file: /root/.my.cnf 3598 | 3599 | FIREWALL: Ports 22, 80, 443, 19999, 61208 open 3600 | 3601 | PACKAGE MANAGER: 3602 | Installed as Debian package 3603 | State: $PKG_STATE_DIR/installed 3604 | Config: $PKG_CONFIG_DIR/config 3605 | 3606 | SUPPORT: https://paypal.me/sugandodrai 3607 | ======================================== 3608 | EOF 3609 | 3610 | echo -e "${GREEN}" 3611 | echo "============================================" 3612 | echo "โœ… Installation Complete! (v3.0)" 3613 | echo "============================================" 3614 | echo "" 3615 | 3616 | echo "๐Ÿ“Š Monitoring:" 3617 | echo " Netdata: http://$IP_ADDRESS:19999" 3618 | echo " Glances: http://$IP_ADDRESS:61208" 3619 | echo "" 3620 | echo "๐ŸŒ WordPress:" 3621 | echo " Not installed yet - Run: easyinstall domain yourdomain.com" 3622 | echo " With SSL: easyinstall domain yourdomain.com --ssl" 3623 | echo " Note: Nginx supports pretty permalinks - enable in WordPress Settings" 3624 | echo " Theme/Plugin Editor: ENABLED (You can edit themes/plugins from admin)" 3625 | echo "" 3626 | echo "๐Ÿ˜ PHP Sites:" 3627 | echo " Create: easyinstall create example.com --php" 3628 | echo " With SSL: easyinstall create example.com --php --ssl" 3629 | echo "" 3630 | echo "๐ŸŒ HTML Sites:" 3631 | echo " Create: easyinstall create example.com --html" 3632 | echo " With SSL: easyinstall create example.com --html --ssl" 3633 | echo "" 3634 | echo "๐Ÿ”’ SSL Management:" 3635 | echo " Enable SSL for any site: easyinstall site example.com --ssl=on" 3636 | echo "" 3637 | echo "๐Ÿ”Œ XML-RPC Management:" 3638 | echo " Default: XML-RPC is ENABLED" 3639 | echo " To disable (recommended for security): easyinstall xmlrpc disable" 3640 | echo " To re-enable: easyinstall xmlrpc enable" 3641 | echo " To check status: easyinstall xmlrpc status" 3642 | echo " To test: easyinstall xmlrpc test yourdomain.com" 3643 | echo "" 3644 | echo "๐Ÿ›ก๏ธ Security Features:" 3645 | echo " โ€ข ModSecurity WAF with OWASP rules (if installed)" 3646 | echo " โ€ข Enhanced Fail2ban WordPress protection" 3647 | echo " โ€ข Security headers enabled" 3648 | echo " โ€ข Monthly WordPress key rotation" 3649 | echo " โ€ข XML-RPC can be disabled via command" 3650 | echo "" 3651 | echo "โšก Performance Features:" 3652 | echo " โ€ข Redis + Memcached optimized" 3653 | echo " โ€ข Auto-tuned MySQL" 3654 | echo " โ€ข Adaptive PHP memory limits" 3655 | echo " โ€ข Official Nginx with FastCGI cache" 3656 | echo " โ€ข Pretty permalinks supported out of the box" 3657 | echo "" 3658 | echo "๐Ÿฅ Auto-healing: Enabled (monitors all services)" 3659 | echo "" 3660 | echo "โš ๏ธ IMPORTANT:" 3661 | echo " โ€ข WordPress will ONLY be installed with 'domain' or 'create' commands" 3662 | echo " โ€ข Domain must be valid and not already exist on this server" 3663 | echo "" 3664 | echo "๐Ÿ“ฆ Package Manager: Installed (use 'dpkg -r easyinstall' to remove)" 3665 | echo "" 3666 | echo "๐Ÿ”ง Available commands:" 3667 | echo " easyinstall help" 3668 | echo " easyinstall status" 3669 | echo " easyinstall domain example.com" 3670 | echo " easyinstall domain example.com --ssl" 3671 | echo " easyinstall create example.com" 3672 | echo " easyinstall create example.com --ssl" 3673 | echo " easyinstall create example.com --php" 3674 | echo " easyinstall create example.com --php --ssl" 3675 | echo " easyinstall create example.com --html" 3676 | echo " easyinstall create example.com --html --ssl" 3677 | echo " easyinstall site example.com --ssl=on" 3678 | echo " easyinstall xmlrpc disable" 3679 | echo " easyinstall xmlrpc status" 3680 | echo "" 3681 | echo -e "${GREEN}โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" 3682 | echo -e "${YELLOW}โ˜• Support: https://paypal.me/sugandodrai${NC}" 3683 | echo -e "${GREEN}โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" 3684 | echo "" 3685 | echo -e "${NC}" 3686 | 3687 | # Commit transaction if in package mode 3688 | if [ "$PKG_MODE" = true ]; then 3689 | commit_transaction "full-install" "3.0" 3690 | fi 3691 | } 3692 | 3693 | # ============================================ 3694 | # Main Execution - FIXED to handle commands properly 3695 | # ============================================ 3696 | main() { 3697 | # Parse command line arguments for package mode 3698 | while [[ $# -gt 0 ]]; do 3699 | case $1 in 3700 | --pkg-update|--pkg-remove|--pkg-status|--pkg-verify) 3701 | if [ "$PKG_MODE" = true ]; then 3702 | handle_package_command "$@" 3703 | exit $? 3704 | fi 3705 | shift 3706 | ;; 3707 | --force) 3708 | FORCE=true 3709 | shift 3710 | ;; 3711 | *) 3712 | # If we have arguments that look like commands, don't run full installation 3713 | if [[ "$1" =~ ^(domain|create|site|xmlrpc|ssl|backup|restore|remote|status|report|monitor|telegram|logs|cache|redis|memcached|keys|fail2ban|waf|cdn|site-manager|restart|clean|update|help)$ ]]; then 3714 | # Command will be handled by easyinstall script after installation 3715 | # We need to ensure easyinstall is installed first 3716 | if [ ! -f /usr/local/bin/easyinstall ]; then 3717 | echo -e "${YELLOW}EasyInstall not fully installed. Running full installation first...${NC}" 3718 | # Run full installation 3719 | setup_swap 3720 | kernel_tuning 3721 | install_packages 3722 | setup_modsecurity 3723 | setup_autoheal 3724 | setup_database 3725 | optimize_php 3726 | cleanup_nginx_config 3727 | configure_nginx 3728 | configure_redis_memcached 3729 | setup_fail2ban 3730 | prepare_wordpress 3731 | setup_security_keys_cron 3732 | setup_xmlrpc_commands 3733 | setup_backups 3734 | setup_advanced_monitoring 3735 | setup_advanced_cdn 3736 | setup_email 3737 | setup_panel 3738 | setup_remote 3739 | install_commands 3740 | finalize 3741 | fi 3742 | # Now execute the command 3743 | exec /usr/local/bin/easyinstall "$@" 3744 | fi 3745 | shift 3746 | ;; 3747 | esac 3748 | done 3749 | 3750 | # If no arguments or we reach here, run full installation 3751 | if [ $# -eq 0 ]; then 3752 | setup_swap 3753 | kernel_tuning 3754 | install_packages 3755 | setup_modsecurity 3756 | setup_autoheal 3757 | setup_database 3758 | optimize_php 3759 | cleanup_nginx_config 3760 | configure_nginx 3761 | configure_redis_memcached 3762 | setup_fail2ban 3763 | prepare_wordpress 3764 | setup_security_keys_cron 3765 | setup_xmlrpc_commands 3766 | setup_backups 3767 | setup_advanced_monitoring 3768 | setup_advanced_cdn 3769 | setup_email 3770 | setup_panel 3771 | setup_remote 3772 | install_commands 3773 | finalize 3774 | fi 3775 | } 3776 | 3777 | # Run main function with all arguments 3778 | main "$@" 3779 |