Securing CloudPanel on Ubuntu 24.04 Part 11
22/11/2024 22/11/2024 security 6 mins read
Table Of Contents
Part 11: Automated Backup and Disaster Recovery System #
Let’s create a comprehensive backup and recovery system that ensures both data integrity and quick recovery capabilities.
#!/bin/bash
# Create backup management scriptsudo nano /usr/local/bin/cloudpanel-backup-manager.sh
#
#!/bin/bash
# Initialize paths and configurationCP_HOME="/home/clp"DB_PATH="${CP_HOME}/htdocs/app/data/db.sq3"BACKUP_ROOT="/backup/cloudpanel"LOG_DIR="${CP_HOME}/logs/backup"TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Create necessary directoriesmkdir -p "${BACKUP_ROOT}/{system,sites,databases,ssl,logs}" "$LOG_DIR"
# Function to read site configurations from CloudPanel databaseget_site_configurations() { sqlite3 "$DB_PATH" " SELECT s.id, s.domain_name, s.user, s.root_directory, d.name as db_name FROM site s LEFT JOIN database d ON s.id = d.site_id WHERE s.type = 'vhost';"}
# Function to backup CloudPanel system filesbackup_system_files() { local backup_dir="${BACKUP_ROOT}/system/${TIMESTAMP}" echo "Backing up system files to $backup_dir"
# Create backup directories mkdir -p "$backup_dir"/{config,services,database,ssl}
# Backup core configuration tar -czf "$backup_dir/config/cloudpanel_config.tar.gz" \ "${CP_HOME}/services/nginx/nginx.conf" \ "${CP_HOME}/services/php-fpm" \ "${CP_HOME}/services/nginx/sites-enabled" \ --exclude='*.log'
# Backup SSL certificates cp -r "${CP_HOME}/services/nginx/ssl-certificates" "$backup_dir/ssl/"
# Backup CloudPanel database sqlite3 "$DB_PATH" ".backup '${backup_dir}/database/cloudpanel.sq3'"
# Create backup manifest { echo "CloudPanel System Backup - $(date)" echo "=================================" echo "Backup Type: System Files" echo "Timestamp: $TIMESTAMP" find "$backup_dir" -type f -exec ls -lh {} \; } > "$backup_dir/MANIFEST.txt"}
# Function to backup individual sitesbackup_site() { local domain="$1" local user="$2" local root_dir="$3" local db_name="$4"
local site_backup_dir="${BACKUP_ROOT}/sites/${domain}/${TIMESTAMP}" echo "Backing up site: $domain to $site_backup_dir"
# Create site backup directory mkdir -p "$site_backup_dir"/{files,database,logs,config}
# Backup site files tar -czf "$site_backup_dir/files/site_files.tar.gz" \ "$root_dir" \ --exclude='*/cache/*' \ --exclude='*/tmp/*' \ --exclude='*/logs/*'
# Backup site database if exists if [ ! -z "$db_name" ]; then mysqldump --single-transaction \ --quick \ --lock-tables=false \ "$db_name" > "$site_backup_dir/database/${db_name}.sql"
# Compress database backup gzip "$site_backup_dir/database/${db_name}.sql" fi
# Backup site configuration cp "/home/clp/services/nginx/sites-enabled/${domain}.conf" \ "$site_backup_dir/config/"
# Create site backup manifest { echo "Site Backup - $domain" echo "=================================" echo "Backup Type: Site Files and Configuration" echo "Timestamp: $TIMESTAMP" echo "User: $user" echo "Database: $db_name" find "$site_backup_dir" -type f -exec ls -lh {} \; } > "$site_backup_dir/MANIFEST.txt"}
# Function to verify backup integrityverify_backup() { local backup_dir="$1" local backup_type="$2" local verification_log="${LOG_DIR}/verification_${TIMESTAMP}.log"
echo "Verifying backup integrity for $backup_type"
# Verify tar archives find "$backup_dir" -name "*.tar.gz" -type f | while read -r archive; do if ! tar -tzf "$archive" >/dev/null 2>&1; then echo "ERROR: Corrupt archive detected: $archive" >> "$verification_log" return 1 fi done
# Verify database backups find "$backup_dir" -name "*.sql.gz" -type f | while read -r db_backup; do if ! gunzip -t "$db_backup" >/dev/null 2>&1; then echo "ERROR: Corrupt database backup detected: $db_backup" >> "$verification_log" return 1 fi done
# Record successful verification echo "Backup verification completed successfully for $backup_type" >> "$verification_log" return 0}
# Function to handle backup rotationrotate_backups() { local backup_path="$1" local retention_days=7
echo "Rotating old backups in $backup_path"
# Remove backups older than retention period find "$backup_path" -type d -mtime +$retention_days -exec rm -rf {} \;}
# Function to create recovery scriptcreate_recovery_script() { local backup_dir="$1" local recovery_script="${backup_dir}/recover.sh"
cat > "$recovery_script" <<'EOF'#!/bin/bash
# CloudPanel Recovery ScriptCP_HOME="/home/clp"
# Verify environmentif [ ! -d "$CP_HOME" ]; then echo "ERROR: CloudPanel directory not found!" exit 1fi
# Restore system filesrestore_system_files() { echo "Restoring system files..." tar -xzf config/cloudpanel_config.tar.gz -C /
# Restore SSL certificates cp -r ssl/* "${CP_HOME}/services/nginx/ssl-certificates/"
# Restore database sqlite3 "${CP_HOME}/htdocs/app/data/db.sq3" ".restore 'database/cloudpanel.sq3'"}
# Restore site datarestore_site() { local site_dir="$1"
echo "Restoring site from: $site_dir"
# Restore site files tar -xzf "${site_dir}/files/site_files.tar.gz" -C /
# Restore database if exists for db_backup in "${site_dir}"/database/*.sql.gz; do if [ -f "$db_backup" ]; then local db_name=$(basename "$db_backup" .sql.gz) gunzip -c "$db_backup" | mysql "$db_name" fi done
# Restore configuration cp "${site_dir}"/config/* "${CP_HOME}/services/nginx/sites-enabled/"}
# Main recovery processmain() { echo "Starting CloudPanel recovery process..."
# Restore system components restore_system_files
# Restore individual sites for site_backup in sites/*/${TIMESTAMP}; do if [ -d "$site_backup" ]; then restore_site "$site_backup" fi done
# Restart services systemctl restart nginx php-fpm mysql
echo "Recovery process completed"}
main "$@"EOF
chmod +x "$recovery_script"}
# Main executionmain() { echo "Starting CloudPanel backup process..."
# Backup system files backup_system_files verify_backup "${BACKUP_ROOT}/system/${TIMESTAMP}" "system"
# Backup individual sites while IFS='|' read -r site_id domain user root_dir db_name; do backup_site "$domain" "$user" "$root_dir" "$db_name" verify_backup "${BACKUP_ROOT}/sites/${domain}/${TIMESTAMP}" "site" done < <(get_site_configurations)
# Create recovery script create_recovery_script "${BACKUP_ROOT}/system/${TIMESTAMP}"
# Rotate old backups rotate_backups "$BACKUP_ROOT"
echo "Backup process completed successfully"}
main "$@"
This backup system provides:
- Comprehensive backup of CloudPanel system files
- Site-specific backups including files, databases, and configurations
- Backup verification and integrity checking
- Automated backup rotation
- Recovery script generation
- Integration with CloudPanel’s database structure
To implement this backup system:
# Make the script executablechmod +x /usr/local/bin/cloudpanel-backup-manager.sh
# Add to crontab for daily execution(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/cloudpanel-backup-manager.sh") | crontab -