549d2b4d06
Changes: - Filter out system/template domains (cloudvpstemplate, cprapid, IP-based) - Skip domains under /nobody/ user - Test directly to server IP using --resolve (bypasses CDN/Cloudflare) - Show server IP being tested for transparency - Now correctly finds and tests actual user domains
2181 lines
75 KiB
Bash
Executable File
2181 lines
75 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
################################################################################
|
||
# Nginx + Varnish + Apache Caching Manager for cPanel
|
||
################################################################################
|
||
# Purpose: Complete setup and management of Nginx → Varnish → Apache stack
|
||
# Architecture: Client → Nginx (80/443) → Varnish (6081) → Apache (81/444)
|
||
# Stock Approach: Uses cPanel's ea-nginx + Apache on default ports
|
||
# Only modifies Nginx proxy target (81 → 6081)
|
||
# Features:
|
||
# - Full automated setup with domain testing
|
||
# - Revert/rollback functionality
|
||
# - Self-healing diagnostics and auto-fix
|
||
# - Smart memory allocation based on server resources
|
||
# - Configuration health checks
|
||
# - Backup/restore of all configurations
|
||
# - cPanel hook for auto-recovery after updates
|
||
################################################################################
|
||
|
||
set -eo pipefail
|
||
|
||
# Path resolution
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||
source "$SCRIPT_DIR/lib/common-functions.sh"
|
||
source "$SCRIPT_DIR/lib/system-detect.sh"
|
||
source "$SCRIPT_DIR/lib/reference-db.sh"
|
||
|
||
# Root check
|
||
if [ "$EUID" -ne 0 ]; then
|
||
print_error "This script must be run as root"
|
||
exit 1
|
||
fi
|
||
|
||
# Configuration
|
||
BACKUP_DIR="/root/nginx-varnish-backups"
|
||
VARNISH_VCL="/etc/varnish/default.vcl"
|
||
VARNISH_SERVICE="/usr/lib/systemd/system/varnish.service"
|
||
VARNISH_PORT="6081" # Varnish default port (stock)
|
||
APACHE_HTTP_PORT="81" # ea-nginx stock port (unchanged)
|
||
APACHE_HTTPS_PORT="444" # ea-nginx stock SSL port (unchanged)
|
||
NGINX_VENDOR_CONF="/etc/nginx/conf.d/includes-optional/cpanel-proxy-vendors/varnish-proxy.conf"
|
||
NGINX_CONFIG_SCRIPT="/etc/nginx/ea-nginx/config-scripts/global/varnish-integration.sh"
|
||
|
||
# Status indicators
|
||
STATUS_FILE="/root/.nginx-varnish-status"
|
||
HOOK_SCRIPT="/root/nginx-varnish-hook.sh"
|
||
HOOK_LOG="/var/log/nginx-varnish-hook.log"
|
||
|
||
################################################################################
|
||
# HELPER FUNCTIONS
|
||
################################################################################
|
||
|
||
# Check if cPanel Nginx is installed
|
||
check_nginx_installed() {
|
||
if rpm -q ea-nginx >/dev/null 2>&1; then
|
||
return 0
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Check if Varnish is installed
|
||
check_varnish_installed() {
|
||
if rpm -q varnish >/dev/null 2>&1; then
|
||
return 0
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Check if setup is already configured
|
||
check_if_configured() {
|
||
if [ -f "$STATUS_FILE" ] && grep -q "CONFIGURED=yes" "$STATUS_FILE" 2>/dev/null; then
|
||
return 0
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Get total system RAM in MB
|
||
get_total_ram_mb() {
|
||
free -m | awk '/^Mem:/{print $2}'
|
||
}
|
||
|
||
# Calculate recommended Varnish memory
|
||
calculate_varnish_memory() {
|
||
local total_ram=$(get_total_ram_mb)
|
||
local varnish_mem
|
||
|
||
# Allocate 10-20% of total RAM for Varnish, with sensible limits
|
||
if [ "$total_ram" -lt 2048 ]; then
|
||
# Less than 2GB RAM - use 256MB
|
||
varnish_mem=256
|
||
elif [ "$total_ram" -lt 4096 ]; then
|
||
# 2-4GB RAM - use 512MB
|
||
varnish_mem=512
|
||
elif [ "$total_ram" -lt 8192 ]; then
|
||
# 4-8GB RAM - use 1GB
|
||
varnish_mem=1024
|
||
elif [ "$total_ram" -lt 16384 ]; then
|
||
# 8-16GB RAM - use 2GB
|
||
varnish_mem=2048
|
||
else
|
||
# 16GB+ RAM - use 4GB
|
||
varnish_mem=4096
|
||
fi
|
||
|
||
echo "$varnish_mem"
|
||
}
|
||
|
||
# Create backup with timestamp
|
||
create_backup() {
|
||
local timestamp=$(date +%Y%m%d_%H%M%S)
|
||
local backup_path="$BACKUP_DIR/backup_$timestamp"
|
||
|
||
# Check disk space before backup
|
||
local available_space=$(df /root | tail -1 | awk '{print $4}')
|
||
if [ "$available_space" -lt 51200 ]; then
|
||
print_error "Insufficient disk space for backup (less than 50MB available)"
|
||
return 1
|
||
fi
|
||
|
||
mkdir -p "$backup_path"
|
||
|
||
# Backup Nginx configs if they exist
|
||
if [ -f /etc/nginx/ea-nginx.conf ]; then
|
||
cp -a /etc/nginx/ea-nginx.conf "$backup_path/" 2>/dev/null || true
|
||
fi
|
||
if [ -d /etc/nginx/conf.d ]; then
|
||
cp -a /etc/nginx/conf.d "$backup_path/" 2>/dev/null || true
|
||
fi
|
||
if [ -d /etc/nginx/ea-nginx ]; then
|
||
cp -a /etc/nginx/ea-nginx "$backup_path/" 2>/dev/null || true
|
||
fi
|
||
|
||
# Backup Varnish configs if they exist
|
||
if [ -f /etc/varnish/default.vcl ]; then
|
||
cp -a /etc/varnish/default.vcl "$backup_path/" 2>/dev/null || true
|
||
fi
|
||
if [ -f /usr/lib/systemd/system/varnish.service ]; then
|
||
cp -a /usr/lib/systemd/system/varnish.service "$backup_path/" 2>/dev/null || true
|
||
fi
|
||
|
||
# Backup Apache configs
|
||
if [ -f /var/cpanel/cpanel.config ]; then
|
||
cp -a /var/cpanel/cpanel.config "$backup_path/" 2>/dev/null || true
|
||
fi
|
||
|
||
echo "$backup_path"
|
||
}
|
||
|
||
# Get list of cPanel domains
|
||
get_cpanel_domains() {
|
||
local domains=()
|
||
|
||
# Get domains from cPanel user data
|
||
if [ -d /var/cpanel/userdata ]; then
|
||
while IFS= read -r domain_file; do
|
||
local domain=$(basename "$domain_file")
|
||
|
||
# Skip cache files, main file, and config files
|
||
if [[ "$domain_file" =~ \.cache$ ]] || \
|
||
[[ "$domain_file" =~ /cache$ ]] || \
|
||
[[ "$domain_file" =~ /main$ ]] || \
|
||
[[ "$domain" =~ _SSL$ ]] || \
|
||
[[ "$domain" =~ \.yaml$ ]] || \
|
||
[[ "$domain" =~ \.json$ ]] || \
|
||
[[ "$domain" =~ \.conf$ ]] || \
|
||
[[ "$domain" =~ \.backup$ ]]; then
|
||
continue
|
||
fi
|
||
|
||
# Skip system/template domains
|
||
if [[ "$domain" =~ cloudvpstemplate\. ]] || \
|
||
[[ "$domain" =~ cprapid\. ]] || \
|
||
[[ "$domain" =~ ^[0-9\-]+\. ]] || \
|
||
[[ "$domain_file" =~ /nobody/ ]]; then
|
||
continue
|
||
fi
|
||
|
||
# Only add if it looks like a domain (has a dot, not . or ..)
|
||
if [[ "$domain" != "." && "$domain" != ".." && "$domain" =~ \. ]]; then
|
||
domains+=("$domain")
|
||
fi
|
||
done < <(find /var/cpanel/userdata -type f 2>/dev/null | head -50)
|
||
fi
|
||
|
||
printf '%s\n' "${domains[@]}"
|
||
}
|
||
|
||
# Check if cPanel hook is registered
|
||
check_hook_registered() {
|
||
if [ -f /usr/local/cpanel/bin/manage_hooks ]; then
|
||
if /usr/local/cpanel/bin/manage_hooks list 2>/dev/null | grep -q "nginx-varnish-hook.sh"; then
|
||
return 0
|
||
fi
|
||
fi
|
||
return 1
|
||
}
|
||
|
||
# Modify ea-nginx settings.json to use Varnish port
|
||
modify_settings_json() {
|
||
local settings_file="/etc/nginx/ea-nginx/settings.json"
|
||
|
||
print_info "Modifying ea-nginx settings.json to use Varnish port..."
|
||
|
||
# Backup original settings.json
|
||
if [ ! -f "${settings_file}.stock" ]; then
|
||
cp "$settings_file" "${settings_file}.stock"
|
||
print_info "Original settings.json backed up to ${settings_file}.stock"
|
||
fi
|
||
|
||
# ============================================================================
|
||
# HTTP + HTTPS Caching Configuration
|
||
# ============================================================================
|
||
# Strategy: SSL termination at Nginx, HTTP backends to Varnish
|
||
#
|
||
# How it works:
|
||
# 1. settings.json sets apache_port to 6081 (Varnish) for HTTP traffic
|
||
# 2. ea-nginx generates config with $scheme://apache_backend_${scheme}_...
|
||
# 3. Config-script post-processes to force HTTP protocol for all backends
|
||
# 4. Result: SSL terminates at Nginx, all backend traffic uses HTTP to Varnish
|
||
#
|
||
# Architecture:
|
||
# - Client → Nginx (SSL termination for HTTPS) → Varnish → Apache (all HTTP)
|
||
# - HTTP: Client:80 → Nginx:80 → Varnish:6081 → Apache:81 [CACHED]
|
||
# - HTTPS: Client:443 → Nginx:443 (SSL) → Varnish:6081 (HTTP) → Apache:81 [CACHED]
|
||
#
|
||
# Note: Config-script at /etc/nginx/ea-nginx/config-scripts/global/ runs after
|
||
# every ea-nginx rebuild to maintain the HTTP backend override.
|
||
# ============================================================================
|
||
cat > "$settings_file" <<EOFSETTINGS
|
||
{
|
||
"apache_port" : "6081",
|
||
"apache_port_ip" : "127.0.0.1",
|
||
"apache_ssl_port" : "444",
|
||
"apache_ssl_port_ip" : "127.0.0.1",
|
||
"client_max_body_size" : "128m"
|
||
}
|
||
EOFSETTINGS
|
||
|
||
if grep -q '"apache_port" : "6081"' "$settings_file"; then
|
||
print_success "settings.json updated successfully"
|
||
echo ""
|
||
print_info "Configuration Applied:"
|
||
print_info " • HTTP traffic (port 80) → Varnish:6081 → Apache:81 [CACHED]"
|
||
print_info " • HTTPS traffic (port 443) → Varnish:6081 → Apache:81 [CACHED]"
|
||
echo ""
|
||
print_success "Both HTTP and HTTPS will be cached by Varnish"
|
||
print_info " Method: SSL termination at Nginx, HTTP backends to Varnish"
|
||
print_info " Safety: Config-script maintains configuration after ea-nginx rebuilds"
|
||
return 0
|
||
else
|
||
print_error "Failed to update settings.json"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Restore ea-nginx settings.json to stock
|
||
restore_settings_json() {
|
||
local settings_file="/etc/nginx/ea-nginx/settings.json"
|
||
|
||
print_info "Restoring ea-nginx settings.json to stock configuration..."
|
||
|
||
if [ -f "${settings_file}.stock" ]; then
|
||
cp "${settings_file}.stock" "$settings_file"
|
||
rm -f "${settings_file}.stock"
|
||
print_success "settings.json restored to stock (port 81)"
|
||
else
|
||
# Create stock settings if backup doesn't exist
|
||
cat > "$settings_file" <<EOFSETTINGS
|
||
{
|
||
"apache_port" : "81",
|
||
"apache_port_ip" : "127.0.0.1",
|
||
"apache_ssl_port" : "444",
|
||
"apache_ssl_port_ip" : "127.0.0.1",
|
||
"client_max_body_size" : "128m"
|
||
}
|
||
EOFSETTINGS
|
||
print_success "settings.json reset to stock defaults"
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
# Create ea-nginx config script for automatic recovery
|
||
create_eanginx_config_script() {
|
||
local config_script="/etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish"
|
||
|
||
print_info "Creating ea-nginx config script for automatic recovery..."
|
||
|
||
# Ensure directory exists
|
||
mkdir -p /etc/nginx/ea-nginx/config-scripts/global
|
||
|
||
# Create the config script
|
||
cat > "$config_script" <<'EOFSCRIPT'
|
||
#!/bin/bash
|
||
################################################################################
|
||
# ea-nginx Global Config Script: Varnish Proxy Auto-Fix
|
||
################################################################################
|
||
# Purpose: Automatically re-apply Varnish proxy configuration after ea-nginx
|
||
# config regeneration (runs every time ea-nginx config --global runs)
|
||
# Location: /etc/nginx/ea-nginx/config-scripts/global/
|
||
# Triggered by: ea-nginx config --global, ea-nginx config --all, cPanel updates
|
||
################################################################################
|
||
|
||
NGINX_CONF="/etc/nginx/conf.d/ea-nginx.conf"
|
||
STATUS_FILE="/root/.nginx-varnish-status"
|
||
LOG_FILE="/var/log/nginx-varnish-hook.log"
|
||
|
||
# Logging function
|
||
log_message() {
|
||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ea-nginx-config-script] $1" >> "$LOG_FILE"
|
||
}
|
||
|
||
log_message "=== ea-nginx Config Script Triggered ==="
|
||
|
||
# Check if Varnish integration is configured
|
||
if [ ! -f "$STATUS_FILE" ] || ! grep -q "CONFIGURED=yes" "$STATUS_FILE" 2>/dev/null; then
|
||
log_message "Varnish not configured. Skipping."
|
||
exit 0
|
||
fi
|
||
|
||
log_message "Varnish integration detected. Checking Nginx configuration..."
|
||
|
||
# Check if nginx conf exists
|
||
if [ ! -f "$NGINX_CONF" ]; then
|
||
log_message "ERROR: Nginx config file not found at $NGINX_CONF"
|
||
exit 0
|
||
fi
|
||
|
||
# Check if configuration needs fixing (ea-nginx regenerated it to stock port 81)
|
||
if grep -q "^\s*default\s\+81\s*;" "$NGINX_CONF" 2>/dev/null; then
|
||
log_message "DETECTED: ea-nginx.conf regenerated with stock port 81. Re-applying Varnish proxy (port 6081)..."
|
||
|
||
# Re-apply proxy port change to Varnish
|
||
if sed -i 's/^\(\s*default\s\+\)81\s*;/\16081;/' "$NGINX_CONF" 2>/dev/null; then
|
||
log_message "SUCCESS: Proxy port changed to 6081 (Varnish)"
|
||
else
|
||
log_message "ERROR: Failed to change proxy port to 6081"
|
||
fi
|
||
else
|
||
log_message "Configuration already correct (points to port 6081). No action needed."
|
||
fi
|
||
|
||
# ============================================================================
|
||
# Force HTTPS traffic to use HTTP backend protocol (enables HTTPS caching)
|
||
# ============================================================================
|
||
# This processes all per-domain configs to force HTTP backend for both
|
||
# HTTP and HTTPS traffic. Without this, HTTPS bypasses Varnish.
|
||
#
|
||
# Original: $scheme://apache_backend_${scheme}_IP (HTTP->HTTP, HTTPS->HTTPS)
|
||
# Modified: http://apache_backend_http_IP (both use HTTP backend)
|
||
# ============================================================================
|
||
|
||
log_message "Processing per-domain configs to force HTTP backend for HTTPS..."
|
||
|
||
domain_count=0
|
||
modified_count=0
|
||
|
||
# Process all per-domain config files
|
||
for config_file in /etc/nginx/conf.d/users/*.conf; do
|
||
[ -f "$config_file" ] || continue
|
||
domain_count=$((domain_count + 1))
|
||
|
||
# Check if this domain needs fixing (uses scheme-based backend)
|
||
if grep -q '\$scheme://apache_backend_\${scheme}_' "$config_file" 2>/dev/null; then
|
||
# Force HTTP backend protocol for all traffic (enables HTTPS caching)
|
||
if sed -i 's|\$scheme://apache_backend_\${\?scheme\?}_|http://apache_backend_http_|g' "$config_file" 2>/dev/null; then
|
||
modified_count=$((modified_count + 1))
|
||
fi
|
||
fi
|
||
done
|
||
|
||
if [ $modified_count -gt 0 ]; then
|
||
log_message "SUCCESS: Modified $modified_count of $domain_count domain configs to use HTTP backend"
|
||
log_message "HTTPS traffic now routes through Varnish (SSL terminates at Nginx, HTTP to backend)"
|
||
else
|
||
log_message "All $domain_count domain configs already use HTTP backend. No changes needed."
|
||
fi
|
||
|
||
log_message "=== Config Script Completed ==="
|
||
exit 0
|
||
EOFSCRIPT
|
||
|
||
chmod +x "$config_script"
|
||
|
||
if [ -f "$config_script" ] && [ -x "$config_script" ]; then
|
||
print_success "ea-nginx config script created successfully"
|
||
print_info "Script will auto-fix proxy port after ANY ea-nginx rebuild"
|
||
return 0
|
||
else
|
||
print_error "Failed to create ea-nginx config script"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Remove ea-nginx config script
|
||
remove_eanginx_config_script() {
|
||
local config_script="/etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish"
|
||
|
||
if [ -f "$config_script" ]; then
|
||
print_info "Removing ea-nginx config script..."
|
||
rm -f "$config_script"
|
||
print_success "ea-nginx config script removed"
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
################################################################################
|
||
# INSTALLATION FUNCTIONS
|
||
################################################################################
|
||
|
||
# Install cPanel Nginx
|
||
install_cpanel_nginx() {
|
||
print_banner "Installing cPanel Nginx"
|
||
|
||
# Fix hostname resolution for Apache RemoteIPInternalProxy
|
||
local server_hostname=$(hostname -f 2>/dev/null || hostname)
|
||
if [ -n "$server_hostname" ]; then
|
||
if ! grep -q "127.0.0.1.*$server_hostname" /etc/hosts 2>/dev/null; then
|
||
echo "Adding hostname to /etc/hosts for Apache configuration..."
|
||
echo "127.0.0.1 $server_hostname" >> /etc/hosts
|
||
print_info "Added $server_hostname to /etc/hosts"
|
||
fi
|
||
fi
|
||
|
||
echo ""
|
||
echo "Installing ea-nginx package..."
|
||
if yum install -y ea-nginx; then
|
||
print_success "ea-nginx installed successfully"
|
||
else
|
||
print_error "Failed to install ea-nginx"
|
||
return 1
|
||
fi
|
||
|
||
echo ""
|
||
echo "Rebuilding HTTP configuration..."
|
||
if /scripts/rebuildhttpdconf; then
|
||
print_success "HTTP configuration rebuilt"
|
||
else
|
||
print_error "Failed to rebuild HTTP configuration"
|
||
return 1
|
||
fi
|
||
|
||
echo ""
|
||
echo "Enabling and starting Nginx..."
|
||
systemctl enable nginx
|
||
systemctl restart nginx
|
||
|
||
if systemctl is-active --quiet nginx; then
|
||
print_success "Nginx is running"
|
||
else
|
||
print_error "Nginx failed to start"
|
||
return 1
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
# Install Varnish
|
||
install_varnish() {
|
||
print_banner "Installing Varnish Cache"
|
||
|
||
echo "Installing Varnish 6.6 from AlmaLinux repositories..."
|
||
echo "(Varnish 6.6 with VCL 4.1 support is fully compatible)"
|
||
echo ""
|
||
|
||
if yum install -y varnish; then
|
||
local varnish_version=$(varnishd -V 2>&1 | head -1)
|
||
print_success "Varnish installed successfully"
|
||
echo " Version: $varnish_version"
|
||
else
|
||
print_error "Failed to install Varnish"
|
||
return 1
|
||
fi
|
||
|
||
systemctl enable varnish
|
||
|
||
return 0
|
||
}
|
||
|
||
# Configure Varnish VCL
|
||
configure_varnish_vcl() {
|
||
print_banner "Configuring Varnish VCL"
|
||
|
||
# Get server's primary IP address for Apache backend
|
||
local server_ip=$(hostname -I | awk '{print $1}')
|
||
if [ -z "$server_ip" ]; then
|
||
server_ip="127.0.0.1"
|
||
print_warning "Could not detect server IP, using 127.0.0.1"
|
||
else
|
||
print_info "Detected server IP: $server_ip"
|
||
fi
|
||
|
||
# Simple VCL with comprehensive admin page bypasses
|
||
cat > "$VARNISH_VCL" <<'EOFVCL'
|
||
vcl 4.1;
|
||
|
||
# Backend definition - Apache on port 81 (ea-nginx stock port)
|
||
backend default {
|
||
.host = "SERVER_IP_PLACEHOLDER";
|
||
.port = "81";
|
||
.connect_timeout = 600s;
|
||
.first_byte_timeout = 600s;
|
||
.between_bytes_timeout = 600s;
|
||
}
|
||
|
||
sub vcl_recv {
|
||
# Normalize the host header
|
||
set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
|
||
|
||
# CRITICAL: AutoSSL / Let's Encrypt - Don't cache SSL validation
|
||
if (req.url ~ "^/\.well-known/acme-challenge/") {
|
||
return (pass);
|
||
}
|
||
|
||
# CRITICAL: cPanel Services - Don't cache cPanel admin interfaces
|
||
if (req.http.Host ~ "^(cpanel|webmail|whm|cpcalendars|cpcontacts)\." ||
|
||
req.http.Host ~ ":2082$" ||
|
||
req.http.Host ~ ":2083$" ||
|
||
req.http.Host ~ ":2086$" ||
|
||
req.http.Host ~ ":2087$") {
|
||
return (pipe);
|
||
}
|
||
|
||
# Don't cache admin/login pages for common CMSs and admin panels
|
||
if (req.url ~ "^/wp-admin" ||
|
||
req.url ~ "^/wp-login\.php" ||
|
||
req.url ~ "^/administrator" ||
|
||
req.url ~ "^/admin" ||
|
||
req.url ~ "^/user/login" ||
|
||
req.url ~ "^/cpanel" ||
|
||
req.url ~ "^/webmail" ||
|
||
req.url ~ "^/whm" ||
|
||
req.url ~ "^/phpmyadmin" ||
|
||
req.url ~ "^/pma" ||
|
||
req.url ~ "^/roundcube" ||
|
||
req.url ~ "^/horde" ||
|
||
req.url ~ "^/squirrelmail") {
|
||
return (pass);
|
||
}
|
||
|
||
# Don't cache POST requests
|
||
if (req.method == "POST") {
|
||
return (pass);
|
||
}
|
||
|
||
# Don't cache requests with cookies (except static files)
|
||
if (req.http.Cookie && req.url !~ "\.(jpg|jpeg|jpe|gif|png|ico|bmp|tif|tiff|svg|svgz|webp|avif|heic|heif|jfif|pjpeg|pjp|apng|css|js|mjs|map|woff|woff2|ttf|otf|eot|zip|tgz|gz|tar|rar|bz2|7z|xz|lz|lzma|pdf|txt|rtf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odp|csv|xml|json|mp3|mp4|m4a|m4v|ogg|oga|ogv|webm|wav|flac|aac|wma|opus|mid|midi|avi|mov|wmv|flv|mkv|mpeg|mpg|3gp|3g2|m2v|ts|m3u8|swf|html|htm|wasm|manifest|appcache|bin|exe|msi|dmg|iso|deb|rpm|cab)$") {
|
||
return (pass);
|
||
}
|
||
|
||
# Cache static files - remove cookies
|
||
if (req.url ~ "\.(jpg|jpeg|jpe|gif|png|ico|bmp|tif|tiff|svg|svgz|webp|avif|heic|heif|jfif|pjpeg|pjp|apng|css|js|mjs|map|woff|woff2|ttf|otf|eot|zip|tgz|gz|tar|rar|bz2|7z|xz|lz|lzma|pdf|txt|rtf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odp|csv|xml|json|mp3|mp4|m4a|m4v|ogg|oga|ogv|webm|wav|flac|aac|wma|opus|mid|midi|avi|mov|wmv|flv|mkv|mpeg|mpg|3gp|3g2|m2v|ts|m3u8|swf|html|htm|wasm|manifest|appcache|bin|exe|msi|dmg|iso|deb|rpm|cab)$") {
|
||
unset req.http.Cookie;
|
||
return (hash);
|
||
}
|
||
|
||
# Default: try to serve from cache
|
||
return (hash);
|
||
}
|
||
|
||
sub vcl_backend_fetch {
|
||
# CRITICAL: Preserve Host header for Apache VirtualHost routing
|
||
# Without this, Apache receives IP address and serves wrong VirtualHost
|
||
if (bereq.http.Host) {
|
||
set bereq.http.Host = bereq.http.Host;
|
||
}
|
||
}
|
||
|
||
sub vcl_backend_response {
|
||
# Add identifying header
|
||
set beresp.http.X-Served-By = "Varnish";
|
||
|
||
# Cache static files for 1 hour
|
||
if (bereq.url ~ "\.(jpg|jpeg|jpe|gif|png|ico|bmp|tif|tiff|svg|svgz|webp|avif|heic|heif|jfif|pjpeg|pjp|apng|css|js|mjs|map|woff|woff2|ttf|otf|eot|zip|tgz|gz|tar|rar|bz2|7z|xz|lz|lzma|pdf|txt|rtf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odp|csv|xml|json|mp3|mp4|m4a|m4v|ogg|oga|ogv|webm|wav|flac|aac|wma|opus|mid|midi|avi|mov|wmv|flv|mkv|mpeg|mpg|3gp|3g2|m2v|ts|m3u8|swf|html|htm|wasm|manifest|appcache|bin|exe|msi|dmg|iso|deb|rpm|cab)$") {
|
||
set beresp.ttl = 1h;
|
||
unset beresp.http.Set-Cookie;
|
||
}
|
||
|
||
# Don't cache if Set-Cookie is present (dynamic content)
|
||
if (beresp.http.Set-Cookie) {
|
||
set beresp.ttl = 0s;
|
||
set beresp.uncacheable = true;
|
||
return (deliver);
|
||
}
|
||
|
||
# Cache 404s for a short time to reduce backend load
|
||
if (beresp.status == 404) {
|
||
set beresp.ttl = 60s;
|
||
}
|
||
|
||
# Don't cache 5xx errors
|
||
if (beresp.status >= 500) {
|
||
set beresp.ttl = 0s;
|
||
set beresp.uncacheable = true;
|
||
return (deliver);
|
||
}
|
||
|
||
return (deliver);
|
||
}
|
||
|
||
sub vcl_deliver {
|
||
# Add cache status header for debugging
|
||
if (obj.hits > 0) {
|
||
set resp.http.X-Cache = "HIT";
|
||
set resp.http.X-Cache-Hits = obj.hits;
|
||
} else {
|
||
set resp.http.X-Cache = "MISS";
|
||
}
|
||
|
||
# Keep the Varnish identifier
|
||
set resp.http.X-Served-By = "Varnish";
|
||
|
||
# Remove internal headers before sending to client
|
||
unset resp.http.X-Varnish;
|
||
unset resp.http.Via;
|
||
unset resp.http.Age;
|
||
|
||
return (deliver);
|
||
}
|
||
EOFVCL
|
||
|
||
# Replace placeholder with actual server IP
|
||
sed -i "s/SERVER_IP_PLACEHOLDER/$server_ip/g" "$VARNISH_VCL"
|
||
|
||
# Test VCL configuration
|
||
# Note: /tmp is usually mounted with noexec on cPanel servers, so use -n parameter
|
||
# to specify a working directory outside /tmp
|
||
mkdir -p /var/lib/varnish/test
|
||
if varnishd -n /var/lib/varnish/test -C -f "$VARNISH_VCL" >/dev/null 2>&1; then
|
||
print_success "VCL configuration is valid"
|
||
return 0
|
||
else
|
||
print_error "VCL configuration is invalid"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Configure Varnish to listen on port 81
|
||
configure_varnish_port() {
|
||
local varnish_mem="${1:-256}"
|
||
|
||
print_banner "Configuring Varnish Port and Memory"
|
||
|
||
echo "Setting Varnish to listen on port $VARNISH_PORT with ${varnish_mem}m RAM..."
|
||
|
||
# Create systemd override directory
|
||
mkdir -p /etc/systemd/system/varnish.service.d/
|
||
|
||
# Create override configuration
|
||
cat > /etc/systemd/system/varnish.service.d/override.conf <<EOFSERVICE
|
||
[Service]
|
||
ExecStart=
|
||
ExecStart=/usr/sbin/varnishd -a :${VARNISH_PORT} -f /etc/varnish/default.vcl -s malloc,${varnish_mem}m
|
||
EOFSERVICE
|
||
|
||
systemctl daemon-reload
|
||
|
||
print_success "Varnish configured to use port $VARNISH_PORT with ${varnish_mem}m RAM"
|
||
|
||
return 0
|
||
}
|
||
|
||
# Configure Nginx to proxy to Varnish
|
||
configure_nginx_varnish_proxy() {
|
||
print_banner "Configuring Nginx to Proxy to Varnish"
|
||
|
||
# With settings.json approach, we just rebuild ea-nginx config
|
||
# ea-nginx reads settings.json (with apache_port = 6081) and generates correct config
|
||
echo "Rebuilding ea-nginx configuration from settings.json..."
|
||
if /usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1; then
|
||
print_success "ea-nginx configuration rebuilt"
|
||
else
|
||
print_warning "ea-nginx rebuild encountered issues (may still work)"
|
||
fi
|
||
|
||
# Verify the generated config
|
||
local nginx_conf="/etc/nginx/conf.d/ea-nginx.conf"
|
||
if grep -q "default 6081;" "$nginx_conf" 2>/dev/null; then
|
||
print_success "Nginx configured to proxy to Varnish (port 6081)"
|
||
else
|
||
print_warning "Proxy port may not be correct - check ea-nginx.conf"
|
||
fi
|
||
|
||
# Test Nginx configuration
|
||
if nginx -t >/dev/null 2>&1; then
|
||
print_success "Nginx configuration is valid"
|
||
return 0
|
||
else
|
||
print_error "Nginx configuration test failed"
|
||
nginx -t 2>&1 | tail -5
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Test domain accessibility
|
||
test_domain() {
|
||
local domain="$1"
|
||
local protocol="$2"
|
||
|
||
local url="${protocol}://${domain}"
|
||
local response=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$url" 2>/dev/null || echo "000")
|
||
local varnish_header=$(curl -s -I --max-time 5 "$url" 2>/dev/null | grep -i "X-Served-By" | grep -i "Varnish" || true)
|
||
|
||
if [ "$response" = "200" ] || [ "$response" = "301" ] || [ "$response" = "302" ]; then
|
||
if [ -n "$varnish_header" ]; then
|
||
echo "✓ $domain ($protocol): $response - Varnish active"
|
||
return 0
|
||
else
|
||
echo "⚠ $domain ($protocol): $response - No Varnish header"
|
||
return 0 # Don't crash the script
|
||
fi
|
||
else
|
||
echo "✗ $domain ($protocol): $response"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Quick proof that caching is actually working
|
||
proof_of_caching() {
|
||
print_banner "Proof of Caching Test"
|
||
|
||
echo "This test proves caching is working by showing MISS → HIT pattern"
|
||
echo ""
|
||
|
||
# Get first domain
|
||
local domain=$(get_cpanel_domains | head -1)
|
||
|
||
if [ -z "$domain" ]; then
|
||
print_error "No domains found to test"
|
||
echo ""
|
||
echo "Tip: Make sure you have at least one active domain/website configured"
|
||
return 0
|
||
fi
|
||
|
||
# Get server IP for direct testing (bypasses CDN)
|
||
local server_ip=$(hostname -I | awk '{print $1}')
|
||
|
||
echo "Testing domain: $domain"
|
||
echo "Server IP: $server_ip (testing direct to bypass CDN)"
|
||
echo ""
|
||
|
||
# Test common static files
|
||
local test_files=(
|
||
"/robots.txt"
|
||
"/favicon.ico"
|
||
"/"
|
||
)
|
||
|
||
local cache_working=0
|
||
|
||
for test_path in "${test_files[@]}"; do
|
||
local url="http://${domain}${test_path}"
|
||
|
||
echo "Testing: $test_path"
|
||
|
||
# First request - should be MISS
|
||
# Use --resolve to bypass CDN and test directly to server
|
||
local first_request=$(curl -s -I --max-time 5 --resolve "${domain}:80:${server_ip}" "$url" 2>/dev/null)
|
||
local first_cache=$(echo "$first_request" | grep -i "X-Cache:" | awk '{print $2}' | tr -d '\r')
|
||
|
||
# Second request - should be HIT
|
||
sleep 0.5
|
||
local second_request=$(curl -s -I --max-time 5 --resolve "${domain}:80:${server_ip}" "$url" 2>/dev/null)
|
||
local second_cache=$(echo "$second_request" | grep -i "X-Cache:" | awk '{print $2}' | tr -d '\r')
|
||
|
||
# Check if we got valid responses
|
||
if [ -z "$first_cache" ] || [ -z "$second_cache" ]; then
|
||
echo " Status: Skipped (no cache headers)"
|
||
echo ""
|
||
continue
|
||
fi
|
||
|
||
# Display results
|
||
echo " Request 1: X-Cache: $first_cache"
|
||
echo " Request 2: X-Cache: $second_cache"
|
||
|
||
# Check if caching worked
|
||
if [ "$first_cache" = "MISS" ] && [ "$second_cache" = "HIT" ]; then
|
||
print_success " ✓ CACHING WORKS! (MISS → HIT)"
|
||
cache_working=1
|
||
elif [ "$second_cache" = "HIT" ]; then
|
||
print_success " ✓ Cache HIT detected"
|
||
cache_working=1
|
||
elif [ "$first_cache" = "MISS" ] && [ "$second_cache" = "MISS" ]; then
|
||
print_warning " ⚠ No caching (both MISS) - may be dynamic content"
|
||
else
|
||
print_info " ℹ Status: $first_cache → $second_cache"
|
||
fi
|
||
|
||
echo ""
|
||
done
|
||
|
||
echo "════════════════════════════════════════════════════════════"
|
||
|
||
if [ "$cache_working" -eq 1 ]; then
|
||
echo ""
|
||
print_success "✓ PROOF CONFIRMED: Varnish is caching your sites!"
|
||
echo ""
|
||
echo "What this means:"
|
||
echo " • Static files are being cached by Varnish"
|
||
echo " • Repeat visitors get instant responses from cache"
|
||
echo " • Server load is reduced for cached content"
|
||
echo ""
|
||
else
|
||
echo ""
|
||
print_warning "⚠ Could not confirm caching"
|
||
echo ""
|
||
echo "Possible reasons:"
|
||
echo " • Tested URLs are dynamic (admin pages, etc.)"
|
||
echo " • Cache was already populated (no MISS seen)"
|
||
echo " • Try option 7 to clear cache, then test again"
|
||
echo ""
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
################################################################################
|
||
# DIAGNOSTIC FUNCTIONS
|
||
################################################################################
|
||
|
||
# Run comprehensive diagnostics
|
||
run_diagnostics() {
|
||
print_banner "Nginx + Varnish Health Check"
|
||
|
||
local issues_found=0
|
||
|
||
echo "Checking service status..."
|
||
echo ""
|
||
|
||
# Check Nginx
|
||
if systemctl is-active --quiet nginx; then
|
||
print_success "Nginx is running"
|
||
else
|
||
print_error "Nginx is not running"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
# Check Varnish
|
||
if systemctl is-active --quiet varnish; then
|
||
print_success "Varnish is running"
|
||
|
||
# Check if enabled for auto-start on boot
|
||
if ! systemctl is-enabled --quiet varnish 2>/dev/null; then
|
||
print_warning "Varnish is NOT enabled (won't start on reboot)"
|
||
print_info " Run 'Auto-Fix Issues' to enable auto-start"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
else
|
||
print_error "Varnish is not running"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
# Check Apache
|
||
if systemctl is-active --quiet httpd; then
|
||
print_success "Apache is running"
|
||
else
|
||
print_error "Apache is not running"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
echo ""
|
||
echo "Checking port configuration..."
|
||
echo ""
|
||
|
||
# Check ports using ss (more reliable) or netstat as fallback
|
||
if command -v ss >/dev/null 2>&1; then
|
||
# Use ss if available
|
||
if ss -tlnp 2>/dev/null | grep -E ":80\s.*nginx" >/dev/null; then
|
||
print_success "Nginx listening on port 80"
|
||
else
|
||
print_error "Nginx not listening on port 80"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
if ss -tlnp 2>/dev/null | grep -E ":443\s.*nginx" >/dev/null; then
|
||
print_success "Nginx listening on port 443"
|
||
else
|
||
print_error "Nginx not listening on port 443"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
if ss -tlnp 2>/dev/null | grep -E ":${VARNISH_PORT}\s.*varnish" >/dev/null; then
|
||
print_success "Varnish listening on port $VARNISH_PORT"
|
||
else
|
||
print_error "Varnish not listening on port $VARNISH_PORT"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
if ss -tlnp 2>/dev/null | grep -E ":${APACHE_HTTP_PORT}\s.*httpd" >/dev/null; then
|
||
print_success "Apache listening on port $APACHE_HTTP_PORT"
|
||
else
|
||
print_error "Apache not listening on port $APACHE_HTTP_PORT"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
else
|
||
# Fallback to netstat with better patterns
|
||
if netstat -tlnp 2>/dev/null | awk '$4 ~ /:80$/ && $7 ~ /nginx/' | head -1 | grep -q .; then
|
||
print_success "Nginx listening on port 80"
|
||
else
|
||
print_error "Nginx not listening on port 80"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
if netstat -tlnp 2>/dev/null | awk '$4 ~ /:443$/ && $7 ~ /nginx/' | head -1 | grep -q .; then
|
||
print_success "Nginx listening on port 443"
|
||
else
|
||
print_error "Nginx not listening on port 443"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
if netstat -tlnp 2>/dev/null | awk -v port="$VARNISH_PORT" '$4 ~ ":"port"$" && $7 ~ /varnish/' | head -1 | grep -q .; then
|
||
print_success "Varnish listening on port $VARNISH_PORT"
|
||
else
|
||
print_error "Varnish not listening on port $VARNISH_PORT"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
if netstat -tlnp 2>/dev/null | awk -v port="$APACHE_HTTP_PORT" '$4 ~ ":"port"$" && $7 ~ /httpd/' | head -1 | grep -q .; then
|
||
print_success "Apache listening on port $APACHE_HTTP_PORT"
|
||
else
|
||
print_error "Apache not listening on port $APACHE_HTTP_PORT"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
fi
|
||
|
||
echo ""
|
||
echo "Checking configuration files..."
|
||
echo ""
|
||
|
||
# Check VCL - use varnishadm instead of varnishd -C (more reliable)
|
||
if [ -f "$VARNISH_VCL" ]; then
|
||
if varnishadm vcl.list 2>/dev/null | grep -q "active.*warm"; then
|
||
print_success "Varnish VCL is loaded and active"
|
||
else
|
||
print_warning "Varnish VCL may not be active"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
else
|
||
print_error "Varnish VCL file not found"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
# Check Nginx config
|
||
if nginx -t 2>&1 | grep -q "successful"; then
|
||
print_success "Nginx configuration is valid"
|
||
else
|
||
print_error "Nginx configuration has errors"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
# Check settings.json configuration
|
||
if [ -f /etc/nginx/ea-nginx/settings.json ]; then
|
||
if grep -q "\"apache_port\" : \"${VARNISH_PORT}\"" /etc/nginx/ea-nginx/settings.json; then
|
||
print_success "settings.json configured for Varnish (port ${VARNISH_PORT})"
|
||
else
|
||
print_error "settings.json not configured for Varnish"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
else
|
||
print_error "settings.json not found"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
# Check ea-nginx.conf proxy configuration for HTTP
|
||
if [ -f /etc/nginx/conf.d/ea-nginx.conf ]; then
|
||
if grep -q "default ${VARNISH_PORT};" /etc/nginx/conf.d/ea-nginx.conf; then
|
||
print_success "ea-nginx.conf proxies HTTP to Varnish (port ${VARNISH_PORT})"
|
||
else
|
||
print_warning "ea-nginx.conf may not be proxying to Varnish"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
# Check HTTPS configuration
|
||
if grep -q "\"apache_ssl_port\" : \"444\"" /etc/nginx/ea-nginx/settings.json 2>/dev/null; then
|
||
print_success "HTTPS backend configured correctly (Apache:444)"
|
||
print_info " Note: Config-script forces HTTP protocol for Varnish caching"
|
||
|
||
# Verify config-script has applied HTTP backend override
|
||
if grep -q 'set $CPANEL_APACHE_PROXY_PASS http://apache_backend_http_' /etc/nginx/conf.d/users/*.conf 2>/dev/null; then
|
||
print_success " ✓ HTTPS traffic routed through Varnish (HTTP protocol)"
|
||
else
|
||
print_warning " ⚠ Config-script override not detected - HTTPS may not cache"
|
||
print_info " Run 'Auto-Fix Issues' to apply config-script"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
fi
|
||
else
|
||
print_error "ea-nginx.conf not found"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
|
||
echo ""
|
||
echo "Checking Varnish backend health..."
|
||
echo ""
|
||
|
||
if command -v varnishadm >/dev/null 2>&1; then
|
||
if varnishadm backend.list 2>/dev/null | grep -qi "healthy"; then
|
||
print_success "Varnish backend is healthy"
|
||
else
|
||
print_warning "Varnish backend may not be healthy"
|
||
issues_found=$((issues_found + 1))
|
||
fi
|
||
fi
|
||
|
||
echo ""
|
||
echo "Checking configuration persistence..."
|
||
echo ""
|
||
|
||
# Check if config-script safety net exists
|
||
if [ -f /etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish ]; then
|
||
print_success "Config-script safety net installed"
|
||
print_info " Auto-fixes if settings.json is overwritten"
|
||
else
|
||
print_info "Config-script safety net not installed"
|
||
print_info " Configuration relies on settings.json RPM preservation"
|
||
fi
|
||
|
||
echo ""
|
||
echo "════════════════════════════════════════════════════════════"
|
||
|
||
if [ "$issues_found" -eq 0 ]; then
|
||
print_success "All checks passed! Configuration is healthy."
|
||
else
|
||
print_warning "Found $issues_found issue(s) that may need attention"
|
||
fi
|
||
|
||
# Always return 0 - finding issues is not a failure, it's information
|
||
return 0
|
||
}
|
||
|
||
# Auto-fix common issues
|
||
auto_fix_issues() {
|
||
print_banner "Self-Healing: Auto-Fixing Common Issues"
|
||
|
||
local fixes_applied=0
|
||
|
||
echo "Checking for common issues and applying fixes..."
|
||
echo ""
|
||
|
||
# Fix 1: Restart services if not running
|
||
if ! systemctl is-active --quiet varnish; then
|
||
echo "Fixing: Varnish is not running..."
|
||
if systemctl restart varnish; then
|
||
print_success "Restarted Varnish"
|
||
fixes_applied=$((fixes_applied + 1))
|
||
else
|
||
print_error "Failed to restart Varnish"
|
||
fi
|
||
fi
|
||
|
||
if ! systemctl is-active --quiet nginx; then
|
||
echo "Fixing: Nginx is not running..."
|
||
if systemctl restart nginx; then
|
||
print_success "Restarted Nginx"
|
||
fixes_applied=$((fixes_applied + 1))
|
||
else
|
||
print_error "Failed to restart Nginx"
|
||
fi
|
||
fi
|
||
|
||
# Fix 1b: Enable Varnish for auto-start on boot
|
||
if ! systemctl is-enabled --quiet varnish 2>/dev/null; then
|
||
echo "Fixing: Varnish not enabled for auto-start on boot..."
|
||
if systemctl enable varnish; then
|
||
print_success "Enabled Varnish (will start on boot)"
|
||
fixes_applied=$((fixes_applied + 1))
|
||
else
|
||
print_error "Failed to enable Varnish"
|
||
fi
|
||
fi
|
||
|
||
# Fix 1c: Verify config-script is applying HTTP backend override for HTTPS
|
||
if ! grep -q 'set $CPANEL_APACHE_PROXY_PASS http://apache_backend_http_' /etc/nginx/conf.d/users/*.conf 2>/dev/null; then
|
||
echo "Fixing: HTTPS not configured to use Varnish..."
|
||
echo " Running config-script to force HTTP backend protocol..."
|
||
|
||
# Run the config-script
|
||
if bash /etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish 2>/dev/null; then
|
||
print_success "Applied HTTP backend override for HTTPS traffic"
|
||
print_info " HTTPS now routes through Varnish using HTTP protocol"
|
||
fixes_applied=$((fixes_applied + 1))
|
||
else
|
||
print_error "Failed to run config-script"
|
||
fi
|
||
fi
|
||
|
||
# Fix 2: Check if settings.json has wrong port
|
||
if [ -f /etc/nginx/ea-nginx/settings.json ]; then
|
||
if grep -q '"apache_port" : "81"' /etc/nginx/ea-nginx/settings.json 2>/dev/null; then
|
||
echo "Fixing: settings.json has stock port (81) instead of Varnish (6081)..."
|
||
if modify_settings_json; then
|
||
print_success "Fixed settings.json (port 6081)"
|
||
# Rebuild ea-nginx config
|
||
/usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1
|
||
systemctl reload nginx
|
||
fixes_applied=$((fixes_applied + 1))
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# Fix 3: Check if ea-nginx.conf has wrong port despite settings.json being correct
|
||
if [ -f /etc/nginx/conf.d/ea-nginx.conf ]; then
|
||
if grep -q "default 81;" /etc/nginx/conf.d/ea-nginx.conf 2>/dev/null; then
|
||
# Check if settings.json is correct first
|
||
if grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null; then
|
||
echo "Fixing: ea-nginx.conf has wrong port, rebuilding from settings.json..."
|
||
/usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1
|
||
systemctl reload nginx
|
||
print_success "Rebuilt ea-nginx.conf from settings.json"
|
||
fixes_applied=$((fixes_applied + 1))
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# Fix 4: Reload systemd if Varnish service override exists but daemon not reloaded
|
||
if [ -f /etc/systemd/system/varnish.service.d/override.conf ]; then
|
||
if ! systemctl is-active --quiet varnish; then
|
||
systemctl daemon-reload
|
||
print_success "Reloaded systemd configuration"
|
||
fixes_applied=$((fixes_applied + 1))
|
||
fi
|
||
fi
|
||
|
||
# Fix 5: Rebuild HTTP conf if Nginx config is broken
|
||
if ! nginx -t >/dev/null 2>&1; then
|
||
echo "Fixing: Nginx configuration errors..."
|
||
if /scripts/rebuildhttpdconf; then
|
||
# After rebuild, ensure settings.json config is applied
|
||
if grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null; then
|
||
/usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1
|
||
fi
|
||
systemctl reload nginx
|
||
print_success "Rebuilt Nginx configuration"
|
||
fixes_applied=$((fixes_applied + 1))
|
||
fi
|
||
fi
|
||
|
||
# Fix 6: Recreate config-script if missing (safety net)
|
||
if [ -f "$STATUS_FILE" ] && grep -q "CONFIGURED=yes" "$STATUS_FILE"; then
|
||
if [ ! -f /etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish ]; then
|
||
echo "Fixing: ea-nginx config-script missing, recreating..."
|
||
if create_eanginx_config_script; then
|
||
print_success "Recreated config-script safety net"
|
||
fixes_applied=$((fixes_applied + 1))
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# Fix 7: Restore settings.json.stock backup if settings.json is missing
|
||
if [ ! -f /etc/nginx/ea-nginx/settings.json ] && [ -f /etc/nginx/ea-nginx/settings.json.stock ]; then
|
||
echo "Fixing: settings.json missing, restoring from backup..."
|
||
cp /etc/nginx/ea-nginx/settings.json.stock /etc/nginx/ea-nginx/settings.json
|
||
# Rebuild ea-nginx config
|
||
/usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1
|
||
systemctl reload nginx
|
||
print_success "Restored settings.json from backup"
|
||
fixes_applied=$((fixes_applied + 1))
|
||
fi
|
||
|
||
echo ""
|
||
if [ "$fixes_applied" -gt 0 ]; then
|
||
print_success "Applied $fixes_applied fix(es)"
|
||
else
|
||
print_info "No fixes needed"
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
################################################################################
|
||
# MAIN SETUP FUNCTION
|
||
################################################################################
|
||
|
||
full_setup() {
|
||
print_banner "Complete Nginx + Varnish Setup"
|
||
|
||
echo "This will install and configure the complete caching stack:"
|
||
echo ""
|
||
echo " Stock Apache → ea-nginx (Reverse Proxy) + Varnish (Cache) + Apache"
|
||
echo ""
|
||
echo "Components to be installed:"
|
||
echo " 1. ea-nginx - Nginx reverse proxy (if not already installed)"
|
||
echo " 2. Varnish Cache - HTTP accelerator"
|
||
echo " 3. Complete stack configuration"
|
||
echo ""
|
||
echo "Traffic flow:"
|
||
echo " Client → Nginx (80/443) → Varnish (6081) → Apache (81/444)"
|
||
echo ""
|
||
print_warning "⚠ IMPORTANT:"
|
||
print_warning " • This is NOT officially supported by cPanel"
|
||
print_warning " • Use 'Revert Setup' to completely remove and return to stock Apache"
|
||
print_warning " • Revert will remove BOTH Nginx and Varnish"
|
||
echo ""
|
||
read -p "Continue with complete stack installation? (yes/no): " confirm
|
||
|
||
if [ "$confirm" != "yes" ]; then
|
||
echo "Installation cancelled."
|
||
press_enter
|
||
return 0
|
||
fi
|
||
|
||
# Create backup first
|
||
echo ""
|
||
print_info "Creating backup of current configuration..."
|
||
local backup_path=$(create_backup)
|
||
print_success "Backup created at: $backup_path"
|
||
|
||
# Calculate recommended Varnish memory
|
||
local total_ram=$(get_total_ram_mb)
|
||
local recommended_mem=$(calculate_varnish_memory)
|
||
|
||
echo ""
|
||
echo "Server RAM: ${total_ram}MB"
|
||
echo "Recommended Varnish memory: ${recommended_mem}MB"
|
||
echo ""
|
||
|
||
# Step 1: Install cPanel Nginx if not already installed
|
||
if ! check_nginx_installed; then
|
||
echo ""
|
||
print_info "Step 1/5: Installing cPanel Nginx..."
|
||
if ! install_cpanel_nginx; then
|
||
print_error "Setup failed at Step 1"
|
||
press_enter
|
||
return 0 # Don't crash the script
|
||
fi
|
||
else
|
||
print_success "Step 1/5: cPanel Nginx already installed"
|
||
fi
|
||
|
||
# Step 2: Install Varnish
|
||
if ! check_varnish_installed; then
|
||
echo ""
|
||
print_info "Step 2/5: Installing Varnish..."
|
||
if ! install_varnish; then
|
||
print_error "Setup failed at Step 2"
|
||
press_enter
|
||
return 0 # Don't crash the script
|
||
fi
|
||
else
|
||
print_success "Step 2/5: Varnish already installed"
|
||
fi
|
||
|
||
# Step 3: Configure Varnish
|
||
echo ""
|
||
print_info "Step 3/5: Configuring Varnish..."
|
||
if ! configure_varnish_vcl; then
|
||
print_error "Setup failed at Step 3"
|
||
press_enter
|
||
return 1
|
||
fi
|
||
|
||
if ! configure_varnish_port "$recommended_mem"; then
|
||
print_error "Setup failed at Step 3"
|
||
press_enter
|
||
return 1
|
||
fi
|
||
|
||
# Step 4: Modify settings.json and configure Nginx to proxy to Varnish
|
||
# Apache stays on stock ea-nginx ports (81/444) - NO changes needed!
|
||
echo ""
|
||
print_info "Step 4/5: Configuring Nginx to proxy to Varnish..."
|
||
|
||
# First, modify settings.json to use Varnish port
|
||
if ! modify_settings_json; then
|
||
print_error "Setup failed at Step 4 (settings.json modification)"
|
||
press_enter
|
||
return 1
|
||
fi
|
||
|
||
# Then rebuild ea-nginx config from modified settings.json
|
||
if ! configure_nginx_varnish_proxy; then
|
||
print_error "Setup failed at Step 4 (nginx configuration)"
|
||
press_enter
|
||
return 1
|
||
fi
|
||
|
||
# Step 5: Start services
|
||
echo ""
|
||
print_info "Step 5/5: Starting services..."
|
||
|
||
systemctl enable varnish
|
||
systemctl restart varnish
|
||
if systemctl is-active --quiet varnish; then
|
||
print_success "Varnish started successfully"
|
||
if systemctl is-enabled --quiet varnish; then
|
||
print_success "Varnish enabled (auto-start on boot)"
|
||
fi
|
||
else
|
||
print_error "Failed to start Varnish"
|
||
press_enter
|
||
return 1
|
||
fi
|
||
|
||
systemctl restart nginx
|
||
if systemctl is-active --quiet nginx; then
|
||
print_success "Nginx restarted successfully"
|
||
else
|
||
print_error "Failed to restart Nginx"
|
||
press_enter
|
||
return 1
|
||
fi
|
||
|
||
# Create ea-nginx config-script as safety net
|
||
echo ""
|
||
print_info "Installing config-script for HTTPS→Varnish routing..."
|
||
create_eanginx_config_script
|
||
|
||
# Run config-script immediately to enable HTTPS caching
|
||
print_info "Applying HTTPS caching configuration..."
|
||
if bash /etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish 2>/dev/null; then
|
||
print_success "HTTPS traffic now routes through Varnish (HTTP protocol)"
|
||
else
|
||
print_warning "Config-script execution had issues - check logs"
|
||
fi
|
||
|
||
# Mark as configured
|
||
cat > "$STATUS_FILE" <<EOFSTATUS
|
||
CONFIGURED=yes
|
||
INSTALL_DATE=$(date +%Y-%m-%d)
|
||
VARNISH_MEMORY=${recommended_mem}m
|
||
BACKUP_PATH=$backup_path
|
||
EOFSTATUS
|
||
|
||
echo ""
|
||
print_success "═══════════════════════════════════════════════════════"
|
||
print_success "Setup completed successfully!"
|
||
print_success "═══════════════════════════════════════════════════════"
|
||
|
||
# Run diagnostics
|
||
echo ""
|
||
run_diagnostics
|
||
|
||
# Test domains
|
||
echo ""
|
||
print_info "Testing domain accessibility..."
|
||
echo ""
|
||
|
||
local test_domains=$(get_cpanel_domains | head -5)
|
||
if [ -n "$test_domains" ]; then
|
||
while IFS= read -r domain; do
|
||
test_domain "$domain" "http" || true
|
||
test_domain "$domain" "https" || true
|
||
done <<< "$test_domains"
|
||
else
|
||
print_warning "No domains found to test"
|
||
fi
|
||
|
||
echo ""
|
||
print_info "═══════════════════════════════════════════════════════"
|
||
print_info "Configuration Persistence:"
|
||
echo ""
|
||
print_success "✓ settings.json modified (apache_port = 6081)"
|
||
print_info " ea-nginx natively generates correct proxy config"
|
||
print_info " Preserved by RPM during package updates"
|
||
echo ""
|
||
print_success "✓ ea-nginx config-script installed (safety net)"
|
||
print_info " Auto-fixes if settings.json ever falls back to defaults"
|
||
print_info " Logs to: /var/log/nginx-varnish-hook.log"
|
||
echo ""
|
||
print_info "Backup: /etc/nginx/ea-nginx/settings.json.stock"
|
||
print_info "Backup location: $backup_path"
|
||
echo ""
|
||
print_warning "⚠ IMPORTANT NOTES:"
|
||
print_warning " • This setup is NOT officially supported by cPanel"
|
||
print_warning " • Config-script maintains configuration after ea-nginx updates"
|
||
print_success " ✓ Both HTTP and HTTPS traffic are cached by Varnish"
|
||
echo ""
|
||
print_info "To completely remove:"
|
||
print_info " • Use 'Revert Setup' to remove Nginx + Varnish"
|
||
print_info " • Returns server to stock Apache-only configuration"
|
||
echo ""
|
||
print_info "How HTTPS caching works:"
|
||
print_info " • SSL terminates at Nginx (standard practice)"
|
||
print_info " • Backend uses HTTP protocol to Varnish (config-script override)"
|
||
print_info " • Varnish caches all static content for both protocols"
|
||
echo ""
|
||
print_info "If using Cloudflare: This provides origin-level caching behind CDN"
|
||
print_info "═══════════════════════════════════════════════════════"
|
||
|
||
press_enter
|
||
}
|
||
|
||
################################################################################
|
||
# REVERT FUNCTION
|
||
################################################################################
|
||
|
||
revert_setup() {
|
||
print_banner "Revert Nginx + Varnish Setup"
|
||
|
||
# Check what's actually installed
|
||
local has_varnish_config=false
|
||
local has_nginx=false
|
||
local has_varnish=false
|
||
|
||
# Check Varnish configuration
|
||
if [ -f /etc/nginx/ea-nginx/settings.json ]; then
|
||
if grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null; then
|
||
has_varnish_config=true
|
||
fi
|
||
fi
|
||
|
||
# Check if ea-nginx is installed
|
||
if check_nginx_installed; then
|
||
has_nginx=true
|
||
fi
|
||
|
||
# Check if Varnish is installed
|
||
if check_varnish_installed; then
|
||
has_varnish=true
|
||
fi
|
||
|
||
# If nothing to revert, exit
|
||
if [ "$has_nginx" = "false" ] && [ "$has_varnish" = "false" ] && [ "$has_varnish_config" = "false" ]; then
|
||
print_warning "Nothing to revert:"
|
||
print_info " • ea-nginx not installed"
|
||
print_info " • Varnish not installed"
|
||
print_info " • No Varnish configuration found"
|
||
echo ""
|
||
print_success "System is already in stock Apache-only configuration"
|
||
press_enter
|
||
return 0
|
||
fi
|
||
|
||
# Show what's currently installed
|
||
echo "Current state:"
|
||
if [ "$has_nginx" = "true" ]; then
|
||
echo " ✓ ea-nginx installed"
|
||
else
|
||
echo " ✗ ea-nginx not installed"
|
||
fi
|
||
if [ "$has_varnish" = "true" ]; then
|
||
echo " ✓ Varnish installed"
|
||
else
|
||
echo " ✗ Varnish not installed"
|
||
fi
|
||
if [ "$has_varnish_config" = "true" ]; then
|
||
echo " ✓ Varnish configuration active"
|
||
else
|
||
echo " ✗ Varnish configuration not active"
|
||
fi
|
||
echo ""
|
||
|
||
# Show appropriate revert options based on what's installed
|
||
echo "Available revert options:"
|
||
echo ""
|
||
|
||
local option_count=0
|
||
local partial_option=""
|
||
local full_option=""
|
||
|
||
# Option 1: Partial revert (only if Varnish exists)
|
||
if [ "$has_varnish" = "true" ] || [ "$has_varnish_config" = "true" ]; then
|
||
option_count=$((option_count + 1))
|
||
partial_option="1"
|
||
echo " 1) Partial Revert - Remove Varnish only (keep Nginx + Apache)"
|
||
echo " • Removes Varnish caching layer"
|
||
echo " • Keeps ea-nginx reverse proxy"
|
||
echo " • Result: Client → Nginx → Apache"
|
||
echo ""
|
||
fi
|
||
|
||
# Option 2: Full revert (if Nginx exists OR Varnish stuff needs cleanup)
|
||
if [ "$has_nginx" = "true" ] || [ "$has_varnish" = "true" ] || [ "$has_varnish_config" = "true" ]; then
|
||
option_count=$((option_count + 1))
|
||
if [ -z "$partial_option" ]; then
|
||
full_option="1"
|
||
echo " 1) Full Revert - Remove everything (return to stock Apache)"
|
||
else
|
||
full_option="2"
|
||
echo " 2) Full Revert - Remove everything (return to stock Apache)"
|
||
fi
|
||
if [ "$has_varnish" = "true" ]; then
|
||
echo " • Removes Varnish caching layer"
|
||
fi
|
||
if [ "$has_nginx" = "true" ]; then
|
||
echo " • Removes ea-nginx reverse proxy"
|
||
fi
|
||
if [ "$has_varnish_config" = "true" ]; then
|
||
echo " • Cleans up Varnish configuration"
|
||
fi
|
||
echo " • Result: Client → Apache (stock cPanel)"
|
||
echo ""
|
||
fi
|
||
|
||
echo " 0) Cancel"
|
||
echo ""
|
||
read -p "Select option: " revert_choice
|
||
|
||
case $revert_choice in
|
||
"$partial_option")
|
||
if [ -n "$partial_option" ]; then
|
||
revert_partial
|
||
else
|
||
print_error "Invalid option"
|
||
press_enter
|
||
return 1
|
||
fi
|
||
;;
|
||
"$full_option")
|
||
if [ -n "$full_option" ]; then
|
||
revert_full
|
||
else
|
||
print_error "Invalid option"
|
||
press_enter
|
||
return 1
|
||
fi
|
||
;;
|
||
0)
|
||
echo "Revert cancelled."
|
||
press_enter
|
||
return 0
|
||
;;
|
||
*)
|
||
print_error "Invalid option"
|
||
press_enter
|
||
return 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
revert_partial() {
|
||
print_banner "Partial Revert - Remove Varnish Only"
|
||
|
||
echo "This will:"
|
||
echo " 1. Stop and remove Varnish"
|
||
echo " 2. Configure Nginx to proxy directly to Apache"
|
||
echo " 3. Keep ea-nginx (Nginx reverse proxy)"
|
||
echo ""
|
||
print_info "Result: Client → Nginx → Apache (no caching)"
|
||
echo ""
|
||
read -p "Continue with partial revert? (yes/no): " confirm
|
||
|
||
if [ "$confirm" != "yes" ]; then
|
||
echo "Partial revert cancelled."
|
||
press_enter
|
||
return 0
|
||
fi
|
||
|
||
# Create backup before reverting
|
||
echo ""
|
||
print_info "Creating backup before revert..."
|
||
local backup_path=$(create_backup)
|
||
print_success "Backup created at: $backup_path"
|
||
|
||
# Stop Varnish
|
||
echo ""
|
||
print_info "Stopping Varnish..."
|
||
systemctl stop varnish || true
|
||
systemctl disable varnish || true
|
||
|
||
# Restore settings.json to stock
|
||
echo ""
|
||
restore_settings_json
|
||
|
||
# Rebuild ea-nginx config from restored settings.json
|
||
print_info "Rebuilding ea-nginx configuration..."
|
||
/usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1 || true
|
||
print_success "Nginx now proxies directly to Apache (port 81)"
|
||
|
||
# Reload Nginx
|
||
print_info "Reloading Nginx..."
|
||
systemctl reload nginx
|
||
|
||
# Remove ea-nginx config script (safety net no longer needed)
|
||
echo ""
|
||
remove_eanginx_config_script
|
||
|
||
# Remove status file
|
||
rm -f "$STATUS_FILE"
|
||
|
||
echo ""
|
||
print_success "Varnish configuration reverted"
|
||
echo ""
|
||
|
||
# Remove Varnish package
|
||
print_info "Removing Varnish package..."
|
||
yum remove -y varnish >/dev/null 2>&1 || true
|
||
print_success "Varnish package removed"
|
||
|
||
echo ""
|
||
print_success "═══════════════════════════════════════════════════════"
|
||
print_success "Partial revert completed"
|
||
print_success "═══════════════════════════════════════════════════════"
|
||
echo ""
|
||
print_info "Your server configuration:"
|
||
print_info " • Nginx reverse proxy still active (ea-nginx)"
|
||
print_info " • Client → Nginx (80/443) → Apache (81/444)"
|
||
print_info " • No Varnish caching layer"
|
||
echo ""
|
||
print_info "Benefits you still have:"
|
||
print_info " • Nginx connection handling and buffering"
|
||
print_info " • Support for modern protocols (HTTP/2, etc.)"
|
||
echo ""
|
||
print_info "To fully remove Nginx and return to stock Apache:"
|
||
print_info " Run this revert option again and choose 'Full Revert'"
|
||
|
||
press_enter
|
||
}
|
||
|
||
revert_full() {
|
||
print_banner "Full Revert - Return to Stock Apache"
|
||
|
||
# Check what needs to be removed
|
||
local has_varnish=$(check_varnish_installed && echo "true" || echo "false")
|
||
local has_nginx=$(check_nginx_installed && echo "true" || echo "false")
|
||
local has_config=$([ -f /etc/nginx/ea-nginx/settings.json ] && grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null && echo "true" || echo "false")
|
||
|
||
echo "This will remove:"
|
||
[ "$has_varnish" = "true" ] && echo " • Varnish package"
|
||
[ "$has_nginx" = "true" ] && echo " • ea-nginx package"
|
||
[ "$has_config" = "true" ] && echo " • Varnish configuration"
|
||
[ "$has_varnish" = "false" ] && [ "$has_nginx" = "false" ] && [ "$has_config" = "false" ] && echo " • Clean up any remaining configuration"
|
||
echo ""
|
||
echo "Result: Stock cPanel Apache-only configuration"
|
||
echo ""
|
||
print_warning "⚠ WARNING: This returns your server to stock Apache-only"
|
||
echo ""
|
||
read -p "Continue with full revert? (yes/no): " confirm
|
||
|
||
if [ "$confirm" != "yes" ]; then
|
||
echo "Full revert cancelled."
|
||
press_enter
|
||
return 0
|
||
fi
|
||
|
||
# Create backup before reverting (if there's anything to backup)
|
||
if [ "$has_config" = "true" ]; then
|
||
echo ""
|
||
print_info "Creating backup before revert..."
|
||
local backup_path=$(create_backup)
|
||
print_success "Backup created at: $backup_path"
|
||
fi
|
||
|
||
# Stop Varnish (if running) (if running)
|
||
if systemctl is-active --quiet varnish 2>/dev/null; then
|
||
echo ""
|
||
print_info "Stopping Varnish..."
|
||
systemctl stop varnish || true
|
||
systemctl disable varnish || true
|
||
fi
|
||
|
||
# Restore settings.json to stock (if configured)
|
||
if [ -f /etc/nginx/ea-nginx/settings.json ]; then
|
||
if grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null; then
|
||
echo ""
|
||
restore_settings_json
|
||
|
||
# Rebuild ea-nginx config from restored settings.json
|
||
print_info "Rebuilding ea-nginx configuration..."
|
||
/usr/local/cpanel/scripts/ea-nginx config --global >/dev/null 2>&1 || true
|
||
print_success "Configuration restored"
|
||
|
||
# Reload Nginx before removing it
|
||
if systemctl is-active --quiet nginx 2>/dev/null; then
|
||
print_info "Reloading Nginx..."
|
||
systemctl reload nginx
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# Remove ea-nginx config script (if exists)
|
||
if [ -f /etc/nginx/ea-nginx/config-scripts/global/config-scripts-global-varnish ]; then
|
||
echo ""
|
||
remove_eanginx_config_script
|
||
fi
|
||
|
||
# Remove status file (if exists)
|
||
if [ -f "$STATUS_FILE" ]; then
|
||
rm -f "$STATUS_FILE"
|
||
fi
|
||
|
||
echo ""
|
||
print_success "Varnish configuration cleaned up"
|
||
echo ""
|
||
|
||
# Remove Varnish package (if installed)
|
||
if check_varnish_installed; then
|
||
print_info "Removing Varnish package..."
|
||
yum remove -y varnish >/dev/null 2>&1 || true
|
||
print_success "Varnish package removed"
|
||
else
|
||
print_info "Varnish package already removed"
|
||
fi
|
||
|
||
# Remove ea-nginx and return to stock Apache
|
||
if check_nginx_installed; then
|
||
echo ""
|
||
print_info "Removing ea-nginx (Nginx reverse proxy)..."
|
||
print_warning " This will return your server to stock Apache-only configuration"
|
||
|
||
if /usr/local/cpanel/scripts/ea-nginx disable >/dev/null 2>&1; then
|
||
print_success "ea-nginx disabled"
|
||
fi
|
||
|
||
if yum remove -y ea-nginx >/dev/null 2>&1; then
|
||
print_success "ea-nginx package removed"
|
||
fi
|
||
else
|
||
echo ""
|
||
print_info "ea-nginx already removed"
|
||
fi
|
||
|
||
# Restart Apache to ensure it's listening on port 80/443
|
||
echo ""
|
||
print_info "Restarting Apache on stock ports..."
|
||
systemctl restart httpd
|
||
|
||
if systemctl is-active --quiet httpd; then
|
||
print_success "Apache is now running on ports 80/443 (stock configuration)"
|
||
fi
|
||
|
||
echo ""
|
||
print_success "═══════════════════════════════════════════════════════"
|
||
print_success "Full revert completed"
|
||
print_success "═══════════════════════════════════════════════════════"
|
||
echo ""
|
||
print_info "Your server has been returned to:"
|
||
print_info " • Stock cPanel Apache-only configuration"
|
||
print_info " • Apache listening directly on ports 80/443"
|
||
print_info " • No Nginx reverse proxy"
|
||
print_info " • No Varnish caching"
|
||
|
||
press_enter
|
||
}
|
||
|
||
################################################################################
|
||
# MEMORY ADJUSTMENT FUNCTIONS
|
||
################################################################################
|
||
|
||
adjust_varnish_memory() {
|
||
print_banner "Adjust Varnish Memory Allocation"
|
||
|
||
if ! check_varnish_installed; then
|
||
print_error "Varnish is not installed"
|
||
press_enter
|
||
return 0 # Don't crash the script
|
||
fi
|
||
|
||
local total_ram=$(get_total_ram_mb)
|
||
local current_mem=$(grep "ExecStart.*malloc" /etc/systemd/system/varnish.service.d/override.conf 2>/dev/null | grep -oP 'malloc,\K[0-9]+' || echo "unknown")
|
||
|
||
echo "Server total RAM: ${total_ram}MB"
|
||
echo "Current Varnish memory: ${current_mem}MB"
|
||
echo ""
|
||
echo "Select memory allocation:"
|
||
echo ""
|
||
echo " 1) 256MB - For servers with <2GB RAM"
|
||
echo " 2) 512MB - For servers with 2-4GB RAM"
|
||
echo " 3) 1GB - For servers with 4-8GB RAM"
|
||
echo " 4) 2GB - For servers with 8-16GB RAM"
|
||
echo " 5) 4GB - For servers with 16GB+ RAM"
|
||
echo " 6) Custom amount"
|
||
echo " 7) Auto-calculate based on current RAM usage"
|
||
echo " 0) Cancel"
|
||
echo ""
|
||
read -p "Select option: " mem_choice
|
||
|
||
local new_mem=""
|
||
|
||
case $mem_choice in
|
||
1) new_mem=256 ;;
|
||
2) new_mem=512 ;;
|
||
3) new_mem=1024 ;;
|
||
4) new_mem=2048 ;;
|
||
5) new_mem=4096 ;;
|
||
6)
|
||
echo ""
|
||
read -p "Enter custom memory in MB (or 0 to cancel): " custom_mem
|
||
if [ "$custom_mem" = "0" ] || [ -z "$custom_mem" ]; then
|
||
echo "Cancelled."
|
||
press_enter
|
||
return 0
|
||
fi
|
||
new_mem="$custom_mem"
|
||
;;
|
||
7)
|
||
new_mem=$(calculate_varnish_memory)
|
||
echo ""
|
||
print_info "Auto-calculated memory: ${new_mem}MB"
|
||
;;
|
||
0)
|
||
echo "Cancelled."
|
||
press_enter
|
||
return 0
|
||
;;
|
||
*)
|
||
print_error "Invalid option"
|
||
press_enter
|
||
return 1
|
||
;;
|
||
esac
|
||
|
||
if [ -z "$new_mem" ]; then
|
||
print_error "Invalid memory value"
|
||
press_enter
|
||
return 1
|
||
fi
|
||
|
||
echo ""
|
||
print_info "Setting Varnish memory to ${new_mem}MB..."
|
||
|
||
configure_varnish_port "$new_mem"
|
||
|
||
echo ""
|
||
print_info "Restarting Varnish..."
|
||
if systemctl restart varnish; then
|
||
print_success "Varnish memory updated to ${new_mem}MB"
|
||
|
||
# Update status file
|
||
if [ -f "$STATUS_FILE" ]; then
|
||
sed -i "s/VARNISH_MEMORY=.*/VARNISH_MEMORY=${new_mem}m/" "$STATUS_FILE"
|
||
fi
|
||
else
|
||
print_error "Failed to restart Varnish"
|
||
fi
|
||
|
||
press_enter
|
||
}
|
||
|
||
################################################################################
|
||
# CACHE MANAGEMENT FUNCTIONS
|
||
################################################################################
|
||
|
||
manage_varnish_cache() {
|
||
print_banner "Varnish Cache Management"
|
||
|
||
if ! systemctl is-active --quiet varnish; then
|
||
print_error "Varnish is not running"
|
||
press_enter
|
||
return 0 # Don't crash the script
|
||
fi
|
||
|
||
echo " 1) Clear all cache"
|
||
echo " 2) Clear cache for specific domain"
|
||
echo " 3) View cache statistics"
|
||
echo " 4) View cache hit ratio"
|
||
echo " 0) Cancel"
|
||
echo ""
|
||
read -p "Select option: " cache_choice
|
||
|
||
case $cache_choice in
|
||
1)
|
||
echo ""
|
||
print_info "Clearing all Varnish cache..."
|
||
if varnishadm "ban req.url ~ /" 2>/dev/null; then
|
||
print_success "Cache cleared successfully"
|
||
else
|
||
print_error "Failed to clear cache"
|
||
fi
|
||
;;
|
||
2)
|
||
echo ""
|
||
read -p "Enter domain name (or 0 to cancel): " domain
|
||
if [ "$domain" = "0" ] || [ -z "$domain" ]; then
|
||
echo "Cancelled."
|
||
else
|
||
print_info "Clearing cache for $domain..."
|
||
if varnishadm "ban req.http.host == $domain" 2>/dev/null; then
|
||
print_success "Cache cleared for $domain"
|
||
else
|
||
print_error "Failed to clear cache"
|
||
fi
|
||
fi
|
||
;;
|
||
3)
|
||
echo ""
|
||
print_info "Varnish cache statistics (press 'q' to quit):"
|
||
echo ""
|
||
varnishstat || print_error "Failed to get statistics"
|
||
;;
|
||
4)
|
||
echo ""
|
||
print_info "Cache hit ratio:"
|
||
echo ""
|
||
varnishstat -1 | grep -E 'cache_hit|cache_miss' || print_error "Failed to get statistics"
|
||
;;
|
||
0)
|
||
return 0
|
||
;;
|
||
*)
|
||
print_error "Invalid option"
|
||
;;
|
||
esac
|
||
|
||
press_enter
|
||
}
|
||
|
||
################################################################################
|
||
# BACKUP/RESTORE FUNCTIONS
|
||
################################################################################
|
||
|
||
manage_backups() {
|
||
print_banner "Backup & Restore Management"
|
||
|
||
echo " 1) Create new backup"
|
||
echo " 2) List available backups"
|
||
echo " 3) Restore from backup"
|
||
echo " 0) Cancel"
|
||
echo ""
|
||
read -p "Select option: " backup_choice
|
||
|
||
case $backup_choice in
|
||
1)
|
||
echo ""
|
||
print_info "Creating backup..."
|
||
local backup_path=$(create_backup)
|
||
print_success "Backup created at: $backup_path"
|
||
;;
|
||
2)
|
||
echo ""
|
||
if [ -d "$BACKUP_DIR" ] && [ "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then
|
||
echo "Available backups:"
|
||
echo ""
|
||
ls -lh "$BACKUP_DIR" | grep "^d" | awk '{print $9, "("$6, $7, $8")"}'
|
||
else
|
||
print_info "No backups found"
|
||
fi
|
||
;;
|
||
3)
|
||
echo ""
|
||
if [ ! -d "$BACKUP_DIR" ] || [ ! "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then
|
||
print_error "No backups available"
|
||
press_enter
|
||
return 0 # Don't crash the script
|
||
fi
|
||
|
||
echo "Available backups:"
|
||
echo ""
|
||
local backups=($(ls -d "$BACKUP_DIR"/backup_* 2>/dev/null | sort -r))
|
||
local count=1
|
||
for backup in "${backups[@]}"; do
|
||
echo " $count) $(basename "$backup")"
|
||
count=$((count + 1))
|
||
done
|
||
echo " 0) Cancel"
|
||
echo ""
|
||
read -p "Select backup to restore: " restore_choice
|
||
|
||
if [ "$restore_choice" = "0" ]; then
|
||
echo "Cancelled."
|
||
elif [ "$restore_choice" -ge 1 ] && [ "$restore_choice" -lt "$count" ]; then
|
||
local selected_backup="${backups[$((restore_choice - 1))]}"
|
||
echo ""
|
||
print_warning "This will restore configuration from: $(basename "$selected_backup")"
|
||
read -p "Continue? (yes/no): " confirm
|
||
|
||
if [ "$confirm" = "yes" ]; then
|
||
print_info "Restoring backup..."
|
||
|
||
# Check disk space before restore
|
||
local available_space=$(df /etc | tail -1 | awk '{print $4}')
|
||
if [ "$available_space" -lt 10240 ]; then
|
||
print_error "Insufficient disk space (less than 10MB available)"
|
||
press_enter
|
||
return 0 # Don't crash the script
|
||
fi
|
||
|
||
# Restore files
|
||
[ -f "$selected_backup/ea-nginx.conf" ] && cp -f "$selected_backup/ea-nginx.conf" /etc/nginx/
|
||
[ -d "$selected_backup/conf.d" ] && cp -rf "$selected_backup/conf.d/"* /etc/nginx/conf.d/
|
||
[ -f "$selected_backup/default.vcl" ] && cp -f "$selected_backup/default.vcl" /etc/varnish/
|
||
|
||
# Reload services
|
||
systemctl daemon-reload
|
||
systemctl reload nginx || true
|
||
systemctl restart varnish || true
|
||
|
||
print_success "Backup restored successfully"
|
||
else
|
||
echo "Restore cancelled."
|
||
fi
|
||
else
|
||
print_error "Invalid selection"
|
||
fi
|
||
;;
|
||
0)
|
||
return 0
|
||
;;
|
||
*)
|
||
print_error "Invalid option"
|
||
;;
|
||
esac
|
||
|
||
press_enter
|
||
}
|
||
|
||
################################################################################
|
||
# VIEW LOGS FUNCTION
|
||
################################################################################
|
||
|
||
view_logs() {
|
||
print_banner "View Service Logs"
|
||
|
||
echo " 1) Varnish logs (live)"
|
||
echo " 2) Nginx error log (tail)"
|
||
echo " 3) Nginx access log (tail)"
|
||
echo " 4) Apache error log (tail)"
|
||
echo " 0) Cancel"
|
||
echo ""
|
||
read -p "Select option: " log_choice
|
||
|
||
case $log_choice in
|
||
1)
|
||
echo ""
|
||
print_info "Viewing Varnish logs (press Ctrl+C to exit)..."
|
||
echo ""
|
||
varnishlog || print_error "Failed to view logs"
|
||
;;
|
||
2)
|
||
echo ""
|
||
print_info "Viewing Nginx error log (press Ctrl+C to exit)..."
|
||
echo ""
|
||
tail -f /var/log/nginx/error.log || print_error "Failed to view logs"
|
||
;;
|
||
3)
|
||
echo ""
|
||
print_info "Viewing Nginx access log (press Ctrl+C to exit)..."
|
||
echo ""
|
||
tail -f /var/log/nginx/access.log || print_error "Failed to view logs"
|
||
;;
|
||
4)
|
||
echo ""
|
||
print_info "Viewing Apache error log (press Ctrl+C to exit)..."
|
||
echo ""
|
||
tail -f /usr/local/apache/logs/error_log || print_error "Failed to view logs"
|
||
;;
|
||
0)
|
||
return 0
|
||
;;
|
||
*)
|
||
print_error "Invalid option"
|
||
;;
|
||
esac
|
||
|
||
press_enter
|
||
}
|
||
|
||
################################################################################
|
||
# MAIN MENU
|
||
################################################################################
|
||
|
||
show_varnish_menu() {
|
||
clear
|
||
print_banner "Nginx + Varnish Caching Manager"
|
||
|
||
# Detect current mode
|
||
local has_nginx=$(check_nginx_installed && echo "true" || echo "false")
|
||
local has_varnish=$(check_varnish_installed && echo "true" || echo "false")
|
||
local has_varnish_config=$([ -f /etc/nginx/ea-nginx/settings.json ] && grep -q '"apache_port" : "6081"' /etc/nginx/ea-nginx/settings.json 2>/dev/null && echo "true" || echo "false")
|
||
|
||
# Determine mode
|
||
local mode=""
|
||
local mode_color=""
|
||
|
||
if [ "$has_varnish" = "true" ] && [ "$has_nginx" = "true" ] && [ "$has_varnish_config" = "true" ]; then
|
||
mode="Varnish + Nginx + Apache (Full Stack)"
|
||
mode_color="${GREEN}"
|
||
elif [ "$has_nginx" = "true" ]; then
|
||
mode="Nginx + Apache (Reverse Proxy)"
|
||
mode_color="${YELLOW}"
|
||
else
|
||
mode="Apache Only (Stock cPanel)"
|
||
mode_color="${YELLOW}"
|
||
fi
|
||
|
||
echo -e "${mode_color}● Mode: ${mode}${NC}"
|
||
|
||
# Show installation info if configured
|
||
if [ "$has_varnish_config" = "true" ] && [ -f "$STATUS_FILE" ]; then
|
||
local install_date=$(grep "INSTALL_DATE" "$STATUS_FILE" | cut -d= -f2)
|
||
local varnish_mem=$(grep "VARNISH_MEMORY" "$STATUS_FILE" | cut -d= -f2)
|
||
echo " Installed: $install_date"
|
||
echo " Varnish Memory: $varnish_mem"
|
||
fi
|
||
|
||
# Always show port status with color coding
|
||
echo ""
|
||
echo " Services & Ports:"
|
||
|
||
# Check Nginx ports (80/443)
|
||
if ss -tlnp 2>/dev/null | grep -E ":80\s.*nginx" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk '$4 ~ /:80$/ && $7 ~ /nginx/' | grep -q .; then
|
||
echo -e " ${GREEN}✓${NC} Nginx: 80"
|
||
elif ss -tlnp 2>/dev/null | grep -E ":80\s.*httpd" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk '$4 ~ /:80$/ && $7 ~ /httpd/' | grep -q .; then
|
||
echo -e " ${GREEN}✓${NC} Apache: 80 (direct)"
|
||
else
|
||
echo -e " ${RED}✗${NC} Port 80 (not active)"
|
||
fi
|
||
|
||
if ss -tlnp 2>/dev/null | grep -E ":443\s.*nginx" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk '$4 ~ /:443$/ && $7 ~ /nginx/' | grep -q .; then
|
||
echo -e " ${GREEN}✓${NC} Nginx: 443"
|
||
elif ss -tlnp 2>/dev/null | grep -E ":443\s.*httpd" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk '$4 ~ /:443$/ && $7 ~ /httpd/' | grep -q .; then
|
||
echo -e " ${GREEN}✓${NC} Apache: 443 (direct)"
|
||
else
|
||
echo -e " ${RED}✗${NC} Port 443 (not active)"
|
||
fi
|
||
|
||
# Check Varnish port (6081)
|
||
if ss -tlnp 2>/dev/null | grep -E ":${VARNISH_PORT}\s.*varnish" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk -v port="$VARNISH_PORT" '$4 ~ ":"port"$" && $7 ~ /varnish/' | grep -q .; then
|
||
echo -e " ${GREEN}✓${NC} Varnish: ${VARNISH_PORT}"
|
||
else
|
||
echo -e " ${RED}✗${NC} Varnish: ${VARNISH_PORT}"
|
||
fi
|
||
|
||
# Check Apache backend ports (81/444)
|
||
if ss -tlnp 2>/dev/null | grep -E ":${APACHE_HTTP_PORT}\s.*httpd" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk -v port="$APACHE_HTTP_PORT" '$4 ~ ":"port"$" && $7 ~ /httpd/' | grep -q .; then
|
||
echo -e " ${GREEN}✓${NC} Apache: ${APACHE_HTTP_PORT}"
|
||
else
|
||
echo -e " ${RED}✗${NC} Apache: ${APACHE_HTTP_PORT}"
|
||
fi
|
||
|
||
if ss -tlnp 2>/dev/null | grep -E ":${APACHE_HTTPS_PORT}\s.*httpd" >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | awk -v port="$APACHE_HTTPS_PORT" '$4 ~ ":"port"$" && $7 ~ /httpd/' | grep -q .; then
|
||
echo -e " ${GREEN}✓${NC} Apache: ${APACHE_HTTPS_PORT}"
|
||
else
|
||
echo -e " ${RED}✗${NC} Apache: ${APACHE_HTTPS_PORT}"
|
||
fi
|
||
|
||
echo ""
|
||
echo -e "${BOLD}Setup & Installation:${NC}"
|
||
echo ""
|
||
echo " 1) Full Setup - Install and configure complete stack"
|
||
echo " 2) Revert Setup - Remove Varnish integration"
|
||
echo ""
|
||
echo -e "${BOLD}Diagnostics & Maintenance:${NC}"
|
||
echo ""
|
||
echo " 3) Run Health Check - Diagnose configuration issues"
|
||
echo " 4) Auto-Fix Issues - Self-healing diagnostics"
|
||
echo " 5) Proof of Caching - Quick test showing MISS → HIT pattern"
|
||
echo ""
|
||
echo -e "${BOLD}Optimization:${NC}"
|
||
echo ""
|
||
echo " 6) Adjust Varnish Memory - Change RAM allocation"
|
||
echo " 7) Manage Varnish Cache - Clear cache, view stats"
|
||
echo ""
|
||
echo -e "${BOLD}Advanced:${NC}"
|
||
echo ""
|
||
echo " 8) Backup & Restore - Manage configuration backups"
|
||
echo " 9) View Logs - Service logs and monitoring"
|
||
echo ""
|
||
echo " 0) Return to Performance Menu"
|
||
echo ""
|
||
echo "═══════════════════════════════════════════════════════════"
|
||
echo -n "Select option: "
|
||
}
|
||
|
||
# Main loop
|
||
run_varnish_manager() {
|
||
while true; do
|
||
show_varnish_menu
|
||
read -r choice
|
||
|
||
case $choice in
|
||
1) full_setup ;;
|
||
2) revert_setup ;;
|
||
3) run_diagnostics; press_enter ;;
|
||
4) auto_fix_issues; press_enter ;;
|
||
5) proof_of_caching; press_enter ;;
|
||
6) adjust_varnish_memory ;;
|
||
7) manage_varnish_cache ;;
|
||
8) manage_backups ;;
|
||
9) view_logs ;;
|
||
0)
|
||
clear
|
||
exit 0
|
||
;;
|
||
*)
|
||
echo ""
|
||
print_error "Invalid option"
|
||
sleep 1
|
||
;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
# Run main menu
|
||
run_varnish_manager
|